chiark / gitweb /
git-debrebase: Fix snagging
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 9 Jun 2018 12:08:51 +0000 (13:08 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 16 Jun 2018 21:40:14 +0000 (22:40 +0100)
* Rename $snags_checked to $snags_summarised and make it a counter
  of the snags we have summarised in snags_maybe_bail.
* Introduce all_snags_summarised, which uses arithmetic to see if
  we have had new snags since the most recent snags_maybe_bail,
* Use this in run_deferred_updates rather than the existing
  approach; this means we can crash if there were new snags for
  which we should have bailed.
* Make snags_maybe_bail not produce a redundant identical summary.
* Initialise counters to 0 so arithmetic does not give undef warnings.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
git-debrebase

index d174fe6..d9ceb20 100755 (executable)
@@ -102,17 +102,19 @@ sub fresh_workarea () {
     in_workarea sub { playtree_setup };
 }
 
-our $snags_forced;
-our $snags_tripped;
-our $snags_checked;
+our $snags_forced = 0;
+our $snags_tripped = 0;
+our $snags_summarised = 0;
 our @deferred_updates;
 our @deferred_update_messages;
 
+sub all_snags_summarised () {
+    $snags_forced + $snags_tripped == $snags_summarised;
+}
 sub run_deferred_updates ($) {
     my ($mrest) = @_;
 
-    confess 'dangerous internal error' if
-       !$snags_checked || $snags_tripped || $snags_forced;
+    confess 'dangerous internal error' unless all_snags_summarised();
 
     my @upd_cmd = (@git, qw(update-ref --stdin -m), "debrebase: $mrest");
     debugcmd '>|', @upd_cmd;
@@ -247,26 +249,30 @@ sub snag ($$) {
     }
 }
 
+# Important: all mainline code must call snags_maybe_bail after
+# any point where snag might be called, but before making changes
+# (eg before any call to run_deferred_updates).  snags_maybe_bail
+# may be called more than once if necessary (but this is not ideal
+# because then the messages about number of snags may be confusing).
 sub snags_maybe_bail () {
-    $snags_checked++;
+    return if all_snags_summarised();
     if ($snags_forced) {
        printf STDERR
            "%s: snags: %d overriden by individual -f options\n",
            $us, $snags_forced;
-       $snags_forced=0;
     }
     if ($snags_tripped) {
        if ($opt_force) {
            printf STDERR
                "%s: snags: %d overriden by global --force\n",
                $us, $snags_tripped;
-           $snags_tripped=0;
        } else {
            fail sprintf
   "%s: snags: %d blockers (you could -f<tag>, or --force)",
                $us, $snags_tripped;
        }
     }
+    $snags_summarised = $snags_forced + $snags_tripped;
 }
 sub any_snags () {
     return $snags_forced || $snags_tripped;