# HG changeset patch # User Gregory Szorc # Date 2015-10-17 18:40:29 # Node ID 43708f92f47110b8090106ba429cf438a1083f37 # Parent 9e272a96f7648416b4b875dc482e4c32a79818fa commands: support creating stream clone bundles Now that we have support for recognizing the streaming clone bundle type, add a debug command for creating them. I decided to create a new debug command instead of adding support to `hg bundle` because stream clone bundles are not exactly used the same way as normal bundle files and I don't want to commit to supporting them through the official `hg bundle` command forever. A debug command, however, can be changed without as much concern for backwards compatibility. As part of this, `hg bundle` will explicitly reject requests to produce stream bundles. This command will be required by server operators using stream clone bundles with the clone bundles feature. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -23,6 +23,7 @@ import random, operator import setdiscovery, treediscovery, dagutil, pvec, localrepo, destutil import phases, obsolete, exchange, bundle2, repair, lock as lockmod import ui as uimod +import streamclone table = {} @@ -1250,6 +1251,11 @@ def bundle(ui, repo, fname, dest=None, * hint=_('see "hg help bundle" for supported ' 'values for --type')) + # Packed bundles are a pseudo bundle format for now. + if cgversion == 's1': + raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'), + hint=_('use "hg debugcreatestreamclonebundle"')) + if opts.get('all'): base = ['null'] else: @@ -1960,6 +1966,18 @@ def _debugbundle2(ui, gen, **opts): ui.write(" %s\n" % hex(node)) chain = node +@command('debugcreatestreamclonebundle', [], 'FILE') +def debugcreatestreamclonebundle(ui, repo, fname): + """create a stream clone bundle file + + Stream bundles are special bundles that are essentially archives of + revlog files. They are commonly used for cloning very quickly. + """ + requirements, gen = streamclone.generatebundlev1(repo) + changegroup.writechunks(ui, gen, fname) + + ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements))) + @command('debugcheckstate', [], '') def debugcheckstate(ui, repo): """validate the correctness of the current dirstate""" diff --git a/tests/test-bundle.t b/tests/test-bundle.t --- a/tests/test-bundle.t +++ b/tests/test-bundle.t @@ -250,6 +250,44 @@ Pull full.hg into empty again (using -R; changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:empty+full.hg (glob) (run 'hg heads' to see heads, 'hg merge' to merge) +Cannot produce streaming clone bundles with "hg bundle" + + $ hg -R test bundle -t packed1 packed.hg + abort: packed bundles cannot be produced by "hg bundle" + (use "hg debugcreatestreamclonebundle") + [255] + +packed1 is produced properly + + $ hg -R test debugcreatestreamclonebundle packed.hg + writing 2608 bytes for 6 files + bundle requirements: revlogv1 + + $ f -B 64 --size --sha1 --hexdump packed.hg + packed.hg: size=2758, sha1=864c1c7b490bac9f2950ef5a660668378ac0524e + 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........| + 0010: 00 00 00 00 0a 30 00 09 72 65 76 6c 6f 67 76 31 |.....0..revlogv1| + 0020: 00 64 61 74 61 2f 61 64 69 66 66 65 72 65 6e 74 |.data/adifferent| + 0030: 66 69 6c 65 2e 69 00 31 33 39 0a 00 01 00 01 00 |file.i.139......| + +generaldelta requirement is listed in stream clone bundles + + $ hg --config format.generaldelta=true init testgd + $ cd testgd + $ touch foo + $ hg -q commit -A -m initial + $ cd .. + $ hg -R testgd debugcreatestreamclonebundle packedgd.hg + writing 301 bytes for 3 files + bundle requirements: generaldelta, revlogv1 + + $ f -B 64 --size --sha1 --hexdump packedgd.hg + packedgd.hg: size=396, sha1=981f9e589799335304a5a9a44caa3623a48d2a9f + 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........| + 0010: 00 00 00 00 01 2d 00 16 67 65 6e 65 72 61 6c 64 |.....-..generald| + 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da| + 0030: 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 03 00 01 |ta/foo.i.64.....| + Create partial clones $ rm -r empty diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -75,6 +75,7 @@ Show debug commands if there are no othe debugcommands debugcomplete debugconfig + debugcreatestreamclonebundle debugdag debugdata debugdate @@ -236,6 +237,7 @@ Show all commands + options debugcheckstate: debugcommands: debugcomplete: options + debugcreatestreamclonebundle: debugdag: tags, branches, dots, spaces debugdata: changelog, manifest, dir debugdate: extended diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -791,6 +791,8 @@ Test list of internal help commands list all available commands and options debugcomplete returns the completion list associated with the given command + debugcreatestreamclonebundle + create a stream clone bundle file debugdag format the changelog or an index DAG as a concise textual description debugdata dump the contents of a data file revision @@ -1064,10 +1066,11 @@ Test keyword search help Commands: - bookmarks create a new bookmark or list existing bookmarks - clone make a copy of an existing repository - paths show aliases for remote repositories - update update working directory (or switch revisions) + bookmarks create a new bookmark or list existing bookmarks + clone make a copy of an existing repository + debugcreatestreamclonebundle create a stream clone bundle file + paths show aliases for remote repositories + update update working directory (or switch revisions) Extensions: