[PATCH V2] shelve: restore parents after unshelve (issue5123)

liscju piotr.listkiewicz at gmail.com
Thu Mar 31 18:15:12 EDT 2016


# HG changeset patch
# User liscju <piotr.listkiewicz at gmail.com>
# Date 1459461357 -7200
#      Thu Mar 31 23:55:57 2016 +0200
# Node ID 427ff5e02d5d4a4cb0a51b816ac2bbca84377cfd
# Parent  ff0d3b6b287f89594bd8d0308fe2810d2a18ea01
shelve: restore parents after unshelve (issue5123)

unshelve operates on the first parent of the working directory,
commiting pending changes and applying the saved commit
in shelve on the first parent.

Before this commit it forgot about second parent, so second
parent was not restored and lost in the process. This commit makes
unshelve remember original parents of the working directory and
recreates it when working context had more than one parent.

Recreating merge parent is done in restoremergeparent function.
It sets the working copy second parent to the second parent of
pendingctx. pendingctx is changeset with saved changes to working
copy, it is best represented by the following diagram:

.. -> originalwctx -> pendingctx -> shelvectx

Restoring second parent of pendingctx is done only when originalwctx
is different than pendingctx. When pendingctx is the same as orignalwctx
it means that working copy wasn't changed so working copy after unshelve
should have only one parent - originalwctx.

diff -r ff0d3b6b287f -r 427ff5e02d5d hgext/shelve.py
--- a/hgext/shelve.py	Tue Mar 29 12:29:00 2016 -0500
+++ b/hgext/shelve.py	Thu Mar 31 23:55:57 2016 +0200
@@ -532,6 +532,7 @@ def unshelveabort(ui, repo, state, opts)
             mergefiles(ui, repo, state.wctx, state.pendingctx)
             repair.strip(ui, repo, state.stripnodes, backup=False,
                          topic='shelve')
+            restoremergeparent(repo, state.wctx, state.pendingctx)
         finally:
             shelvedstate.clear(repo)
             ui.warn(_("unshelve of '%s' aborted\n") % state.name)
