From 84a022344a0f4986f58c690eb933da480a59957f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 21 Dec 2020 16:25:58 +0100 Subject: ggc: fix pruning of Changes with no corresponding state refs Changes which were only grouped won't have any state refs associated with them, so looping over refs would never garbage-collect them. this mistake stemmed from an earlier implementation having refs associated with each assigned Change. Change-Id: I9b571b01ed87cdab995688873e5328a9aede173e Reviewed-by: Alexandru Croitor --- bin/git-ggc | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) (limited to 'bin') diff --git a/bin/git-ggc b/bin/git-ggc index ea71bce..0c28f3f 100755 --- a/bin/git-ggc +++ b/bin/git-ggc @@ -204,17 +204,15 @@ sub perform_gc() my $local_changes = visit_revs_pull('HEAD', (map { 'refs/heads/'.$_ } @local_refs)); print "Collecting locally present Changes ...\n" if ($debug); - my %zap_ids; # { gerrit-id => 1 } - foreach my $key (keys %zaps) { + my %zap_ids; # { change-id => 1 } + foreach my $key (sort keys %change_by_key) { my $change = $change_by_key{$key}; - if ($change) { - my $changeid = $$change{id}; - if (defined($$local_changes{$changeid})) { - print "Keeping $key ($changeid): exists locally.\n" - if ($verbose); - delete $zaps{$key}; - next; - } + my $changeid = $$change{id}; + if (defined($$local_changes{$changeid})) { + print "Keeping $key ($changeid): exists locally.\n" + if ($verbose); + delete $zaps{$key}; + } else { $zap_ids{$changeid} = 1; } } @@ -225,24 +223,30 @@ sub perform_gc() if (%zap_ids || %fzaps); print "Pruning stale Changes ...\n" if ($debug); - foreach my $key (sort keys %zaps) { + foreach my $key (sort keys %change_by_key) { my $change = $change_by_key{$key}; - if ($change) { - # Even Changes which are absent from the local branch are pruned - # only if they are in a terminal state. Otherwise, there is reason - # to believe that they might be used again at a later point. - my $changeid = $$change{id}; - if ($change2active{$changeid}) { - print "Keeping $key ($changeid): active on Gerrit.\n" - if ($verbose); - $$local_changes{$changeid} = 1; - delete $zaps{$key}; - next; - } + # Even Changes which are absent from the local branch are pruned + # only if they are in a terminal state. Otherwise, there is reason + # to believe that they might be used again at a later point. + my $changeid = $$change{id}; + if (!defined($zap_ids{$changeid})) { + # Exists locally; already handled above. + } elsif ($change2active{$changeid}) { + print "Keeping $key ($changeid): active on Gerrit.\n" + if ($verbose); + $$local_changes{$changeid} = 1; + delete $zaps{$key}; + } else { print "Pruning $key ($changeid).\n" if ($verbose); $$change{garbage} = 1; - } else { - print "Pruning $key (unrecognized Change).\n" if ($verbose); + } + } + if ($verbose) { + foreach my $key (sort keys %zaps) { + # This is unlikely to ever trigger, as the regular load_refs() + # cleans up anyway. + print "Pruning $key (unrecognized Change).\n" + if (!$change_by_key{$key}); } } -- cgit v1.2.1