Bug 4398 - unshelve --continue destroys most recently committed revision if all unshelve change were dropped
Summary: unshelve --continue destroys most recently committed revision if all unshelve...
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: shelve (show other bugs)
Version: 3.1.1
Hardware: All All
: critical bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-06 15:46 UTC by Braden McDaniel
Modified: 2015-01-22 15:04 UTC (History)
4 users (show)

See Also:
Python Version: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Braden McDaniel 2014-10-06 15:46 UTC
Under certain circumstances, unshelve destroys the most recently committed revision.  After the unshelve operation, the revision is nowhere to be found.  It appears to be completely lost.

I have so far encountered this bug twice: once when using hg on Windows, and once on Mac OS.

Here is what I know of the circumstances:

In both instances, unshelve encountered conflicts that required resolution.  Now, while I am not 100% certain on this point, I think that in both cases there were no net changes to the current revision after resolving the conflicts.  The destructive operation appears to have been "hg unshelve --continue" after resolving the conflicts.  After performing that operation, the most recent committed revision vanished and "hg st" yields a message like this:

  warning: ignoring unknown working parent 7a818d36acdb!
Comment 1 Pierre-Yves David 2014-10-07 16:39 UTC
Moving to critical since this involve data loss (Alarm sound).

Happen when all changes in the shelve are dropped and the unshelving spawn across multiple call. This most likely happen because the --continue conclude the rebase  who drop the empty node and then nuke '.' to oblivion.

Full repro script Below.


  $ echo '[extensions]' >> $HGRCPATH
  $ echo 'shelve=' >> $HGRCPATH


  $ hg init bar
  $ cd bar
  $ echo base > foo
  $ hg add foo
  $ hg ci -m base

shelve some change

  $ echo shelved > foo
  $ hg shelve
  shelved as default
  1 files updated, 0 files merged, 0 files removed, 0 files unresolved

commit conflict

  $ echo commited > foo
  $ hg ci -m new
  $ hg log
  changeset:   1:06e0307ef077
  tag:         tip
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  summary:     new
  
  changeset:   0:36e903da4378
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  summary:     base
  

unshelve have conflict

  $ hg unshelve
  unshelving change 'default'
  rebasing shelved changes
  merging foo
  warning: conflicts during merge.
  merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
  [1]
  $ echo commited > foo
  $ hg resolve -m foo
  (no more unresolved files)

unshelve continue (only appears if you use --continue (cross process operation)

  $ hg unshelve --continue
  unshelve of 'default' complete
  $ hg log
  changeset:   0:36e903da4378
  tag:         tip
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  summary:     base
  
  $ hg status
  warning: ignoring unknown working parent 06e0307ef077!
  M foo
  ? foo.orig
  $ cat foo
  commited
Comment 2 HG Bot 2014-10-10 13:30 UTC
Fixed by http://selenic.com/repo/hg/rev/d43d116a118c
Jordi Guti?rrez Hermoso <jordigh@octave.org>
shelve: don't delete "." when rebase is a no-op (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.

(please test the fix)
Comment 3 Matt Mackall 2015-01-22 15:04 UTC
Bulk testing -> fixed