mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 00:45:18 +03:00
59c67e69d3
When a user's repository is in an unfinished unshelve state and they choose to abort, at a minimum, the repo should be out of that state. We've found situations where the user could not leave the state unless manually deleting the state file. This fix ensures that no matter what exception may be raised during the abort, the shelved state file will be deleted, the user will be out of the unshelve state and they can get their repository into a workable condition.
1053 lines
25 KiB
Perl
1053 lines
25 KiB
Perl
$ cat <<EOF >> $HGRCPATH
|
|
> [extensions]
|
|
> mq =
|
|
> shelve =
|
|
> [defaults]
|
|
> diff = --nodates --git
|
|
> qnew = --date '0 0'
|
|
> [shelve]
|
|
> maxbackups = 2
|
|
> EOF
|
|
|
|
$ hg init repo
|
|
$ cd repo
|
|
$ mkdir a b
|
|
$ echo a > a/a
|
|
$ echo b > b/b
|
|
$ echo c > c
|
|
$ echo d > d
|
|
$ echo x > x
|
|
$ hg addremove -q
|
|
|
|
shelve has a help message
|
|
$ hg shelve -h
|
|
hg shelve [OPTION]... [FILE]...
|
|
|
|
save and set aside changes from the working directory
|
|
|
|
Shelving takes files that "hg status" reports as not clean, saves the
|
|
modifications to a bundle (a shelved change), and reverts the files so
|
|
that their state in the working directory becomes clean.
|
|
|
|
To restore these changes to the working directory, using "hg unshelve";
|
|
this will work even if you switch to a different commit.
|
|
|
|
When no files are specified, "hg shelve" saves all not-clean files. If
|
|
specific files or directories are named, only changes to those files are
|
|
shelved.
|
|
|
|
Each shelved change has a name that makes it easier to find later. The
|
|
name of a shelved change defaults to being based on the active bookmark,
|
|
or if there is no active bookmark, the current named branch. To specify a
|
|
different name, use "--name".
|
|
|
|
To see a list of existing shelved changes, use the "--list" option. For
|
|
each shelved change, this will print its name, age, and description; use "
|
|
--patch" or "--stat" for more details.
|
|
|
|
To delete specific shelved changes, use "--delete". To delete all shelved
|
|
changes, use "--cleanup".
|
|
|
|
(use "hg help -e shelve" to show help for the shelve extension)
|
|
|
|
options ([+] can be repeated):
|
|
|
|
-A --addremove mark new/missing files as added/removed before
|
|
shelving
|
|
--cleanup delete all shelved changes
|
|
--date DATE shelve with the specified commit date
|
|
-d --delete delete the named shelved change(s)
|
|
-e --edit invoke editor on commit messages
|
|
-l --list list current shelves
|
|
-m --message TEXT use text as shelve message
|
|
-n --name NAME use the given name for the shelved commit
|
|
-p --patch show patch
|
|
-i --interactive interactive mode, only works while creating a shelve
|
|
--stat output diffstat-style summary of changes
|
|
-I --include PATTERN [+] include names matching the given patterns
|
|
-X --exclude PATTERN [+] exclude names matching the given patterns
|
|
--mq operate on patch repository
|
|
|
|
(some details hidden, use --verbose to show complete help)
|
|
|
|
shelving in an empty repo should be possible
|
|
(this tests also that editor is not invoked, if '--edit' is not
|
|
specified)
|
|
|
|
$ HGEDITOR=cat hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 5 files removed, 0 files unresolved
|
|
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
|
|
$ hg commit -q -m 'initial commit'
|
|
|
|
$ hg shelve
|
|
nothing changed
|
|
[1]
|
|
|
|
make sure shelve files were backed up
|
|
|
|
$ ls .hg/shelve-backup
|
|
default.hg
|
|
default.patch
|
|
|
|
create an mq patch - shelving should work fine with a patch applied
|
|
|
|
$ echo n > n
|
|
$ hg add n
|
|
$ hg commit n -m second
|
|
$ hg qnew second.patch
|
|
|
|
shelve a change that we will delete later
|
|
|
|
$ echo a >> a/a
|
|
$ hg shelve
|
|
shelved as default
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
set up some more complex changes to shelve
|
|
|
|
$ echo a >> a/a
|
|
$ hg mv b b.rename
|
|
moving b/b to b.rename/b (glob)
|
|
$ hg cp c c.copy
|
|
$ hg status -C
|
|
M a/a
|
|
A b.rename/b
|
|
b/b
|
|
A c.copy
|
|
c
|
|
R b/b
|
|
|
|
prevent some foot-shooting
|
|
|
|
$ hg shelve -n foo/bar
|
|
abort: shelved change names may not contain slashes
|
|
[255]
|
|
$ hg shelve -n .baz
|
|
abort: shelved change names may not start with '.'
|
|
[255]
|
|
|
|
the common case - no options or filenames
|
|
|
|
$ hg shelve
|
|
shelved as default-01
|
|
2 files updated, 0 files merged, 2 files removed, 0 files unresolved
|
|
$ hg status -C
|
|
|
|
ensure that our shelved changes exist
|
|
|
|
$ hg shelve -l
|
|
default-01 (*)* changes to '[mq]: second.patch' (glob)
|
|
default (*)* changes to '[mq]: second.patch' (glob)
|
|
|
|
$ hg shelve -l -p default
|
|
default (*)* changes to '[mq]: second.patch' (glob)
|
|
|
|
diff --git a/a/a b/a/a
|
|
--- a/a/a
|
|
+++ b/a/a
|
|
@@ -1,1 +1,2 @@
|
|
a
|
|
+a
|
|
|
|
$ hg shelve --list --addremove
|
|
abort: options '--list' and '--addremove' may not be used together
|
|
[255]
|
|
|
|
delete our older shelved change
|
|
|
|
$ hg shelve -d default
|
|
$ hg qfinish -a -q
|
|
|
|
ensure shelve backups aren't overwritten
|
|
|
|
$ ls .hg/shelve-backup/
|
|
default-1.hg
|
|
default-1.patch
|
|
default.hg
|
|
default.patch
|
|
|
|
local edits should not prevent a shelved change from applying
|
|
|
|
$ printf "z\na\n" > a/a
|
|
$ hg unshelve --keep
|
|
unshelving change 'default-01'
|
|
temporarily committing pending changes (restore with 'hg unshelve --abort')
|
|
rebasing shelved changes
|
|
rebasing 4:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
|
|
merging a/a
|
|
|
|
$ hg revert --all -q
|
|
$ rm a/a.orig b.rename/b c.copy
|
|
|
|
apply it and make sure our state is as expected
|
|
|
|
(this also tests that same timestamp prevents backups from being
|
|
removed, even though there are more than 'maxbackups' backups)
|
|
|
|
$ f -t .hg/shelve-backup/default.hg
|
|
.hg/shelve-backup/default.hg: file
|
|
$ touch -t 200001010000 .hg/shelve-backup/default.hg
|
|
$ f -t .hg/shelve-backup/default-1.hg
|
|
.hg/shelve-backup/default-1.hg: file
|
|
$ touch -t 200001010000 .hg/shelve-backup/default-1.hg
|
|
|
|
$ hg unshelve
|
|
unshelving change 'default-01'
|
|
$ hg status -C
|
|
M a/a
|
|
A b.rename/b
|
|
b/b
|
|
A c.copy
|
|
c
|
|
R b/b
|
|
$ hg shelve -l
|
|
|
|
(both of default.hg and default-1.hg should be still kept, because it
|
|
is difficult to decide actual order of them from same timestamp)
|
|
|
|
$ ls .hg/shelve-backup/
|
|
default-01.hg
|
|
default-01.patch
|
|
default-1.hg
|
|
default-1.patch
|
|
default.hg
|
|
default.patch
|
|
|
|
$ hg unshelve
|
|
abort: no shelved changes to apply!
|
|
[255]
|
|
$ hg unshelve foo
|
|
abort: shelved change 'foo' not found
|
|
[255]
|
|
|
|
named shelves, specific filenames, and "commit messages" should all work
|
|
(this tests also that editor is invoked, if '--edit' is specified)
|
|
|
|
$ hg status -C
|
|
M a/a
|
|
A b.rename/b
|
|
b/b
|
|
A c.copy
|
|
c
|
|
R b/b
|
|
$ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
|
|
wat
|
|
|
|
|
|
HG: Enter commit message. Lines beginning with 'HG:' are removed.
|
|
HG: Leave message empty to abort commit.
|
|
HG: --
|
|
HG: user: shelve@localhost
|
|
HG: branch 'default'
|
|
HG: changed a/a
|
|
|
|
expect "a" to no longer be present, but status otherwise unchanged
|
|
|
|
$ hg status -C
|
|
A b.rename/b
|
|
b/b
|
|
A c.copy
|
|
c
|
|
R b/b
|
|
$ hg shelve -l --stat
|
|
wibble (*) wat (glob)
|
|
a/a | 1 +
|
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
|
|
and now "a/a" should reappear
|
|
|
|
$ cd a
|
|
$ hg unshelve -q wibble
|
|
$ cd ..
|
|
$ hg status -C
|
|
M a/a
|
|
A b.rename/b
|
|
b/b
|
|
A c.copy
|
|
c
|
|
R b/b
|
|
|
|
ensure old shelve backups are being deleted automatically
|
|
|
|
$ ls .hg/shelve-backup/
|
|
default-01.hg
|
|
default-01.patch
|
|
wibble.hg
|
|
wibble.patch
|
|
|
|
cause unshelving to result in a merge with 'a' conflicting
|
|
|
|
$ hg shelve -q
|
|
$ echo c>>a/a
|
|
$ hg commit -m second
|
|
$ hg tip --template '{files}\n'
|
|
a/a
|
|
|
|
add an unrelated change that should be preserved
|
|
|
|
$ mkdir foo
|
|
$ echo foo > foo/foo
|
|
$ hg add foo/foo
|
|
|
|
force a conflicted merge to occur
|
|
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
temporarily committing pending changes (restore with 'hg unshelve --abort')
|
|
rebasing shelved changes
|
|
rebasing 5:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
|
|
merging a/a
|
|
warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
|
|
[1]
|
|
|
|
ensure that we have a merge with unresolved conflicts
|
|
|
|
$ hg heads -q --template '{rev}\n'
|
|
5
|
|
4
|
|
$ hg parents -q --template '{rev}\n'
|
|
4
|
|
5
|
|
$ hg status
|
|
M a/a
|
|
M b.rename/b
|
|
M c.copy
|
|
R b/b
|
|
? a/a.orig
|
|
$ hg diff
|
|
diff --git a/a/a b/a/a
|
|
--- a/a/a
|
|
+++ b/a/a
|
|
@@ -1,2 +1,6 @@
|
|
a
|
|
+<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
|
|
c
|
|
+=======
|
|
+a
|
|
+>>>>>>> source: 4702e8911fe0 - shelve: changes to '[mq]: second.patch'
|
|
diff --git a/b/b b/b.rename/b
|
|
rename from b/b
|
|
rename to b.rename/b
|
|
diff --git a/c b/c.copy
|
|
copy from c
|
|
copy to c.copy
|
|
$ hg resolve -l
|
|
U a/a
|
|
|
|
$ hg shelve
|
|
abort: unshelve already in progress
|
|
(use 'hg unshelve --continue' or 'hg unshelve --abort')
|
|
[255]
|
|
|
|
abort the unshelve and be happy
|
|
|
|
$ hg status
|
|
M a/a
|
|
M b.rename/b
|
|
M c.copy
|
|
R b/b
|
|
? a/a.orig
|
|
$ hg unshelve -a
|
|
rebase aborted
|
|
unshelve of 'default' aborted
|
|
$ hg heads -q
|
|
3:2e69b451d1ea
|
|
$ hg parents
|
|
changeset: 3:2e69b451d1ea
|
|
tag: tip
|
|
user: test
|
|
date: Thu Jan 01 00:00:00 1970 +0000
|
|
summary: second
|
|
|
|
$ hg resolve -l
|
|
$ hg status
|
|
A foo/foo
|
|
? a/a.orig
|
|
|
|
try to continue with no unshelve underway
|
|
|
|
$ hg unshelve -c
|
|
abort: no unshelve operation underway
|
|
[255]
|
|
$ hg status
|
|
A foo/foo
|
|
? a/a.orig
|
|
|
|
redo the unshelve to get a conflict
|
|
|
|
$ hg unshelve -q
|
|
warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
|
|
[1]
|
|
|
|
attempt to continue
|
|
|
|
$ hg unshelve -c
|
|
abort: unresolved conflicts, can't continue
|
|
(see 'hg resolve', then 'hg unshelve --continue')
|
|
[255]
|
|
|
|
$ hg revert -r . a/a
|
|
$ hg resolve -m a/a
|
|
(no more unresolved files)
|
|
|
|
$ hg commit -m 'commit while unshelve in progress'
|
|
abort: unshelve already in progress
|
|
(use 'hg unshelve --continue' or 'hg unshelve --abort')
|
|
[255]
|
|
|
|
$ hg unshelve -c
|
|
rebasing 5:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
|
|
unshelve of 'default' complete
|
|
|
|
ensure the repo is as we hope
|
|
|
|
$ hg parents
|
|
changeset: 3:2e69b451d1ea
|
|
tag: tip
|
|
user: test
|
|
date: Thu Jan 01 00:00:00 1970 +0000
|
|
summary: second
|
|
|
|
$ hg heads -q
|
|
3:2e69b451d1ea
|
|
|
|
$ hg status -C
|
|
A b.rename/b
|
|
b/b
|
|
A c.copy
|
|
c
|
|
A foo/foo
|
|
R b/b
|
|
? a/a.orig
|
|
|
|
there should be no shelves left
|
|
|
|
$ hg shelve -l
|
|
|
|
#if execbit
|
|
|
|
ensure that metadata-only changes are shelved
|
|
|
|
$ chmod +x a/a
|
|
$ hg shelve -q -n execbit a/a
|
|
$ hg status a/a
|
|
$ hg unshelve -q execbit
|
|
$ hg status a/a
|
|
M a/a
|
|
$ hg revert a/a
|
|
|
|
#endif
|
|
|
|
#if symlink
|
|
|
|
$ rm a/a
|
|
$ ln -s foo a/a
|
|
$ hg shelve -q -n symlink a/a
|
|
$ hg status a/a
|
|
$ hg unshelve -q symlink
|
|
$ hg status a/a
|
|
M a/a
|
|
$ hg revert a/a
|
|
|
|
#endif
|
|
|
|
set up another conflict between a commit and a shelved change
|
|
|
|
$ hg revert -q -C -a
|
|
$ rm a/a.orig b.rename/b c.copy
|
|
$ echo a >> a/a
|
|
$ hg shelve -q
|
|
$ echo x >> a/a
|
|
$ hg ci -m 'create conflict'
|
|
$ hg add foo/foo
|
|
|
|
if we resolve a conflict while unshelving, the unshelve should succeed
|
|
|
|
$ HGMERGE=true hg unshelve
|
|
unshelving change 'default'
|
|
temporarily committing pending changes (restore with 'hg unshelve --abort')
|
|
rebasing shelved changes
|
|
rebasing 6:c5e6910e7601 "changes to 'second'" (tip)
|
|
merging a/a
|
|
note: rebase of 6:c5e6910e7601 created no changes to commit
|
|
$ hg parents -q
|
|
4:33f7f61e6c5e
|
|
$ hg shelve -l
|
|
$ hg status
|
|
A foo/foo
|
|
$ cat a/a
|
|
a
|
|
c
|
|
x
|
|
|
|
test keep and cleanup
|
|
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg shelve --list
|
|
default (*) changes to 'create conflict' (glob)
|
|
$ hg unshelve --keep
|
|
unshelving change 'default'
|
|
$ hg shelve --list
|
|
default (*) changes to 'create conflict' (glob)
|
|
$ hg shelve --cleanup
|
|
$ hg shelve --list
|
|
|
|
$ hg shelve --cleanup --delete
|
|
abort: options '--cleanup' and '--delete' may not be used together
|
|
[255]
|
|
$ hg shelve --cleanup --patch
|
|
abort: options '--cleanup' and '--patch' may not be used together
|
|
[255]
|
|
$ hg shelve --cleanup --message MESSAGE
|
|
abort: options '--cleanup' and '--message' may not be used together
|
|
[255]
|
|
|
|
test bookmarks
|
|
|
|
$ hg bookmark test
|
|
$ hg bookmark
|
|
* test 4:33f7f61e6c5e
|
|
$ hg shelve
|
|
shelved as test
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg bookmark
|
|
* test 4:33f7f61e6c5e
|
|
$ hg unshelve
|
|
unshelving change 'test'
|
|
$ hg bookmark
|
|
* test 4:33f7f61e6c5e
|
|
|
|
shelve should still work even if mq is disabled
|
|
|
|
$ hg --config extensions.mq=! shelve
|
|
shelved as test
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg --config extensions.mq=! shelve --list
|
|
test (*) changes to 'create conflict' (glob)
|
|
$ hg bookmark
|
|
* test 4:33f7f61e6c5e
|
|
$ hg --config extensions.mq=! unshelve
|
|
unshelving change 'test'
|
|
$ hg bookmark
|
|
* test 4:33f7f61e6c5e
|
|
|
|
shelve should leave dirstate clean (issue4055)
|
|
|
|
$ cd ..
|
|
$ hg init shelverebase
|
|
$ cd shelverebase
|
|
$ printf 'x\ny\n' > x
|
|
$ echo z > z
|
|
$ hg commit -Aqm xy
|
|
$ echo z >> x
|
|
$ hg commit -Aqm z
|
|
$ hg up 0
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ printf 'a\nx\ny\nz\n' > x
|
|
$ hg commit -Aqm xyz
|
|
$ echo c >> z
|
|
$ hg shelve
|
|
shelved as default
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ hg rebase -d 1 --config extensions.rebase=
|
|
rebasing 2:323bfa07f744 "xyz" (tip)
|
|
merging x
|
|
saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-backup.hg (glob)
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
rebasing shelved changes
|
|
rebasing 4:b8fefe789ed0 "changes to 'xyz'" (tip)
|
|
$ hg status
|
|
M z
|
|
|
|
$ cd ..
|
|
|
|
shelve should only unshelve pending changes (issue4068)
|
|
|
|
$ hg init onlypendingchanges
|
|
$ cd onlypendingchanges
|
|
$ touch a
|
|
$ hg ci -Aqm a
|
|
$ touch b
|
|
$ hg ci -Aqm b
|
|
$ hg up -q 0
|
|
$ touch c
|
|
$ hg ci -Aqm c
|
|
|
|
$ touch d
|
|
$ hg add d
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg up -q 1
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
rebasing shelved changes
|
|
rebasing 3:0cae6656c016 "changes to 'c'" (tip)
|
|
$ hg status
|
|
A d
|
|
|
|
unshelve should work on an ancestor of the original commit
|
|
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg up 0
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
rebasing shelved changes
|
|
rebasing 3:be58f65f55fb "changes to 'b'" (tip)
|
|
$ hg status
|
|
A d
|
|
|
|
test bug 4073 we need to enable obsolete markers for it
|
|
|
|
$ cat >> $HGRCPATH << EOF
|
|
> [experimental]
|
|
> evolution=createmarkers
|
|
> EOF
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg debugobsolete `hg --debug id -i -r 1`
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
|
|
unshelve should leave unknown files alone (issue4113)
|
|
|
|
$ echo e > e
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg status
|
|
? e
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
$ hg status
|
|
A d
|
|
? e
|
|
$ cat e
|
|
e
|
|
|
|
unshelve should keep a copy of unknown files
|
|
|
|
$ hg add e
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
|
|
$ echo z > e
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
$ cat e
|
|
e
|
|
$ cat e.orig
|
|
z
|
|
|
|
|
|
unshelve and conflicts with tracked and untracked files
|
|
|
|
preparing:
|
|
|
|
$ rm *.orig
|
|
$ hg ci -qm 'commit stuff'
|
|
$ hg phase -p null:
|
|
|
|
no other changes - no merge:
|
|
|
|
$ echo f > f
|
|
$ hg add f
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ echo g > f
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
$ hg st
|
|
A f
|
|
? f.orig
|
|
$ cat f
|
|
f
|
|
$ cat f.orig
|
|
g
|
|
|
|
other uncommitted changes - merge:
|
|
|
|
$ hg st
|
|
A f
|
|
? f.orig
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
|
|
o 4 changes to 'commit stuff' shelve@localhost
|
|
|
|
|
$ hg log -G --template '{rev} {desc|firstline} {author}'
|
|
@ 3 commit stuff test
|
|
|
|
|
| o 2 c test
|
|
|/
|
|
o 0 a test
|
|
|
|
$ mv f.orig f
|
|
$ echo 1 > a
|
|
$ hg unshelve --date '1073741824 0'
|
|
unshelving change 'default'
|
|
temporarily committing pending changes (restore with 'hg unshelve --abort')
|
|
rebasing shelved changes
|
|
rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
|
|
merging f
|
|
warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
|
|
[1]
|
|
$ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
|
|
@ 5 changes to 'commit stuff' shelve@localhost 1970-01-01 00:00 +0000
|
|
|
|
|
| @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
|
|
|/
|
|
o 3 commit stuff test 1970-01-01 00:00 +0000
|
|
|
|
|
| o 2 c test 1970-01-01 00:00 +0000
|
|
|/
|
|
o 0 a test 1970-01-01 00:00 +0000
|
|
|
|
$ hg st
|
|
M f
|
|
? f.orig
|
|
$ cat f
|
|
<<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
|
|
g
|
|
=======
|
|
f
|
|
>>>>>>> source: 23b29cada8ba - shelve: changes to 'commit stuff'
|
|
$ cat f.orig
|
|
g
|
|
$ hg unshelve --abort
|
|
rebase aborted
|
|
unshelve of 'default' aborted
|
|
$ hg st
|
|
M a
|
|
? f.orig
|
|
$ cat f.orig
|
|
g
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
temporarily committing pending changes (restore with 'hg unshelve --abort')
|
|
rebasing shelved changes
|
|
rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
|
|
$ hg st
|
|
M a
|
|
A f
|
|
? f.orig
|
|
|
|
other committed changes - merge:
|
|
|
|
$ hg shelve f
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg ci a -m 'intermediate other change'
|
|
$ mv f.orig f
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
rebasing shelved changes
|
|
rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
|
|
merging f
|
|
warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
|
|
[1]
|
|
$ hg st
|
|
M f
|
|
? f.orig
|
|
$ cat f
|
|
<<<<<<< dest: * - test: intermediate other change (glob)
|
|
g
|
|
=======
|
|
f
|
|
>>>>>>> source: 23b29cada8ba - shelve: changes to 'commit stuff'
|
|
$ cat f.orig
|
|
g
|
|
$ hg unshelve --abort
|
|
rebase aborted
|
|
unshelve of 'default' aborted
|
|
$ hg st
|
|
? f.orig
|
|
$ cat f.orig
|
|
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 bookmark
|
|
* test 4:33f7f61e6c5e
|
|
$ hg unshelve
|
|
unshelving change 'default'
|
|
rebasing shelved changes
|
|
rebasing 5:4b555fdb4e96 "changes to 'second'" (tip)
|
|
merging a/a
|
|
warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
|
|
[1]
|
|
$ hg bookmark
|
|
test 4:33f7f61e6c5e
|
|
|
|
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 (glob)
|
|
$ hg resolve -m a/a
|
|
(no more unresolved files)
|
|
$ hg unshelve -c
|
|
rebasing 5:4b555fdb4e96 "changes to 'second'" (tip)
|
|
note: rebase of 5:4b555fdb4e96 created no changes to commit
|
|
unshelve of 'default' complete
|
|
$ hg bookmark
|
|
* test 4:33f7f61e6c5e
|
|
$ 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)
|
|
phases: 5 draft
|
|
|
|
$ hg shelve --delete --stat
|
|
abort: options '--delete' and '--stat' may not be used together
|
|
[255]
|
|
$ hg shelve --delete --name NAME
|
|
abort: options '--delete' and '--name' may not be used together
|
|
[255]
|
|
|
|
Test interactive shelve
|
|
$ cat <<EOF >> $HGRCPATH
|
|
> [ui]
|
|
> interactive = true
|
|
> EOF
|
|
$ echo 'a' >> a/b
|
|
$ cat a/a >> a/b
|
|
$ echo 'x' >> a/b
|
|
$ mv a/b a/a
|
|
$ echo 'a' >> foo/foo
|
|
$ hg st
|
|
M a/a
|
|
? a/a.orig
|
|
? foo/foo
|
|
$ cat a/a
|
|
a
|
|
a
|
|
c
|
|
x
|
|
x
|
|
$ cat foo/foo
|
|
foo
|
|
a
|
|
$ hg shelve --interactive --config ui.interactive=false
|
|
abort: running non-interactively
|
|
[255]
|
|
$ hg shelve --interactive << EOF
|
|
> y
|
|
> y
|
|
> n
|
|
> EOF
|
|
diff --git a/a/a b/a/a
|
|
2 hunks, 2 lines changed
|
|
examine changes to 'a/a'? [Ynesfdaq?] y
|
|
|
|
@@ -1,3 +1,4 @@
|
|
+a
|
|
a
|
|
c
|
|
x
|
|
record change 1/2 to 'a/a'? [Ynesfdaq?] y
|
|
|
|
@@ -1,3 +2,4 @@
|
|
a
|
|
c
|
|
x
|
|
+x
|
|
record change 2/2 to 'a/a'? [Ynesfdaq?] n
|
|
|
|
shelved as test
|
|
merging a/a
|
|
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
|
|
$ cat a/a
|
|
a
|
|
c
|
|
x
|
|
x
|
|
$ cat foo/foo
|
|
foo
|
|
a
|
|
$ hg st
|
|
M a/a
|
|
? foo/foo
|
|
$ hg bookmark
|
|
* test 4:33f7f61e6c5e
|
|
$ hg unshelve
|
|
unshelving change 'test'
|
|
temporarily committing pending changes (restore with 'hg unshelve --abort')
|
|
rebasing shelved changes
|
|
rebasing 6:65b5d1c34c34 "changes to 'create conflict'" (tip)
|
|
merging a/a
|
|
$ hg bookmark
|
|
* test 4:33f7f61e6c5e
|
|
$ cat a/a
|
|
a
|
|
a
|
|
c
|
|
x
|
|
x
|
|
|
|
shelve --patch and shelve --stat should work with a single valid shelfname
|
|
|
|
$ hg up --clean .
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
(leaving bookmark test)
|
|
$ hg shelve --list
|
|
$ echo 'patch a' > shelf-patch-a
|
|
$ hg add shelf-patch-a
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ echo 'patch b' > shelf-patch-b
|
|
$ hg add shelf-patch-b
|
|
$ hg shelve
|
|
shelved as default-01
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg shelve --patch default default-01
|
|
abort: --patch expects a single shelf
|
|
[255]
|
|
$ hg shelve --stat default default-01
|
|
abort: --stat expects a single shelf
|
|
[255]
|
|
$ hg shelve --patch default
|
|
default (* ago) changes to 'create conflict' (glob)
|
|
|
|
diff --git a/shelf-patch-a b/shelf-patch-a
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/shelf-patch-a
|
|
@@ -0,0 +1,1 @@
|
|
+patch a
|
|
$ hg shelve --stat default
|
|
default (* ago) changes to 'create conflict' (glob)
|
|
shelf-patch-a | 1 +
|
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
$ hg shelve --patch nonexistentshelf
|
|
abort: cannot find shelf nonexistentshelf
|
|
[255]
|
|
$ hg shelve --stat nonexistentshelf
|
|
abort: cannot find shelf nonexistentshelf
|
|
[255]
|
|
|
|
$ cd ..
|
|
|
|
Shelve from general delta repo uses bundle2 on disk
|
|
--------------------------------------------------
|
|
|
|
no general delta
|
|
|
|
$ hg clone --pull repo bundle1 --config format.generaldelta=0
|
|
requesting all changes
|
|
adding changesets
|
|
adding manifests
|
|
adding file changes
|
|
added 5 changesets with 8 changes to 6 files
|
|
updating to branch default
|
|
6 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ cd bundle1
|
|
$ echo babar > jungle
|
|
$ hg add jungle
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg debugbundle .hg/shelved/*.hg
|
|
7e30d8ac6f23cfc84330fd7e698730374615d21a
|
|
$ cd ..
|
|
|
|
with general delta
|
|
|
|
$ hg clone --pull repo bundle2 --config format.generaldelta=1
|
|
requesting all changes
|
|
adding changesets
|
|
adding manifests
|
|
adding file changes
|
|
added 5 changesets with 8 changes to 6 files
|
|
updating to branch default
|
|
6 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ cd bundle2
|
|
$ echo babar > jungle
|
|
$ hg add jungle
|
|
$ hg shelve
|
|
shelved as default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg debugbundle .hg/shelved/*.hg
|
|
Stream params: {'Compression': 'BZ'}
|
|
changegroup -- "{'version': '02'}"
|
|
7e30d8ac6f23cfc84330fd7e698730374615d21a
|
|
$ cd ..
|
|
|
|
test Abort unshelve always gets user out of the unshelved state
|
|
---------------------------------------------------------------
|
|
$ hg init salvage
|
|
$ cd salvage
|
|
$ echo 'content' > root
|
|
$ hg commit -A -m 'root' -q
|
|
$ echo '' > root
|
|
$ hg shelve -q
|
|
$ echo 'contADDent' > root
|
|
$ hg unshelve -q
|
|
warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
|
|
[1]
|
|
Wreak havoc on the unshelve process
|
|
$ rm .hg/unshelverebasestate
|
|
$ hg unshelve --abort
|
|
unshelve of 'default' aborted
|
|
abort: No such file or directory
|
|
[255]
|
|
Can the user leave the current state?
|
|
$ hg up -C .
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
Try again but with a corrupted shelve state file
|
|
$ hg strip -r 2 -r 1 -q
|
|
$ hg up -r 0 -q
|
|
$ echo '' > root
|
|
$ hg shelve -q
|
|
$ echo 'contADDent' > root
|
|
$ hg unshelve -q
|
|
warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
|
|
[1]
|
|
$ sed 's/ae8c668541e8/123456789012/' .hg/shelvedstate > ../corrupt-shelvedstate
|
|
$ mv ../corrupt-shelvedstate .hg/histedit-state
|
|
$ hg unshelve --abort |& grep 'rebase aborted'
|
|
rebase aborted
|
|
$ hg up -C .
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|