summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/git-gpush20
-rw-r--r--bin/git_gpush.pm31
2 files changed, 51 insertions, 0 deletions
diff --git a/bin/git-gpush b/bin/git-gpush
index 7230c5f..56bc5db 100755
--- a/bin/git-gpush
+++ b/bin/git-gpush
@@ -769,6 +769,26 @@ sub aggregate_bool_property($$$$$)
fail_formatted(\@reports);
}
+sub aggregate_indirect_property($$$)
+{
+ my ($group, $get_key, $get_err) = @_;
+
+ my $changes = $$group{changes};
+ my %key_map = map { $_ => 1 } grep { defined($_) } map { $get_key->() } @$changes;
+ my @pkeys = sort keys %key_map;
+ return if (!@pkeys);
+ # Again a hash, as different keys could still lead to the same value.
+ my %prop_map = map { ($prop_by_key{$_} // "") => 1 } @pkeys;
+ my @props = sort keys %prop_map;
+ return $pkeys[0] if (@props == 1);
+
+ my @reports;
+ report_fixed(\@reports, "Series of ".int(@$changes)." Changes:\n");
+ report_local_changes(\@reports, $changes);
+ report_fixed(\@reports, $get_err->(@props));
+ fail_formatted(\@reports);
+}
+
# Find _the_ branch the specified commit lives on. This can be the current
# branch (and other branches are ignored), or _one_ other branch.
sub branch_for_commit($)
diff --git a/bin/git_gpush.pm b/bin/git_gpush.pm
index 7a23c0b..dce7400 100644
--- a/bin/git_gpush.pm
+++ b/bin/git_gpush.pm
@@ -746,11 +746,30 @@ our %change_by_pushed; # { sha1 => change-object }
our $next_group = 10000;
+my $next_prop = 10000;
+# Indirect Change properties, which are shared to save space.
+# An alternative would be group poperties, but this would require
+# resolving inconsistencies at inopportune times; in particular,
+# we do not want to concern gpick with this at all.
+our %prop_by_key;
+
our $last_gc = 0;
my $state_lines;
my $state_updater = ($0 =~ s,^.*/,,r)." @ARGV";
+sub new_prop($)
+{
+ my ($val) = @_;
+
+ my $key;
+ if (length($val)) {
+ $key = $next_prop++;
+ $prop_by_key{$key} = $val;
+ }
+ return $key;
+}
+
# Perform a batch update of refs.
sub update_refs($$)
{
@@ -786,7 +805,9 @@ sub save_state(;$$)
my ($dry, $new) = @_;
print "Saving ".($new ? "new " : "")."state".($dry ? " [DRY]" : "")." ...\n" if ($debug);
+ my %prop_hash;
my (@lines, @updates);
+ my %ikeys = map { $_ => 1 } ();
my @fkeys = ('key', 'grp', 'id', 'base', 'src', 'tgt',
'topic', 'ver',
'nbase', 'ntgt', 'ntopic', 'exclude', 'hide');
@@ -799,6 +820,7 @@ sub save_state(;$$)
push @lines,
"next_key $next_key",
"next_group $next_group",
+ "next_prop $next_prop",
"last_gc $last_gc",
"";
foreach my $key (sort keys %change_by_key) {
@@ -823,10 +845,12 @@ sub save_state(;$$)
# We assume that no property ever contains a literal "".
$val = '""' if (!length($val));
push @lines, "$ky $val";
+ $prop_hash{int($val)} = 1 if (defined($ikeys{$ky}));
}
}
push @lines, "";
}
+ push @lines, map { $_.'='.$prop_by_key{$_} } sort keys %prop_hash;
foreach my $ginfo (values %gerrit_info_by_key) {
my $fetched = $$ginfo{fetched};
next if (!defined($fetched));
@@ -894,6 +918,11 @@ sub load_state_file(;$)
if (!length($_)) {
$inhdr = 0;
$change = undef;
+ } elsif (/^(\d+)=(.*)/) {
+ my ($key, $val) = (int($1), $2);
+ fail("Bad state file: indirect property with duplicate id at line $line.\n")
+ if (defined($prop_by_key{$key}));
+ $prop_by_key{$key} = $val;
} elsif (!/^(\w+) (.*)/) {
fail("Bad state file: Malformed entry at line $line.\n");
} elsif ($inhdr) {
@@ -901,6 +930,8 @@ sub load_state_file(;$)
$next_key = int($2);
} elsif ($1 eq "next_group") {
$next_group = int($2);
+ } elsif ($1 eq "next_prop") {
+ $next_prop = int($2);
} elsif ($1 eq "last_gc") {
$last_gc = int($2);
} elsif ($new && ($1 eq "verify")) {