changeset 6224:17ffdea0edbb stable

evolve: look for split successors of the correct ancestor (issue6648) Consider two changesets, 1 and 2. 1 is split into two new changesets and 2 is pruned. If we stand on 2 and call hg evolve, _singlesuccessor() will traverse ancestors of wdp in search of a changeset with successors to update to (it will be 1, which was split). In case of a split, select_split_successor() gets control. The issue is this function didn't traverse ancestors, and instead tried to look up successors of the original changeset (i.e. 2 in our case, which was pruned). We can make select_split_successor() aware of _singlesuccessor() logic by using the changeset that actually has successors without traversing ancestors again. It's done by storing that changeset in MultipleSuccessorsError exception.
author Anton Shestakov <av6@dwimlabs.net>
date Thu, 21 Apr 2022 22:19:27 +0400
parents 4298ae0b966d
children 810f085d0853
files CHANGELOG hgext3rd/evolve/evolvecmd.py hgext3rd/evolve/utility.py tests/test-check-sdist.t tests/test-evolve-issue6648.t
diffstat 5 files changed, 96 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG	Sat Apr 09 20:49:43 2022 +0300
+++ b/CHANGELOG	Thu Apr 21 22:19:27 2022 +0400
@@ -5,6 +5,8 @@
 --------------------
 
   * evolve: avoid updating working copy when --dry-run is given (issue6669)
+  * evolve: correctly pick successors of a split changeset when its child was
+    pruned (issue6648)
   * fixup: work correctly with bookmarks
 
 10.5.0 -- 2022-02-23
--- a/hgext3rd/evolve/evolvecmd.py	Sat Apr 09 20:49:43 2022 +0300
+++ b/hgext3rd/evolve/evolvecmd.py	Thu Apr 21 22:19:27 2022 +0400
@@ -133,7 +133,7 @@
             ui.write_err(msg)
             return (False, b".")
         if exc.splitflag:
-            splitsucc = utility.select_split_successor(ui, repo, obs)
+            splitsucc = utility.select_split_successor(ui, repo, repo[exc.rev])
             if not splitsucc:
                 msg = _(b"could not solve instability, "
                         b"ambiguous destination: "
@@ -1823,7 +1823,7 @@
         ctx = repo[utility._singlesuccessor(repo, oldctx)]
     except utility.MultipleSuccessorsError as exc:
         if exc.splitflag:
-            splitsucc = utility.select_split_successor(ui, repo, oldctx)
+            splitsucc = utility.select_split_successor(ui, repo, repo[exc.rev])
             if splitsucc:
                 ctx = repo[splitsucc]
             else:
--- a/hgext3rd/evolve/utility.py	Sat Apr 09 20:49:43 2022 +0300
+++ b/hgext3rd/evolve/utility.py	Thu Apr 21 22:19:27 2022 +0400
@@ -70,12 +70,14 @@
     """Exception raised by _singlesuccessor() when multiple successor sets exists
 
     Attributes:
+        rev               the revision that has multiple successor sets
         successorssets    the list of successorssets to call to easily recover
         divergenceflag    indicate that changeset has divergent rewriting
         splitflag         indicate that changeset was split
     """
 
-    def __init__(self, successorssets):
+    def __init__(self, rev, successorssets):
+        self.rev = rev
         self.successorssets = successorssets
         self.divergenceflag = len(successorssets) > 1
         self.splitflag = len(successorssets[0]) > 1
@@ -124,7 +126,7 @@
         obs = obs.p1()
         newer = obsutil.successorssets(repo, obs.node(), cache=cache)
     if len(newer) > 1 or len(newer[0]) > 1:
-        raise MultipleSuccessorsError(newer)
+        raise MultipleSuccessorsError(obs.rev(), newer)
 
     return repo[newer[0][0]].rev()
 
--- a/tests/test-check-sdist.t	Sat Apr 09 20:49:43 2022 +0300
+++ b/tests/test-check-sdist.t	Thu Apr 21 22:19:27 2022 +0400
@@ -35,7 +35,7 @@
 
   $ tar -tzf hg-evolve-*.tar.gz | sed 's|^hg-evolve-[^/]*/||' | sort > files
   $ wc -l files
-  356 files
+  357 files
   $ fgrep debian files
   tests/test-check-debian.t
   $ fgrep __init__.py files
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-issue6648.t	Thu Apr 21 22:19:27 2022 +0400
@@ -0,0 +1,87 @@
+Finding split successors for the correct ancestor (issue6648)
+https://bz.mercurial-scm.org/show_bug.cgi?id=6648
+
+  $ . $TESTDIR/testlib/common.sh
+
+  $ cat << EOF >> $HGRCPATH
+  > [extensions]
+  > evolve =
+  > EOF
+
+  $ hg init issue6648
+  $ cd issue6648
+
+  $ echo hi > foo
+  $ hg commit -qAm 'r0'
+  $ echo foo >> foo
+  $ echo foo >> foosplit
+  $ hg commit -qAm 'r1_splitme'
+  $ echo bar > bar
+  $ hg commit -qAm 'r2_obsoleteme'
+  $ echo baz > baz
+  $ hg commit -qAm 'r3'
+
+  $ hg prune -r 2
+  1 changesets pruned
+  1 new orphan changesets
+  $ hg split -r 1 --no-interactive foosplit
+  1 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  reverting foo
+  adding foosplit
+  created new head
+  no more changes to split
+
+  $ hg update -r 2
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory parent is obsolete! (5c9b6cf2edc5)
+  (use 'hg evolve' to update to its parent successor)
+
+  $ hg log -G
+  o  changeset:   5:983ec6453b57
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     r1_splitme
+  |
+  o  changeset:   4:9ca7a4996099
+  |  parent:      0:e9326971c0ba
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     r1_splitme
+  |
+  | *  changeset:   3:c1e686af368d
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  instability: orphan
+  | |  summary:     r3
+  | |
+  | @  changeset:   2:5c9b6cf2edc5
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  obsolete:    pruned using prune
+  | |  summary:     r2_obsoleteme
+  | |
+  | x  changeset:   1:acdff8eea54c
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    obsolete:    split using split as 4:9ca7a4996099, 5:983ec6453b57
+  |    summary:     r1_splitme
+  |
+  o  changeset:   0:e9326971c0ba
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     r0
+  
+
+handling obsolete wdp works
+
+  $ hg evolve
+  update:[5] r1_splitme
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory is now at 983ec6453b57
+
+stabilizing the orphan works
+
+  $ hg evolve
+  move:[3] r3
+  atop:[5] r1_splitme