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

Pierre-Yves David pierre-yves.david at ens-lyon.org
Mon Feb 22 10:21:45 EST 2016



On 02/17/2016 02:17 PM, liscju wrote:
> # 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)

+1 on timeless feedback (adding (BC) and help update).

> 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.

I do not see the same meaning in the first part and in the second "In 
other words…". The first one scare me, second one is what I'm expecting. 
We should make that description clearer.

(now diving the patch to check which one is right).

> 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 @@

Please add the following to you hgrc to include a bit more context in 
your patch.

   [diff]
   showfunc=1

>               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()
>

You are Touching the shelve format. How did you ensure backward 
compatibility with (1) shelve created with older mercurial version (2) 
older version reading your new shelve format ?

I can see other way that a format update to store this data. But if you 
format change does not have compatibility issue, it seems like a legit path.

> @@ -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()

Could we check this before committing instead? Would that make it easier?

>
>           # 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
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>

-- 
Pierre-Yves David


More information about the Mercurial-devel mailing list