histedit: convert fold/roll actions into a class
authorDurham Goode <durham@fb.com>
Sat, 04 Apr 2015 02:03:27 -0700
changeset 24771 3133e246c912
parent 24770 facdb20e60e9
child 24772 8f6494eb16eb
histedit: convert fold/roll actions into a class This converts the fold/roll actions into a histeditclass instance, as part of an ongoing effort to refactor histedit for maintainability and robustness. The tests changed for two reasons: 1) We get a new 'empty changeset' warning because we now warn more consistently between normal histedit and --continue about commits disappearing. 2) Previously we were not putting the histedit-source extra field on the temporary fold commit during normal runs, but we were on --continue runs. By unifying these code paths we now consistently put histedit-source on the temporary fold commit, which changes some of the hashes in the backup bundles.
hgext/histedit.py
tests/test-histedit-bookmark-motion.t
tests/test-histedit-fold.t
tests/test-histedit-obsolete.t
--- a/hgext/histedit.py	Sat Apr 04 01:00:51 2015 -0700
+++ b/hgext/histedit.py	Sat Apr 04 02:03:27 2015 -0700
@@ -510,26 +510,47 @@
     def commiteditor(self):
         return cmdutil.getcommiteditor(edit=True, editform='histedit.edit')
 
-def rollup(ui, state, ha, opts):
-    rollupopts = opts.copy()
-    rollupopts['rollup'] = True
-    return fold(ui, state, ha, rollupopts)
+class fold(histeditaction):
+    def continuedirty(self):
+        repo = self.repo
+        rulectx = repo[self.node]
+
+        commit = commitfuncfor(repo, rulectx)
+        commit(text='fold-temp-revision %s' % node.short(self.node),
+               user=rulectx.user(), date=rulectx.date(),
+               extra=rulectx.extra())
+
+    def continueclean(self):
+        repo = self.repo
+        ctx = repo['.']
+        rulectx = repo[self.node]
+        parentctxnode = self.state.parentctxnode
+        if ctx.node() == parentctxnode:
+            repo.ui.warn(_('%s: empty changeset\n') %
+                              node.short(self.node))
+            return ctx, [(self.node, (parentctxnode,))]
 
-def fold(ui, state, ha, opts):
-    repo, ctxnode = state.repo, state.parentctxnode
-    ctx = repo[ctxnode]
-    oldctx = repo[ha]
-    hg.update(repo, ctx.node())
-    stats = applychanges(ui, repo, oldctx, opts)
-    if stats and stats[3] > 0:
-        raise error.InterventionRequired(
-            _('Fix up the change and run hg histedit --continue'))
-    n = repo.commit(text='fold-temp-revision %s' % ha[:12], user=oldctx.user(),
-                    date=oldctx.date(), extra=oldctx.extra())
-    if n is None:
-        ui.warn(_('%s: empty changeset') % ha[:12])
-        return ctx, []
-    return finishfold(ui, repo, ctx, oldctx, n, opts, [])
+        parentctx = repo[parentctxnode]
+        newcommits = set(c.node() for c in repo.set('(%d::. - %d)', parentctx,
+                                                 parentctx))
+        if not newcommits:
+            repo.ui.warn(_('%s: cannot fold - working copy is not a '
+                           'descendant of previous commit %s\n') %
+                           (node.short(self.node), node.short(parentctxnode)))
+            return ctx, [(self.node, (ctx.node(),))]
+
+        middlecommits = newcommits.copy()
+        middlecommits.discard(ctx.node())
+
+        foldopts = {}
+        if isinstance(self, rollup):
+            foldopts['rollup'] = True
+
+        return finishfold(repo.ui, repo, parentctx, rulectx, ctx.node(),
+                          foldopts, middlecommits)
+
+class rollup(fold):
+    pass
 
 def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
     parent = ctx.parents()[0].node()
