[PATCH] histedit: handle obsolete commits unknown to histedit state (issue4800)

Kostia Balytskyi ikostia at fb.com
Mon Jan 18 06:03:19 CST 2016


Forgot to add --flag v3, sorry.



On 1/18/16, 12:02 PM, "Kostia Balytskyi" <ikostia at fb.com> wrote:

># HG changeset patch
># User Kostia Balytskyi <ikostia at fb.com>
># Date 1453118372 0
>#      Mon Jan 18 11:59:32 2016 +0000
># Node ID 289562ec0ef6a732c54900842224a04932009d05
># Parent  443848eece189002c542339dc1cf84f49a94c824
>histedit: handle obsolete commits unknown to histedit state (issue4800)
>
>This fix takes sets of final and new commits from
>histedit's state and replaces them with their successor sets.
>
>diff --git a/hgext/histedit.py b/hgext/histedit.py
>--- a/hgext/histedit.py
>+++ b/hgext/histedit.py
>@@ -1362,6 +1362,32 @@
>     tmpnodes = allsuccs & replaced
>     return newnodes, tmpnodes
> 
>+def nonobsoletesuccessors(repo, nodes):
>+    """find all non-obsolete successors for each of the nodes
>+
>+    This fails if any of the nodes has more than one successor
>+    set, e.g. if it diverged at some point and then became obsolete.
>+    """
>+    if not obsolete.isenabled(repo, obsolete.createmarkersopt):
>+        # no obsoletion is enabled, no successors should exist
>+        return nodes
>+
>+    result = []
>+    for cl in nodes:
>+        succset = obsolete.successorssets(repo, cl)
>+        if len(succset) > 1:
>+            msg = _("changeset %s split or divergent,"
>+                    " cannot determine unique successor")
>+            hint =_("solve the issue and run histedit --continue"
>+                    " or abort with histedit --abort")
>+            raise error.Abort(msg % node.hex(cl), hint=hint)
>+        elif len(succset) == 1:
>+            # non-divergent successor set
>+            result += succset[0]
>+        else:
>+            # changeset has been pruned, nothing needs to be done
>+            pass
>+    return result
> 
> def processreplacement(state):
>     """process the list of replacements to return
>@@ -1408,11 +1434,13 @@
>     # turn `final` into list (topologically sorted)
>     nm = state.repo.changelog.nodemap
>     for prec, succs in final.items():
>+        succs = nonobsoletesuccessors(state.repo, succs)
>         final[prec] = sorted(succs, key=nm.get)
> 
>+    nonobsoletenew = nonobsoletesuccessors(state.repo, new)
>     # computed topmost element (necessary for bookmark)
>-    if new:
>-        newtopmost = sorted(new, key=state.repo.changelog.rev)[-1]
>+    if nonobsoletenew:
>+        newtopmost = sorted(nonobsoletenew, key=state.repo.changelog.rev)[-1]
>     elif not final:
>         # Nothing rewritten at all. we won't need `newtopmost`
>         # It is the same as `oldtopmost` and `processreplacement` know it
>@@ -1422,7 +1450,7 @@
>         r = state.repo.changelog.rev
>         newtopmost = state.repo[sorted(final, key=r)[0]].p1().node()
> 
>-    return final, tmpnodes, new, newtopmost
>+    return final, tmpnodes, nonobsoletenew, newtopmost
> 
> def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
>     """Move bookmark from old to newly created node"""
>diff --git a/tests/test-histedit-edit.t b/tests/test-histedit-edit.t
>--- a/tests/test-histedit-edit.t
>+++ b/tests/test-histedit-edit.t
>@@ -477,3 +477,33 @@
>   #  f, fold = use commit, but combine it with the one above
>   #  r, roll = like fold, but discard this commit's description
>   #
>+
>+Ensure that creating obsole revisions while editing commits does not break histedit
>+
>+  $ hg init boo
>+  $ cd boo
>+  $ echo a > aaaa
>+  $ hg ci -Am a
>+  adding aaaa
>+  $ echo a > bbbb
>+  $ echo a > cccc
>+  $ echo a > cccc
>+  $ hg ci -Am b
>+  adding bbbb
>+  adding cccc
>+  $ echo a > dddd
>+  $ hg ci -Am c
>+  adding dddd
>+  $ echo "pick `hg log -r -1 -T '{node|short}'`" > plan
>+  $ echo "pick `hg log -r -3 -T '{node|short}'`" >> plan
>+  $ echo "edit `hg log -r -2 -T '{node|short}'`" >> plan
>+  $ hg histedit -qr 'all()' --commands plan
>+  Editing \([0-9a-f]{12}\), you may commit or record as needed now. (re)
>+  (hg histedit --continue to resume)
>+  [1]
>+  $ hg st
>+  A bbbb
>+  A cccc
>+  ? plan
>+  $ hg commit --amend bbbb
>+  saved backup bundle to $TESTTMP/r0/boo/.hg/strip-backup/*-amend-backup.hg (glob)


More information about the Mercurial-devel mailing list