Patchwork shelve: don't delete "." when resolving all conflicts in its favour (issue4398)

login
register
mail settings
Submitter Jordi Gutiérrez Hermoso
Date Oct. 8, 2014, 12:23 p.m.
Message ID <825f51a02a12e5b15763.1412771012@Iris>
Download mbox | patch
Permalink /patch/6151/
State Accepted
Headers show

Comments

Jordi Gutiérrez Hermoso - Oct. 8, 2014, 12:23 p.m.
# HG changeset patch
# User Jordi Gutiérrez Hermoso <jordigh@octave.org>
# Date 1412768831 14400
#      Wed Oct 08 07:47:11 2014 -0400
# Node ID 825f51a02a12e5b15763e2082ed5da5d967086c4
# Parent  564ae7d2ec9bee86b00a6ba817271ac0b19deca7
shelve: don't delete "." when resolving all conflicts in its favour (issue4398)

When unshelving and facing a conflict, if we resolve all conflicts in
favour of the committed changes instead of the shelved changes, then
the ensuing implicit rebase is a no-op. That is, there is nothing to
rebase. In this case, there are no extra intermediate shelve commits
to strip either. Prior to this change, the commit being unshelved to
would be marked for destruction in a rather catastrophic way.

The relevant part of the test case failed as follows:

    $ hg unshelve -c
    unshelve of 'default' complete
    $ hg diff
    warning: ignoring unknown working parent 33f7f61e6c5e!
    diff --git a/a/a b/a/a
    new file mode 100644
    --- /dev/null
           b/a/a
    @@ -0,0   1,3 @@
      a
      c
      x
    $ hg status
    warning: ignoring unknown working parent 33f7f61e6c5e!
    M a/a
    ? a/a.orig
    ? foo/foo
    $ hg summary
    warning: ignoring unknown working parent 33f7f61e6c5e!
    parent: -1:000000000000  (no revision checked out)
    branch: default
    commit: 1 modified, 2 unknown (new branch head)
    update: 4 new changesets (update)

With this change, this test case now passes.
Augie Fackler - Oct. 8, 2014, 2:02 p.m.
On Wed, Oct 08, 2014 at 08:23:32AM -0400, Jordi Gutiérrez Hermoso wrote:
> # HG changeset patch
> # User Jordi Gutiérrez Hermoso <jordigh@octave.org>
> # Date 1412768831 14400
> #      Wed Oct 08 07:47:11 2014 -0400
> # Node ID 825f51a02a12e5b15763e2082ed5da5d967086c4
> # Parent  564ae7d2ec9bee86b00a6ba817271ac0b19deca7
> shelve: don't delete "." when resolving all conflicts in its favour (issue4398)

Looks good. Queued for stable since it's a bugfix.

