changeset 28224:8ec5478aa0d6

histedit: also handle locally missing nodes when reading obsolescence The previous version of the code was interpreting markers to a missing node as a prune in all cases. The expected way to handle such situation is to keep reading markers, only turning successors into "prune" if they are at the end of a chain. We update the code and add a test for this.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 24 Feb 2016 16:58:07 +0100
parents 0a853dc9b306
children 5c11702fe2a3
files hgext/histedit.py tests/test-histedit-obsolete.t
diffstat 2 files changed, 42 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/histedit.py	Wed Feb 24 18:42:59 2016 +0000
+++ b/hgext/histedit.py	Wed Feb 24 16:58:07 2016 +0100
@@ -1397,6 +1397,8 @@
         return oldreplacements
 
     unfi = repo.unfiltered()
+    nm = unfi.changelog.nodemap
+    obsstore = repo.obsstore
     newreplacements = list(oldreplacements)
     oldsuccs = [r[1] for r in oldreplacements]
     # successors that have already been added to succstocheck once
@@ -1404,15 +1406,13 @@
     succstocheck = list(seensuccs)
     while succstocheck:
         n = succstocheck.pop()
-        try:
-            ctx = unfi[n]
-        except error.RepoError:
-            # XXX node unknown locally, we should properly follow marker
+        missing = nm.get(n) is None
+        markers = obsstore.successors.get(n, ())
+        if missing and not markers:
+            # dead end, mark it as such
             newreplacements.append((n, ()))
-            continue
-
-        for marker in obsolete.successormarkers(ctx):
-            nsuccs = marker.succnodes()
+        for marker in markers:
+            nsuccs = marker[1]
             newreplacements.append((n, nsuccs))
             for nsucc in nsuccs:
                 if nsucc not in seensuccs:
--- a/tests/test-histedit-obsolete.t	Wed Feb 24 18:42:59 2016 +0000
+++ b/tests/test-histedit-obsolete.t	Wed Feb 24 16:58:07 2016 +0100
@@ -54,6 +54,40 @@
   3e30a45cf2f719e96ab3922dfe039cfd047956ce 0 {e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf} (*) {'user': 'test'} (glob)
   1b2d564fad96311b45362f17c2aa855150efb35f 46abc7c4d8738e8563e577f7889e1b6db3da4199 0 (*) {'user': 'test'} (glob)
   114f4176969ef342759a8a57e6bccefc4234829b 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'user': 'test'} (glob)
+
+With some node gone missing during the edit.
+
+  $ echo "pick `hg log -r 0 -T '{node|short}'`" > plan
+  $ echo "pick `hg log -r 6 -T '{node|short}'`" >> plan
+  $ echo "edit `hg log -r 5 -T '{node|short}'`" >> plan
+  $ hg histedit -r 'all()' --commands plan
+  Editing (49d44ab2be1b), you may commit or record as needed now.
+  (hg histedit --continue to resume)
+  [1]
+  $ hg st
+  A b
+  A d
+  ? plan
+  $ hg commit --amend -X . -m XXXXXX
+  $ hg commit --amend -X . -m b2
+  $ hg --hidden --config extensions.strip= strip 'desc(XXXXXX)' --no-backup
+  $ hg histedit --continue
+  $ hg log -G
+  @  9:273c1f3b8626 c
+  |
+  o  8:aba7da937030 b2
+  |
+  o  0:cb9a9f314b8b a
+  
+  $ hg debugobsolete
+  e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'user': 'test'} (glob)
+  3e30a45cf2f719e96ab3922dfe039cfd047956ce 0 {e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf} (*) {'user': 'test'} (glob)
+  1b2d564fad96311b45362f17c2aa855150efb35f 46abc7c4d8738e8563e577f7889e1b6db3da4199 0 (*) {'user': 'test'} (glob)
+  114f4176969ef342759a8a57e6bccefc4234829b 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'user': 'test'} (glob)
+  76f72745eac0643d16530e56e2f86e36e40631f1 2ca853e48edbd6453a0674dc0fe28a0974c51b9c 0 (*) {'user': 'test'} (glob)
+  2ca853e48edbd6453a0674dc0fe28a0974c51b9c aba7da93703075eec9fb1dbaf143ff2bc1c49d46 0 (*) {'user': 'test'} (glob)
+  49d44ab2be1b67a79127568a67c9c99430633b48 273c1f3b86267ed3ec684bb13af1fa4d6ba56e02 0 (*) {'user': 'test'} (glob)
+  46abc7c4d8738e8563e577f7889e1b6db3da4199 aba7da93703075eec9fb1dbaf143ff2bc1c49d46 0 (*) {'user': 'test'} (glob)
   $ cd ..
 
 Base setup for the rest of the testing