@@ -565,6 +566,14 @@ def restorebranch(ui, repo, branchtorest
         ui.status(_('marked working directory as branch %s\n')
                   % branchtorestore)
 
+def restoremergeparent(repo, originalwctx, pendingctx):
+    if originalwctx != pendingctx and len(pendingctx.parents()) > 1:
+        # We want to keep first parent as it is now,
+        # only second parent should change
+        p1 = repo['.'].node()
+        p2 = pendingctx.p2().node()
+        repo.setparents(p1, p2)
+
 def unshelvecleanup(ui, repo, name, opts):
     """remove related files after an unshelve"""
     if not opts.get('keep'):
@@ -605,6 +614,7 @@ def unshelvecontinue(ui, repo, state, op
 
         mergefiles(ui, repo, state.wctx, shelvectx)
         restorebranch(ui, repo, state.branchtorestore)
+        restoremergeparent(repo, state.wctx, state.pendingctx)
 
         repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
         shelvedstate.clear(repo)
@@ -793,6 +803,7 @@ def _dounshelve(ui, repo, *shelved, **op
 
         mergefiles(ui, repo, pctx, shelvectx)
         restorebranch(ui, repo, branchtorestore)
+        restoremergeparent(repo, pctx, tmpwctx)
 
         # Forget any files that were unknown before the shelve, unknown before
         # unshelve started, but are now added.
diff -r ff0d3b6b287f -r 427ff5e02d5d tests/test-shelve.t
--- a/tests/test-shelve.t	Tue Mar 29 12:29:00 2016 -0500
+++ b/tests/test-shelve.t	Thu Mar 31 23:55:57 2016 +0200
@@ -1583,3 +1583,459 @@ On non bare shelve the branch informatio
   ? b
   $ hg branch
   default
+
+  $ cd ..
+
+When unshelving is done on working context that has more than
+one parents, working context after unshelving should still has
+the same parents as before.
+
+  $ hg init unshelving_restores_merge_parents
+  $ cd unshelving_restores_merge_parents
+  $ touch a
+  $ hg add a
+  $ hg commit -m "a"
+  $ touch b
+  $ hg add b
+  $ hg commit -m "b"
+  $ hg update -r 0
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ touch c
+  $ hg add c
+  $ hg commit -m "c"
+  created new head
+  $ hg update -r 1
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg log -G
+  o  changeset:   2:d5e255ef74f8
+  |  tag:         tip
+  |  parent:      0:3903775176ed
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     c
+  |
+  | @  changeset:   1:0e067c57feba
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     b
+  |
+  o  changeset:   0:3903775176ed
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     a
+  
+  $ touch d
+  $ hg add d
+  $ hg shelve
+  shelved as default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge -r 2
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg log -G
+  @  changeset:   2:d5e255ef74f8
+  |  tag:         tip
+  |  parent:      0:3903775176ed
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     c
+  |
+  | @  changeset:   1:0e067c57feba
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     b
+  |
+  o  changeset:   0:3903775176ed
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     a
+  
+  $ hg unshelve
+  unshelving change 'default'
+  temporarily committing pending changes (restore with 'hg unshelve --abort')
+  rebasing shelved changes
+  rebasing 4:013284d9655e "changes to: b" (tip)
+  $ hg parents
+  changeset:   1:0e067c57feba
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     b
+  
+  changeset:   2:d5e255ef74f8
+  tag:         tip
+  parent:      0:3903775176ed
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     c
+  
+  $ hg status
+  A d
+  $ hg commit -m "d"
+  $ hg log -G
+  @    changeset:   3:cf9d915cbda8
+  |\   tag:         tip
+  | |  parent:      1:0e067c57feba
+  | |  parent:      2:d5e255ef74f8
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     d
+  | |
+  | o  changeset:   2:d5e255ef74f8
+  | |  parent:      0:3903775176ed
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     c
+  | |
+  o |  changeset:   1:0e067c57feba
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     b
+  |
+  o  changeset:   0:3903775176ed
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     a
+  
+
+Unshelve should preserve merge parents also when used with --continue
+
+  $ touch e
+  $ hg add e
+  $ hg commit -m "e"
+  $ hg update -r 3
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ touch f
+  $ hg add f
+  $ hg commit -m "f"
+  created new head
+  $ echo "xxx" >> g
+  $ hg add g
+  $ hg shelve
+  shelved as default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg log -G
+  @  changeset:   5:eed8e5d60bdb
+  |  tag:         tip
+  |  parent:      3:cf9d915cbda8
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     f
+  |
+  | o  changeset:   4:2bb82181804e
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     e
+  |
+  o    changeset:   3:cf9d915cbda8
+  |\   parent:      1:0e067c57feba
+  | |  parent:      2:d5e255ef74f8
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     d
+  | |
+  | o  changeset:   2:d5e255ef74f8
+  | |  parent:      0:3903775176ed
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     c
+  | |
+  o |  changeset:   1:0e067c57feba
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     b
+  |
+  o  changeset:   0:3903775176ed
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     a
+  
+  $ hg merge -r 4
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg parents
+  changeset:   5:eed8e5d60bdb
+  tag:         tip
+  parent:      3:cf9d915cbda8
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     f
+  
+  changeset:   4:2bb82181804e
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     e
+  
+  $ echo "ggg" >> g
+  $ hg add g
+  $ hg unshelve
+  unshelving change 'default'
+  temporarily committing pending changes (restore with 'hg unshelve --abort')
+  rebasing shelved changes
+  rebasing 7:f3112b16f74c "changes to: f" (tip)
+  merging g
+  warning: conflicts while merging g! (edit, then use 'hg resolve --mark')
+  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  [1]
+  $ hg resolve --mark g
+  (no more unresolved files)
+  continue: hg unshelve --continue
+  $ hg unshelve --continue
+  rebasing 7:f3112b16f74c "changes to: f" (tip)
+  unshelve of 'default' complete
+  $ hg parents
+  changeset:   5:eed8e5d60bdb
+  tag:         tip
+  parent:      3:cf9d915cbda8
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     f
+  
+  changeset:   4:2bb82181804e
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     e
+  
+  $ hg commit -m "g"
+  $ hg log -G
+  @    changeset:   6:* (glob)
+  |\   tag:         tip
+  | |  parent:      5:eed8e5d60bdb
+  | |  parent:      4:2bb82181804e
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     g
+  | |
+  | o  changeset:   5:eed8e5d60bdb
+  | |  parent:      3:cf9d915cbda8
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     f
+  | |
+  o |  changeset:   4:2bb82181804e
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     e
+  |
+  o    changeset:   3:cf9d915cbda8
+  |\   parent:      1:0e067c57feba
+  | |  parent:      2:d5e255ef74f8
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     d
+  | |
+  | o  changeset:   2:d5e255ef74f8
+  | |  parent:      0:3903775176ed
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     c
+  | |
+  o |  changeset:   1:0e067c57feba
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     b
+  |
+  o  changeset:   0:3903775176ed
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     a
+  
+
+Unshelve should preserve merge parents after --abort
+
+  $ touch h
+  $ hg add h
+  $ hg commit -m "h"
+  $ hg update -r 6
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ touch i
+  $ hg add i
+  $ hg commit -m "i"
+  created new head
+  $ hg log -G
+  @  changeset:   8:* (glob)
+  |  tag:         tip
+  |  parent:      6:* (glob)
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     i
+  |
+  | o  changeset:   7:* (glob)
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     h
+  |
+  o    changeset:   6:* (glob)
+  |\   parent:      5:eed8e5d60bdb
+  | |  parent:      4:2bb82181804e
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     g
+  | |
+  | o  changeset:   5:eed8e5d60bdb
+  | |  parent:      3:cf9d915cbda8
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     f
+  | |
+  o |  changeset:   4:2bb82181804e
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     e
+  |
+  o    changeset:   3:cf9d915cbda8
+  |\   parent:      1:0e067c57feba
+  | |  parent:      2:d5e255ef74f8
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     d
+  | |
+  | o  changeset:   2:d5e255ef74f8
+  | |  parent:      0:3903775176ed
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     c
+  | |
+  o |  changeset:   1:0e067c57feba
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     b
+  |
+  o  changeset:   0:3903775176ed
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     a
+  
+  $ echo "xxx" >> j
+  $ hg add j
+  $ hg shelve
+  shelved as default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge -r 7
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg parents
+  changeset:   8:* (glob)
+  tag:         tip
+  parent:      6:* (glob)
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     i
+  
+  changeset:   7:* (glob)
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     h
+  
+  $ echo "jjj" >> j
+  $ hg add j
+  $ hg unshelve
+  unshelving change 'default'
+  temporarily committing pending changes (restore with 'hg unshelve --abort')
+  rebasing shelved changes
+  rebasing 10:* "changes to: i" (tip) (glob)
+  merging j
+  warning: conflicts while merging j! (edit, then use 'hg resolve --mark')
+  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  [1]
+  $ hg unshelve --abort
+  rebase aborted
+  unshelve of 'default' aborted
+  $ hg status
+  A j
+  ? g.orig
+  ? j.orig
+  $ hg parents
+  changeset:   8:* (glob)
+  tag:         tip
+  parent:      6:* (glob)
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     i
+  
+  changeset:   7:* (glob)
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     h
+  
+  $ hg log -G
+  @  changeset:   8:* (glob)
+  |  tag:         tip
+  |  parent:      6:* (glob)
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     i
+  |
+  | @  changeset:   7:* (glob)
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     h
+  |
+  o    changeset:   6:* (glob)
+  |\   parent:      5:eed8e5d60bdb
+  | |  parent:      4:2bb82181804e
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     g
+  | |
+  | o  changeset:   5:eed8e5d60bdb
+  | |  parent:      3:cf9d915cbda8
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     f
+  | |
+  o |  changeset:   4:2bb82181804e
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     e
+  |
+  o    changeset:   3:cf9d915cbda8
+  |\   parent:      1:0e067c57feba
+  | |  parent:      2:d5e255ef74f8
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     d
+  | |
+  | o  changeset:   2:d5e255ef74f8
+  | |  parent:      0:3903775176ed
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     c
+  | |
+  o |  changeset:   1:0e067c57feba
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     b
+  |
+  o  changeset:   0:3903775176ed
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     a
+  
+Unshelve on merge parent should have only one parent
+
+  $ hg commit -m "Merge 7 and 8"
+  $ touch k
+  $ hg add k
+  $ hg parents
+  changeset:   9:* (glob)
+  tag:         tip
+  parent:      8:* (glob)
+  parent:      7:* (glob)
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Merge 7 and 8
+  
+  $ hg shelve
+  shelved as default-01
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg unshelve
+  unshelving change 'default-01'
+  $ hg parents
+  changeset:   9:* (glob)
+  tag:         tip
+  parent:      8:* (glob)
+  parent:      7:* (glob)
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Merge 7 and 8
+  


More information about the Mercurial-devel mailing list