summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2014-12-16 20:12:18 +0100
committerOswald Buddenhagen <oswald.buddenhagen@gmx.de>2020-02-28 17:45:59 +0000
commit44a75ae0e271e24b2352bd633b7e83d8f38f72cb (patch)
treed545e320c7cfe7e1710a5be9ef289e4ce6c00f50 /bin
parent2ceb3a6aad8b7c2a514727d7a23cab7a6070f3a4 (diff)
downloadqtrepotools-44a75ae0e271e24b2352bd633b7e83d8f38f72cb.tar.gz
gpush: add support for gerrit topic names
ui-wise, i considered the alternative of parsing the topic out of the target ref like a regular push to old versions of gerrit does. however, given that specifying a target branch is rather uncommon when using gpush, this seemed pointless. the topic is persisted (cached) locally, so the purely off-line --list mode can make use of it. Change-Id: I032a1f0c3d2b0e84db594e2e162978a2eff66d21 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'bin')
-rwxr-xr-xbin/git-gpush66
-rw-r--r--bin/git_gpush.pm6
2 files changed, 65 insertions, 7 deletions
diff --git a/bin/git-gpush b/bin/git-gpush
index b467fea..49f256f 100755
--- a/bin/git-gpush
+++ b/bin/git-gpush
@@ -67,6 +67,10 @@ Options:
Push for specified branch despite the pushed Changes having
been pushed previously, but only for different branches.
+ -t, --topic
+ Specify the Gerrit topic name for the pushed Changes.
+ This setting persists for the series, even when it grows.
+
-l, --list
Report all Changes that would be pushed, then quit.
This is a purely off-line operation.
@@ -139,6 +143,7 @@ EOM
my $ref_from;
my $ref_to;
my $force_branch = 0;
+my $topic;
my $force = 0;
my $list_only = 0;
my $list_online = 0;
@@ -165,6 +170,9 @@ sub parse_arguments(@)
} elsif ($arg eq "-r" || $arg eq "--remote") {
fail("--remote needs an argument.\n") if (!@_ || ($_[0] =~ /^-/));
$remote = shift @_;
+ } elsif ($arg eq "-t" || $arg eq "--topic") {
+ fail("--topic needs an argument.\n") if (!@_ || ($_[0] =~ /^-/));
+ $topic = shift @_;
} elsif ($arg eq "-b" || $arg eq "--branch") {
fail("--branch needs an argument.\n") if (!@_ || ($_[0] =~ /^-/));
$ref_to = shift @_;
@@ -218,7 +226,7 @@ sub parse_arguments(@)
my $push_specific =
@reviewers || @CCs || $force || $force_branch
- || defined($remote) || defined($ref_to);
+ || defined($remote) || defined($ref_to) || defined($topic);
if ($list_only) {
fail("--list/--list-online is incompatible with --quiet/--verbose.\n")
@@ -260,12 +268,14 @@ sub caption_group($)
my $changes = $$group{changes};
my $to = $$group{branch};
my $tos = defined($to) ? " for $to" : "";
+ my $tpc = $$group{topic};
+ my $tpcs = length($tpc) ? ", topic '$tpc'" : "";
my ($pfx, $rmt) = $list_only
? ("Series of",
($list_online && length($tos)) ? " on '$remote'" : "")
: ("Pushing", " to '$remote'");
- return (sprintf("%s %d Change(s)%s%s:",
- $pfx, int(@$changes), $tos, $rmt),
+ return (sprintf("%s %d Change(s)%s%s%s:",
+ $pfx, int(@$changes), $tos, $rmt, $tpcs),
$changes);
}
@@ -408,6 +418,20 @@ sub determine_remote_branch($)
$$group{branch} = $br;
}
+sub determine_topic($)
+{
+ my ($group) = @_;
+
+ my $tpc = $topic;
+ if (!defined($tpc)) {
+ # No topic was specified, so deduce it from the previous push(es).
+ $tpc = aggregate_property($group, 'topic',
+ sub { $_[0]->{topic} },
+ sub { ' /'.$_[0] });
+ }
+ $$group{topic} = $tpc;
+}
+
sub finalize_get_changes($)
{
my ($changes) = @_;
@@ -516,6 +540,8 @@ sub map_remote_changes($)
}
if ($good) {
$$change{gerrit} = $good;
+ # This overrides the current value, which is just a cache.
+ $$change{topic} = $$good{topic};
} elsif (@bad && !$force_branch) {
my @bbr = map { $$_{branch} } @bad;
$$change{annotation} = ' ['.join(" ", sort @bbr).']';
@@ -727,6 +753,20 @@ sub prepare_meta($)
$$group{add_rvrs} = [ keys %invite_rvrs ];
$$group{add_ccs} = [ keys %invite_ccs ];
$$group{invite_list} = \@invite_list;
+
+ my @topic_list;
+ my $tpc = $$group{topic};
+ if (defined($tpc)) {
+ my $any;
+ foreach my $change (@{$$group{changes}}) {
+ next if ($tpc eq ($$change{topic} // ""));
+ $any = 1;
+ # Can't set topic of unmodified Changes with a push.
+ add_if_unmodified($change, \@topic_list);
+ }
+ $$group{topic} = undef if (!$any);
+ }
+ $$group{topic_list} = \@topic_list;
}
sub push_changes($)
@@ -736,9 +776,11 @@ sub push_changes($)
my $from = $$group{changes}[-1];
my $tip = $$from{local}{id};
my $to = $$group{branch};
+ my $tpc = $$group{topic};
my ($rvrs, $ccs) = ($$group{add_rvrs} // [], $$group{add_ccs} // []);
my @push_options;
+ push @push_options, "topic=$tpc" if (defined($tpc));
push @push_options, map { "r=$_" } @$rvrs;
push @push_options, map { "cc=$_" } @$ccs;
@@ -774,16 +816,27 @@ sub update_unpushed($)
write_process($pipe, encode_json($json)."\n");
close_process($pipe);
}
+
+ my $topic_list = $$group{topic_list};
+ if (@$topic_list) {
+ # TODO: This can be done with the REST API.
+ print "Warning: Cannot set topic on unmodified commits.\n";
+ }
}
sub update_state($)
{
my ($group) = @_;
- my $branch = $$group{branch};
+ my ($branch, $tpc) = ($$group{branch}, $$group{topic});
+ # Setting an empty topic clears the previous topic from the server.
+ $tpc = undef if (defined($tpc) && !length($tpc));
foreach my $change (@{$$group{changes}}) {
my $sha1 = $$change{local}{id};
- $$change{pushed} = $sha1;
+ if (($$change{pushed} // "") ne $sha1) {
+ $$change{pushed} = $sha1;
+ $$change{topic} = $tpc;
+ }
$$change{tgt} = $branch;
}
}
@@ -810,6 +863,9 @@ sub execute_pushing()
if ($online) {
check_merges($group);
map_remote_changes($group);
+ }
+ determine_topic($group);
+ if ($online) {
classify_changes_online($group);
} elsif (!$quiet) {
classify_changes_offline($group);
diff --git a/bin/git_gpush.pm b/bin/git_gpush.pm
index 2997d71..512fa87 100644
--- a/bin/git_gpush.pm
+++ b/bin/git_gpush.pm
@@ -523,6 +523,7 @@ our %gerrit_infos_by_id;
# - id: Gerrit Change-Id.
# - src: Local branch name, or "-" if Change is on a detached HEAD.
# - tgt: Target branch name.
+# - topic: Gerrit topic. Persisted only as a cache.
# - pushed: SHA1 of the commit this Change was pushed as last time
# from this repository.
@@ -566,7 +567,7 @@ sub save_state(;$)
print "Saving state".($dry ? " [DRY]" : "")." ...\n" if ($debug);
my (@lines, @updates);
- my @fkeys = ('key', 'id', 'src', 'tgt');
+ my @fkeys = ('key', 'id', 'src', 'tgt', 'topic');
my @rkeys = ('pushed');
push @lines,
"next_key $next_key",
@@ -1109,7 +1110,7 @@ sub query_gerrit($;$)
push @{$gerrit_infos_by_id{$changeid}}, $ginfo;
my $status = $$review{'status'};
defined($status) or fail("Huh?! $changeid has no status?\n");
- my $branch = $$review{'branch'};
+ my ($branch, $topic) = ($$review{'branch'}, $$review{'topic'});
defined($branch) or fail("Huh?! $changeid has no branch?\n");
my $pss = $$review{'patchSets'};
defined($pss) or fail("Huh?! $changeid has no PatchSets?\n");
@@ -1129,6 +1130,7 @@ sub query_gerrit($;$)
$$ginfo{id} = $changeid;
$$ginfo{status} = $status;
$$ginfo{branch} = $branch;
+ $$ginfo{topic} = $topic;
$$ginfo{revs} = [ grep { $_ } @revs ]; # Drop deleted ones.
$$ginfo{rev_by_id} = \%rev_map;
my $rvrs = $$review{'allReviewers'};