Subject: [StGit PATCH 5/5] stg repair: Patchify non-patch commits between patches

From: Karl Hasselström <[email-masked]>
Date: Sun, 11 Nov 2007 20:44:04 +0100

This teaches "stg repair" to find non-patch commits that sit between
patches, and turn them into patches. This situation can happen e.g.
like this:

  stg new -m A && stg new -m B && stg new -m C
  stg pop A B C
  stg push B
  echo foo > foo && git add foo && stg refresh
  git reset --hard $(stg id C)

The old "stg repair" would at this point simply conclude that A and C
are applied, and B unapplied. However, B's old commit is still between
them even though it's not a patch, which will cause problems later --
StGit generally assumes that the applied patches are a consecutive
string of commits. The new "stg repair", on the other hand, will find
B's old commit, and create a new patch for it.

One downside of this change is that we can no longer conclude that all
is well just because head == top, so no-op runs of "stg repair" just
got more expensive.

Signed-off-by: Karl Hasselström <[email-masked]>

---

 stgit/commands/repair.py |   19 +++++++------------
 1 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/stgit/commands/repair.py b/stgit/commands/repair.py
index f8fe624..4787f72 100644
--- a/stgit/commands/repair.py
+++ b/stgit/commands/repair.py
@@ -101,33 +101,28 @@ def read_commit_dag(branch):
 def func(parser, options, args):
     """Repair inconsistencies in StGit metadata."""
 
-    def nothing_to_do():
-        out.info('Nothing to repair')
-
     orig_applied = crt_series.get_applied()
     orig_unapplied = crt_series.get_unapplied()
 
-    # If head == top, we're done.
-    head = git.get_commit(git.get_head()).get_id_hash()
-    top = crt_series.get_current_patch()
-    if top and head == top.get_top():
-        return nothing_to_do()
-
     if crt_series.get_protected():
         raise CmdException(
             'This branch is protected. Modification is not permitted.')
 
     # Find commits that aren't patches, and applied patches.
+    head = git.get_commit(git.get_head()).get_id_hash()
     commits, patches = read_commit_dag(crt_series.get_name())
     c = commits[head]
-    patchify = []
+    patchify = []       # commits to definitely patchify
+    maybe_patchify = [] # commits to patchify if we find a patch below them
     applied = []
     while len(c.parents) == 1:
         parent, = c.parents
         if c.patch:
             applied.append(c)
-        elif not applied:
-            patchify.append(c)
+            patchify.extend(maybe_patchify)
+            maybe_patchify = []
+        else:
+            maybe_patchify.append(c)
         c = parent
     applied.reverse()
     patchify.reverse()