diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py --- a/hgext/patchbomb.py +++ b/hgext/patchbomb.py @@ -382,7 +382,10 @@ def _getbundle(repo, dest, **opts): if btype: opts['type'] = btype try: - commands.bundle(ui, repo, tmpfn, dest, **opts) + dests = [] + if dest: + dests = [dest] + commands.bundle(ui, repo, tmpfn, *dests, **opts) return util.readfile(tmpfn) finally: try: diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1531,10 +1531,10 @@ def branches(ui, repo, active=False, clo ), ] + remoteopts, - _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'), + _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]...'), helpcategory=command.CATEGORY_IMPORT_EXPORT, ) -def bundle(ui, repo, fname, dest=None, **opts): +def bundle(ui, repo, fname, *dests, **opts): """create a bundle file Generate a bundle file containing data to be transferred to another @@ -1545,7 +1545,7 @@ def bundle(ui, repo, fname, dest=None, * all the nodes you specify with --base parameters. Otherwise, hg will assume the repository has all the nodes in destination, or default-push/default if no destination is specified, where destination - is the repository you provide through DEST option. + is the repositories you provide through DEST option. You can change bundle format with the -t/--type option. See :hg:`help bundlespec` for documentation on this format. By default, @@ -1590,9 +1590,9 @@ def bundle(ui, repo, fname, dest=None, * ) if opts.get(b'all'): - if dest: + if dests: raise error.InputError( - _(b"--all is incompatible with specifying a destination") + _(b"--all is incompatible with specifying destinations") ) if opts.get(b'base'): ui.warn(_(b"ignoring --base because --all was specified\n")) @@ -1605,31 +1605,54 @@ def bundle(ui, repo, fname, dest=None, * ) if base: - if dest: + if dests: raise error.InputError( - _(b"--base is incompatible with specifying a destination") + _(b"--base is incompatible with specifying destinations") ) common = [repo[rev].node() for rev in base] heads = [repo[r].node() for r in revs] if revs else None outgoing = discovery.outgoing(repo, common, heads) + missing = outgoing.missing + excluded = outgoing.excluded else: - dest = ui.expandpath(dest or b'default-push', dest or b'default') - dest, branches = urlutil.parseurl(dest, opts.get(b'branch')) - other = hg.peer(repo, opts, dest) - revs = [repo[r].hex() for r in revs] - revs, checkout = hg.addbranchrevs(repo, repo, branches, revs) - heads = revs and pycompat.maplist(repo.lookup, revs) or revs - outgoing = discovery.findcommonoutgoing( - repo, - other, - onlyheads=heads, - force=opts.get(b'force'), - portable=True, + missing = set() + excluded = set() + for path in urlutil.get_push_paths(repo, ui, dests): + other = hg.peer(repo, opts, path.rawloc) + if revs is not None: + hex_revs = [repo[r].hex() for r in revs] + else: + hex_revs = None + branches = (path.branch, []) + head_revs, checkout = hg.addbranchrevs( + repo, repo, branches, hex_revs + ) + heads = ( + head_revs + and pycompat.maplist(repo.lookup, head_revs) + or head_revs + ) + outgoing = discovery.findcommonoutgoing( + repo, + other, + onlyheads=heads, + force=opts.get(b'force'), + portable=True, + ) + missing.update(outgoing.missing) + excluded.update(outgoing.excluded) + + if not missing: + scmutil.nochangesfound(ui, repo, not base and excluded) + return 1 + + if heads: + outgoing = discovery.outgoing( + repo, missingroots=missing, ancestorsof=heads ) - - if not outgoing.missing: - scmutil.nochangesfound(ui, repo, not base and outgoing.excluded) - return 1 + else: + outgoing = discovery.outgoing(repo, missingroots=missing) + outgoing.excluded = sorted(excluded) if cgversion == b'01': # bundle1 bversion = b'HG10' + bundlespec.wirecompression diff --git a/tests/test-bundle-r.t b/tests/test-bundle-r.t --- a/tests/test-bundle-r.t +++ b/tests/test-bundle-r.t @@ -171,14 +171,15 @@ should fail $ hg -R test bundle --base 2 -r tip test-bundle-branch1.hg test-3 - abort: --base is incompatible with specifying a destination + abort: --base is incompatible with specifying destinations [10] $ hg -R test bundle -a -r tip test-bundle-branch1.hg test-3 - abort: --all is incompatible with specifying a destination + abort: --all is incompatible with specifying destinations [10] $ hg -R test bundle -r tip test-bundle-branch1.hg - abort: repository default-push not found - [255] + config error: default repository not configured! + (see 'hg help config.paths') + [30] $ hg -R test bundle --base 2 -r tip test-bundle-branch1.hg 2 changesets found diff --git a/tests/test-exchange-multi-source.t b/tests/test-exchange-multi-source.t --- a/tests/test-exchange-multi-source.t +++ b/tests/test-exchange-multi-source.t @@ -170,6 +170,11 @@ push date: Thu Jan 01 00:00:00 1970 +0000 summary: C + $ hg bundle -R test-repo-bare bundle.hg ./branch-E-push ./branch-G-push ./branch-H-push + searching for changes + searching for changes + searching for changes + 6 changesets found $ hg push --force -R test-repo-bare ./branch-E-push ./branch-G-push ./branch-H-push pushing to ./branch-E-push searching for changes @@ -351,6 +356,11 @@ We only push a specific branch with --re date: Thu Jan 01 00:00:00 1970 +0000 summary: C + $ hg bundle -R test-repo-bare bundle.hg ./branch-E-push ./branch-G-push ./branch-H-push --rev default + searching for changes + searching for changes + searching for changes + 2 changesets found $ hg push --force -R test-repo-bare ./branch-E-push ./branch-G-push ./branch-H-push --rev default pushing to ./branch-E-push searching for changes @@ -429,6 +439,11 @@ Same push, but the first one is a no-op date: Thu Jan 01 00:00:00 1970 +0000 summary: C + $ hg bundle -R test-repo-bare bundle.hg ./branch-G-push ./branch-H-push ./branch-E-push --rev default + searching for changes + searching for changes + searching for changes + 2 changesets found $ hg push --force -R test-repo-bare ./branch-G-push ./branch-H-push ./branch-E-push --rev default pushing to ./branch-G-push searching for changes