>
> When unshelving and facing a conflict, if we resolve all conflicts in
> favour of the committed changes instead of the shelved changes, then
> the ensuing implicit rebase is a no-op. That is, there is nothing to
> rebase. In this case, there are no extra intermediate shelve commits
> to strip either. Prior to this change, the commit being unshelved to
> would be marked for destruction in a rather catastrophic way.
>
> The relevant part of the test case failed as follows:
>
>     $ hg unshelve -c
>     unshelve of 'default' complete
>     $ hg diff
>     warning: ignoring unknown working parent 33f7f61e6c5e!
>     diff --git a/a/a b/a/a
>     new file mode 100644
>     --- /dev/null
>            b/a/a
>     @@ -0,0   1,3 @@
>       a
>       c
>       x
>     $ hg status
>     warning: ignoring unknown working parent 33f7f61e6c5e!
>     M a/a
>     ? a/a.orig
>     ? foo/foo
>     $ hg summary
>     warning: ignoring unknown working parent 33f7f61e6c5e!
>     parent: -1:000000000000  (no revision checked out)
>     branch: default
>     commit: 1 modified, 2 unknown (new branch head)
>     update: 4 new changesets (update)
>
> With this change, this test case now passes.
>
> diff --git a/hgext/shelve.py b/hgext/shelve.py
> --- a/hgext/shelve.py
> +++ b/hgext/shelve.py
> @@ -449,10 +449,12 @@ def unshelvecontinue(ui, repo, state, op
>          if not shelvectx in state.pendingctx.children():
>              # rebase was a no-op, so it produced no child commit
>              shelvectx = state.pendingctx
> +        else:
> +            # only strip the shelvectx if the rebase produced it
> +            state.stripnodes.append(shelvectx.node())
>
>          mergefiles(ui, repo, state.wctx, shelvectx)
>
> -        state.stripnodes.append(shelvectx.node())
>          repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
>          shelvedstate.clear(repo)
>          unshelvecleanup(ui, repo, state.name, opts)
> diff --git a/tests/test-shelve.t b/tests/test-shelve.t
> --- a/tests/test-shelve.t
> +++ b/tests/test-shelve.t
> @@ -687,6 +687,49 @@ unshelve and conflicts with tracked and
>    g
>    $ hg shelve --delete default
>
> +Recreate some conflict again
> +
> +  $ cd ../repo
> +  $ hg up -C -r 3
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  (leaving bookmark test)
> +  $ echo y >> a/a
> +  $ hg shelve
> +  shelved as default
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ hg up test
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  (activating bookmark test)
> +  $ hg unshelve
> +  unshelving change 'default'
> +  rebasing shelved changes
> +  merging a/a
> +  warning: conflicts during merge.
> +  merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
> +  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
> +  [1]
> +
> +Test that resolving all conflicts in one direction (so that the rebase
> +is a no-op), works (issue4398)
> +
> +  $ hg revert -a -r .
> +  reverting a/a
> +  $ hg resolve -m a/a
> +  (no more unresolved files)
> +  $ hg unshelve -c
> +  unshelve of 'default' complete
> +  $ hg diff
> +  $ hg status
> +  ? a/a.orig
> +  ? foo/foo
> +  $ hg summary
> +  parent: 4:33f7f61e6c5e tip
> +   create conflict
> +  branch: default
> +  bookmarks: *test
> +  commit: 2 unknown (clean)
> +  update: (current)
> +
>    $ hg shelve --delete --stat
>    abort: options '--delete' and '--stat' may not be used together
>    [255]
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/hgext/shelve.py b/hgext/shelve.py
--- a/hgext/shelve.py
+++ b/hgext/shelve.py
@@ -449,10 +449,12 @@  def unshelvecontinue(ui, repo, state, op
         if not shelvectx in state.pendingctx.children():
             # rebase was a no-op, so it produced no child commit
             shelvectx = state.pendingctx
+        else:
+            # only strip the shelvectx if the rebase produced it
+            state.stripnodes.append(shelvectx.node())
 
         mergefiles(ui, repo, state.wctx, shelvectx)
 
-        state.stripnodes.append(shelvectx.node())
         repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
         shelvedstate.clear(repo)
         unshelvecleanup(ui, repo, state.name, opts)
diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -687,6 +687,49 @@  unshelve and conflicts with tracked and 
   g
   $ hg shelve --delete default
 
+Recreate some conflict again
+
+  $ cd ../repo
+  $ hg up -C -r 3
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (leaving bookmark test)
+  $ echo y >> a/a
+  $ hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg up test
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (activating bookmark test)
+  $ hg unshelve
+  unshelving change 'default'
+  rebasing shelved changes
+  merging a/a
+  warning: conflicts during merge.
+  merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
+  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  [1]
+
+Test that resolving all conflicts in one direction (so that the rebase
+is a no-op), works (issue4398)
+
+  $ hg revert -a -r .
+  reverting a/a
+  $ hg resolve -m a/a
+  (no more unresolved files)
+  $ hg unshelve -c
+  unshelve of 'default' complete
+  $ hg diff
+  $ hg status
+  ? a/a.orig
+  ? foo/foo
+  $ hg summary
+  parent: 4:33f7f61e6c5e tip
+   create conflict
+  branch: default
+  bookmarks: *test
+  commit: 2 unknown (clean)
+  update: (current)
+
   $ hg shelve --delete --stat
   abort: options '--delete' and '--stat' may not be used together
   [255]