rewind: make sure merge commits include files from p1 and p2
authorAnton Shestakov <av6@dwimlabs.net>
Thu, 11 Jul 2019 17:04:08 +0800
changeset 4722 7839720c7c75
parent 4721 b69497b23d31
child 4723 41885988921e
rewind: make sure merge commits include files from p1 and p2 Otherwise rewinding a merge commit makes it lose all changes. This fix populates `updates` argument of rewriteutil.rewrite() with parent changesets. That argument is normally used for folding multiple changesets, but in this case it's simply used to include files from p1 and p2. Usually, rewrite() works fine using ctx.files(), but that function can return an empty list when ctx is a merge commit.
CHANGELOG
hgext3rd/evolve/rewind.py
tests/test-rewind.t
--- a/CHANGELOG	Wed Jul 10 18:16:38 2019 +0800
+++ b/CHANGELOG	Thu Jul 11 17:04:08 2019 +0800
@@ -9,6 +9,7 @@
   * evolve: improve `hg evolve --all` behavior when "." is obsolete
   * topic: fix confusion in branch heads checking logic
   * touch: now works on merge commit too
+  * rewind: fix behavior for merge commit
 
 9.0.1 - in progress
 -------------------
--- a/hgext3rd/evolve/rewind.py	Wed Jul 10 18:16:38 2019 +0800
+++ b/hgext3rd/evolve/rewind.py	Thu Jul 11 17:04:08 2019 +0800
@@ -166,9 +166,12 @@
     p2 = ctx.p2().node()
     p2 = rewindmap.get(p2, p2)
 
+    updates = []
+    if len(ctx.parents()) > 1:
+        updates = ctx.parents()
     extradict = {'extra': extra}
 
-    new, unusedvariable = rewriteutil.rewrite(unfi, ctx, [], ctx,
+    new, unusedvariable = rewriteutil.rewrite(unfi, ctx, updates, ctx,
                                               [p1, p2],
                                               commitopts=extradict)
 
--- a/tests/test-rewind.t	Wed Jul 10 18:16:38 2019 +0800
+++ b/tests/test-rewind.t	Thu Jul 11 17:04:08 2019 +0800
@@ -9,6 +9,8 @@
   > interactive = true
   > [phases]
   > publish=False
+  > [alias]
+  > glf = log -GT "{rev}: {desc} ({files})"
   > [extensions]
   > evolve =
   > EOF
@@ -938,3 +940,45 @@
   $ hg rewind
   abort: uncommitted changes
   [255]
+
+Merge commits
+-------------
+
+  $ hg up --clean .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo foo > foo
+  $ hg ci -qAm foo
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m merge
+  $ hg st --change .
+  A B
+
+  $ echo bar > foo
+  $ hg amend -m 'merge, but foo is now bar'
+  $ hg st --change .
+  M foo
+  A B
+
+  $ hg rewind --from .
+  rewinded to 1 changesets
+  (1 changesets obsoleted)
+  working directory is now at 006fd8c2fed9
+  $ hg st --change .
+  A B
+
+  $ hg glf -r '. + allpredecessors(.) + parents(.)' --hidden
+  @    6: merge ()
+  |\
+  +---x  5: merge, but foo is now bar (foo)
+  | |/
+  +---x  4: merge ()
+  | |/
+  | o  3: foo (C foo)
+  | |
+  | ~
+  o  2: c_B0 (B)
+  |
+  ~