Mercurial > hg
view tests/test-shelve.t @ 26623:5a95fe44121d
clonebundles: support for seeding clones from pre-generated bundles
Cloning can be an expensive operation for servers because the server
generates a bundle from existing repository data at request time. For
a large repository like mozilla-central, this consumes 4+ minutes
of CPU time on the server. It also results in significant network
utilization. Multiplied by hundreds or even thousands of clients and
the ensuing load can result in difficulties scaling the Mercurial server.
Despite generation of bundles being deterministic until the next
changeset is added, the generation of bundles to service a clone request
is not cached. Each clone thus performs redundant work. This is
wasteful.
This patch introduces the "clonebundles" extension and related
client-side functionality to help alleviate this deficiency. The
client-side feature is behind an experimental flag and is not enabled by
default.
It works as follows:
1) Server operator generates a bundle and makes it available on a
server (likely HTTP).
2) Server operator defines the URL of a bundle file in a
.hg/clonebundles.manifest file.
3) Client `hg clone`ing sees the server is advertising bundle URLs.
4) Client fetches and applies the advertised bundle.
5) Client performs equivalent of `hg pull` to fetch changes made since
the bundle was created.
Essentially, the server performs the expensive work of generating a
bundle once and all subsequent clones fetch a static file from
somewhere. Scaling static file serving is a much more manageable
problem than scaling a Python application like Mercurial. Assuming your
repository grows less than 1% per day, the end result is 99+% of CPU
and network load from clones is eliminated, allowing Mercurial servers
to scale more easily. Serving static files also means data can be
transferred to clients as fast as they can consume it, rather than as
fast as servers can generate it. This makes clones faster.
Mozilla has implemented similar functionality of this patch on
hg.mozilla.org using a custom extension. We are hosting bundle files in
Amazon S3 and CloudFront (a CDN) and have successfully offloaded
>1 TB/day in data transfer from hg.mozilla.org, freeing up significant
bandwidth and CPU resources. The positive impact has been stellar and
I believe it has proved its value to be included in Mercurial core. I
feel it is important for the client-side support to be enabled in core
by default because it means that clients will get faster, more reliable
clones and will enable server operators to reduce load without
requiring any client-side configuration changes (assuming clients are
up to date, of course).
The scope of this feature is narrowly and specifically tailored to
cloning, despite "serve pulls from pre-generated bundles" being a valid
and useful feature. I would eventually like for Mercurial servers to
support transferring *all* repository data via statically hosted files.
You could imagine a server that siphons all pushed data to bundle files
and instructs clients to apply a stream of bundles to reconstruct all
repository data. This feature, while useful and powerful, is
significantly more work to implement because it requires the server
component have awareness of discovery and a mapping of which changesets
are in which files. Full, clone bundles, by contrast, are much simpler.
The wire protocol command is named "clonebundles" instead of something
more generic like "staticbundles" to leave the door open for a new, more
powerful and more generic server-side component with minimal backwards
compatibility implications. The name "bundleclone" is used by Mozilla's
extension and would cause problems since there are subtle differences
in Mozilla's extension.
Mozilla's experience with this idea has taught us that some form of
"content negotiation" is required. Not all clients will support all
bundle formats or even URLs (advanced TLS requirements, etc). To ensure
the highest uptake possible, a server needs to advertise multiple
versions of bundles and clients need to be able to choose the most
appropriate from that list one. The "attributes" in each
server-advertised entry facilitate this filtering and sorting. Their
use will become apparent in subsequent patches.
Initial inspiration and credit for the idea of cloning from static files
belongs to Augie Fackler and his "lookaside clone" extension proof of
concept.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 09 Oct 2015 11:22:01 -0700 |
parents | ef1eb6df7071 |
children | ca8170b5d370 |
line wrap: on
line source
$ 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 ..