[PATCH] shelve: adds restoring newly created branch (issue5048)

liscju piotr.listkiewicz at gmail.com
Wed Feb 17 13:17:11 UTC 2016


# HG changeset patch
# User liscju <piotr.listkiewicz at gmail.com>
# Date 1455067407 -3600
#      Wed Feb 10 02:23:27 2016 +0100
# Node ID da5e9a27089d31988dfd2d8cf62fc63805aa13d7
# Parent  a036e1ae1fbe88ab99cb861ebfc2e4da7a3912ca
shelve: adds restoring newly created branch (issue5048)

Before this patch shelve never preserved branch information,
so after applying unshelve branch was the same as it was
on working copy no matter in which branch shelve took place.

This patch makes shelve remember branch in which shelve takes
place and restoring it in unshelve if shelve takes place
in newly created branch. In other words, restoring information
takes place when shelve is made on working copy that is
prepared for a branch change.

diff -r a036e1ae1fbe -r da5e9a27089d hgext/shelve.py
--- a/hgext/shelve.py	Sun Feb 07 00:49:31 2016 -0600
+++ b/hgext/shelve.py	Wed Feb 10 02:23:27 2016 +0100
@@ -148,6 +148,8 @@
             pendingctx = fp.readline().strip()
             parents = [bin(h) for h in fp.readline().split()]
             stripnodes = [bin(h) for h in fp.readline().split()]
+            restorebranch = fp.readline().strip() == 'True'
+            origshelvebranch = fp.readline().strip()
         finally:
             fp.close()
 
@@ -157,11 +159,14 @@
         obj.pendingctx = repo[bin(pendingctx)]
         obj.parents = parents
         obj.stripnodes = stripnodes
+        obj.restorebranch = restorebranch
+        obj.origshelvebranch = origshelvebranch
 
         return obj
 
     @classmethod
-    def save(cls, repo, name, originalwctx, pendingctx, stripnodes):
+    def save(cls, repo, name, originalwctx, pendingctx, stripnodes,
+             restorebranch, origshelvebranch):
         fp = repo.vfs(cls._filename, 'wb')
         fp.write('%i\n' % cls._version)
         fp.write('%s\n' % name)
@@ -169,6 +174,8 @@
         fp.write('%s\n' % hex(pendingctx.node()))
         fp.write('%s\n' % ' '.join([hex(p) for p in repo.dirstate.parents()]))
         fp.write('%s\n' % ' '.join([hex(n) for n in stripnodes]))
+        fp.write('%s\n' % restorebranch)
+        fp.write('%s\n' % origshelvebranch)
         fp.close()
 
     @classmethod
@@ -556,6 +563,8 @@
             state.stripnodes.append(shelvectx.node())
 
         mergefiles(ui, repo, state.wctx, shelvectx)
+        if state.restorebranch:
+            repo.dirstate.setbranch(state.origshelvebranch)
 
         repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
         shelvedstate.clear(repo)
@@ -701,6 +710,8 @@
         ui.quiet = oldquiet
 
         shelvectx = repo['tip']
+        origshelvebranch = shelvectx.branch()
+        restorebranch = shelvectx.branch() != shelvectx.parents()[0].branch()
 
         # If the shelve is not immediately on top of the commit
         # we'll be merging with, rebase it to be on top.
@@ -718,7 +729,8 @@
 
                 stripnodes = [repo.changelog.node(rev)
                               for rev in xrange(oldtiprev, len(repo))]
-                shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes)
+                shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes,
+                                  restorebranch, origshelvebranch)
 
                 util.rename(repo.join('rebasestate'),
                             repo.join('unshelverebasestate'))
@@ -734,6 +746,8 @@
                 shelvectx = tmpwctx
 
         mergefiles(ui, repo, pctx, shelvectx)
+        if restorebranch:
+            repo.dirstate.setbranch(origshelvebranch)
 
         # Forget any files that were unknown before the shelve, unknown before
         # unshelve started, but are now added.
diff -r a036e1ae1fbe -r da5e9a27089d tests/test-shelve.t
--- a/tests/test-shelve.t	Sun Feb 07 00:49:31 2016 -0600
+++ b/tests/test-shelve.t	Wed Feb 10 02:23:27 2016 +0100
@@ -1314,3 +1314,107 @@
   $ hg commit -qm "Remove unknown"
 
   $ cd ..
+
+When i shelve commit on newly created branch i expect
+that after unshelve newly created branch will be preserved.
+
+  $ hg init shelve_on_new_branch_simple
+  $ cd shelve_on_new_branch_simple
+  $ echo "aaa" >> a
+  $ hg commit -A -m "a"
+  adding a
+  $ hg branch
+  default
+  $ hg branch test
+  marked working directory as branch test
+  (branches are permanent and global, did you want a bookmark?)
+  $ echo "bbb" >> a
+  $ hg status
+  M a
+  $ hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg branch
+  default
+  $ echo "bbb" >> b
+  $ hg status
+  ? b
+  $ hg unshelve
+  unshelving change 'default'
+  $ hg status
+  M a
+  ? b
+  $ hg branch
+  test
+
+When i shelve commit on newly created branch, make
+some changes, unshelve it and running into merge
+conflicts i expect that after fixing them and
+running unshelve --continue newly created branch
+will be preserved.
+
+  $ hg init shelve_on_new_branch_conflict
+  $ cd shelve_on_new_branch_conflict
+  $ echo "aaa" >> a
+  $ hg commit -A -m "a"
+  adding a
+  $ hg branch
+  default
+  $ hg branch test
+  marked working directory as branch test
+  (branches are permanent and global, did you want a bookmark?)
+  $ echo "bbb" >> a
+  $ hg status
+  M a
+  $ hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg branch
+  default
+  $ echo "ccc" >> a
+  $ hg status
+  M a
+  $ hg unshelve
+  unshelving change 'default'
+  temporarily committing pending changes (restore with 'hg unshelve --abort')
+  rebasing shelved changes
+  rebasing 2:425c97ef07f3 "changes to: a" (tip)
+  merging a
+  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  [1]
+  $ echo "aaabbbccc" > a
+  $ rm a.orig
+  $ hg resolve --mark a
+  (no more unresolved files)
+  continue: hg unshelve --continue
+  $ hg unshelve --continue
+  rebasing 2:425c97ef07f3 "changes to: a" (tip)
+  unshelve of 'default' complete
+  $ cat a
+  aaabbbccc
+  $ hg status
+  M a
+  $ hg branch
+  test
+  $ hg commit -m "test-commit"
+
+When i shelve on test branch, update to default branch
+and unshelve i expect that it will not preserve previous
+test branch.
+
+  $ echo "xxx" > b
+  $ hg add b
+  $ hg shelve
+  shelved as test
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg update -r default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg unshelve
+  unshelving change 'test'
+  rebasing shelved changes
+  rebasing 2:357525f34729 "changes to: test-commit" (tip)
+  $ hg status
+  A b
+  $ hg branch
+  default


More information about the Mercurial-devel mailing list