@@ -907,10 +928,7 @@
         new = None
         if s.modified or s.added or s.removed or s.deleted:
             # prepare the message for the commit to comes
-            if action in ('f', 'fold', 'r', 'roll'):
-                message = 'fold-temp-revision %s' % currentnode[:12]
-            else:
-                message = ctx.description()
+            message = ctx.description()
             editor = cmdutil.getcommiteditor()
             commit = commitfuncfor(repo, ctx)
             new = commit(text=message, user=ctx.user(), date=ctx.date(),
@@ -925,26 +943,7 @@
             # to parent.
             replacements.append((ctx.node(), tuple(newchildren)))
 
-        if action in ('f', 'fold', 'r', 'roll'):
-            if newchildren:
-                # finalize fold operation if applicable
-                if new is None:
-                    new = newchildren[-1]
-                else:
-                    newchildren.pop()  # remove new from internal changes
-                foldopts = opts
-                if action in ('r', 'roll'):
-                    foldopts = foldopts.copy()
-                    foldopts['rollup'] = True
-                parentctx, repl = finishfold(ui, repo, parentctx, ctx, new,
-                                             foldopts, newchildren)
-                replacements.extend(repl)
-            else:
-                # newchildren is empty if the fold did not result in any commit
-                # this happen when all folded change are discarded during the
-                # merge.
-                replacements.append((ctx.node(), (parentctx.node(),)))
-        elif newchildren:
+        if newchildren:
             # otherwise update "parentctx" before proceeding further
             parentctx = repo[newchildren[-1]]
 
--- a/tests/test-histedit-bookmark-motion.t	Sat Apr 04 01:00:51 2015 -0700
+++ b/tests/test-histedit-bookmark-motion.t	Sat Apr 04 02:03:27 2015 -0700
@@ -92,7 +92,7 @@
   histedit: moving bookmarks two from 177f92b77385 to b346ab9a313d
   histedit: moving bookmarks will-move-backwards from d2ae7f538514 to cb9a9f314b8b
   saved backup bundle to $TESTTMP/r/.hg/strip-backup/d2ae7f538514-48787b8d-backup.hg (glob)
-  saved backup bundle to $TESTTMP/r/.hg/strip-backup/96e494a2d553-60cea58b-backup.hg (glob)
+  saved backup bundle to $TESTTMP/r/.hg/strip-backup/96e494a2d553-3c6c5d92-backup.hg (glob)
   $ hg log --graph
   @  changeset:   3:cacdfd884a93
   |  bookmark:    five
--- a/tests/test-histedit-fold.t	Sat Apr 04 01:00:51 2015 -0700
+++ b/tests/test-histedit-fold.t	Sat Apr 04 02:03:27 2015 -0700
@@ -307,6 +307,7 @@
   $ hg resolve --mark file
   (no more unresolved files)
   $ hg histedit --continue
+  251d831eeec5: empty changeset
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   saved backup bundle to $TESTTMP/*-backup.hg (glob)
   $ hg logt --graph
--- a/tests/test-histedit-obsolete.t	Sat Apr 04 01:00:51 2015 -0700
+++ b/tests/test-histedit-obsolete.t	Sat Apr 04 02:03:27 2015 -0700
@@ -64,7 +64,7 @@
   > fold e860deea161a 4 e
   > pick 652413bf663e 5 f
   > EOF
-  saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-60cea58b-backup.hg (glob)
+  saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-3c6c5d92-backup.hg (glob)
   $ hg log --graph --hidden
   @  8:cacdfd884a93 f
   |
@@ -427,9 +427,9 @@
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-be4b3835-backup.hg (glob)
-  saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-08306a6b-backup.hg (glob)
-  saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-86c99c41-backup.hg (glob)
+  saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-96092fce-backup.hg (glob)
+  saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-f3469cf8-backup.hg (glob)
+  saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-d89a19d7-backup.hg (glob)
   $ hg log -G
   @  19:f9daec13fb98 (secret) i
   |