comparison mercurial/commands.py @ 46948:946db89607c8

bundle: support multiple destinations `hg outgoing` and `hg push` now support multiple destination. We do the same for `hg bundle`. Various other commands needs this kind of behavior and it would be create to factor this code out for their usage. However this is an adventure for another time. They are some minor change to the tests (in addition to the new test for the feature): * one because I updated a message to plurals, * another one because the error changed, and I actually find it clearer. Differential Revision: https://phab.mercurial-scm.org/D10414
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 14 Apr 2021 17:02:20 +0200
parents dec31caf5fd6
children 3800a6aafb6f
comparison
equal deleted inserted replaced
46947:3f29765e0d95 46948:946db89607c8
1529 _(b'bundle compression type to use'), 1529 _(b'bundle compression type to use'),
1530 _(b'TYPE'), 1530 _(b'TYPE'),
1531 ), 1531 ),
1532 ] 1532 ]
1533 + remoteopts, 1533 + remoteopts,
1534 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'), 1534 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]...'),
1535 helpcategory=command.CATEGORY_IMPORT_EXPORT, 1535 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1536 ) 1536 )
1537 def bundle(ui, repo, fname, dest=None, **opts): 1537 def bundle(ui, repo, fname, *dests, **opts):
1538 """create a bundle file 1538 """create a bundle file
1539 1539
1540 Generate a bundle file containing data to be transferred to another 1540 Generate a bundle file containing data to be transferred to another
1541 repository. 1541 repository.
1542 1542
1543 To create a bundle containing all changesets, use -a/--all 1543 To create a bundle containing all changesets, use -a/--all
1544 (or --base null). Otherwise, hg assumes the destination will have 1544 (or --base null). Otherwise, hg assumes the destination will have
1545 all the nodes you specify with --base parameters. Otherwise, hg 1545 all the nodes you specify with --base parameters. Otherwise, hg
1546 will assume the repository has all the nodes in destination, or 1546 will assume the repository has all the nodes in destination, or
1547 default-push/default if no destination is specified, where destination 1547 default-push/default if no destination is specified, where destination
1548 is the repository you provide through DEST option. 1548 is the repositories you provide through DEST option.
1549 1549
1550 You can change bundle format with the -t/--type option. See 1550 You can change bundle format with the -t/--type option. See
1551 :hg:`help bundlespec` for documentation on this format. By default, 1551 :hg:`help bundlespec` for documentation on this format. By default,
1552 the most appropriate format is used and compression defaults to 1552 the most appropriate format is used and compression defaults to
1553 bzip2. 1553 bzip2.
1588 _(b'packed bundles cannot be produced by "hg bundle"'), 1588 _(b'packed bundles cannot be produced by "hg bundle"'),
1589 hint=_(b"use 'hg debugcreatestreamclonebundle'"), 1589 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1590 ) 1590 )
1591 1591
1592 if opts.get(b'all'): 1592 if opts.get(b'all'):
1593 if dest: 1593 if dests:
1594 raise error.InputError( 1594 raise error.InputError(
1595 _(b"--all is incompatible with specifying a destination") 1595 _(b"--all is incompatible with specifying destinations")
1596 ) 1596 )
1597 if opts.get(b'base'): 1597 if opts.get(b'base'):
1598 ui.warn(_(b"ignoring --base because --all was specified\n")) 1598 ui.warn(_(b"ignoring --base because --all was specified\n"))
1599 base = [nullrev] 1599 base = [nullrev]
1600 else: 1600 else:
1603 raise error.Abort( 1603 raise error.Abort(
1604 _(b"repository does not support bundle version %s") % cgversion 1604 _(b"repository does not support bundle version %s") % cgversion
1605 ) 1605 )
1606 1606
1607 if base: 1607 if base:
1608 if dest: 1608 if dests:
1609 raise error.InputError( 1609 raise error.InputError(
1610 _(b"--base is incompatible with specifying a destination") 1610 _(b"--base is incompatible with specifying destinations")
1611 ) 1611 )
1612 common = [repo[rev].node() for rev in base] 1612 common = [repo[rev].node() for rev in base]
1613 heads = [repo[r].node() for r in revs] if revs else None 1613 heads = [repo[r].node() for r in revs] if revs else None
1614 outgoing = discovery.outgoing(repo, common, heads) 1614 outgoing = discovery.outgoing(repo, common, heads)
1615 missing = outgoing.missing
1616 excluded = outgoing.excluded
1615 else: 1617 else:
1616 dest = ui.expandpath(dest or b'default-push', dest or b'default') 1618 missing = set()
1617 dest, branches = urlutil.parseurl(dest, opts.get(b'branch')) 1619 excluded = set()
1618 other = hg.peer(repo, opts, dest) 1620 for path in urlutil.get_push_paths(repo, ui, dests):
1619 revs = [repo[r].hex() for r in revs] 1621 other = hg.peer(repo, opts, path.rawloc)
1620 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs) 1622 if revs is not None:
1621 heads = revs and pycompat.maplist(repo.lookup, revs) or revs 1623 hex_revs = [repo[r].hex() for r in revs]
1622 outgoing = discovery.findcommonoutgoing( 1624 else:
1623 repo, 1625 hex_revs = None
1624 other, 1626 branches = (path.branch, [])
1625 onlyheads=heads, 1627 head_revs, checkout = hg.addbranchrevs(
1626 force=opts.get(b'force'), 1628 repo, repo, branches, hex_revs
1627 portable=True, 1629 )
1630 heads = (
1631 head_revs
1632 and pycompat.maplist(repo.lookup, head_revs)
1633 or head_revs
1634 )
1635 outgoing = discovery.findcommonoutgoing(
1636 repo,
1637 other,
1638 onlyheads=heads,
1639 force=opts.get(b'force'),
1640 portable=True,
1641 )
1642 missing.update(outgoing.missing)
1643 excluded.update(outgoing.excluded)
1644
1645 if not missing:
1646 scmutil.nochangesfound(ui, repo, not base and excluded)
1647 return 1
1648
1649 if heads:
1650 outgoing = discovery.outgoing(
1651 repo, missingroots=missing, ancestorsof=heads
1628 ) 1652 )
1629 1653 else:
1630 if not outgoing.missing: 1654 outgoing = discovery.outgoing(repo, missingroots=missing)
1631 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded) 1655 outgoing.excluded = sorted(excluded)
1632 return 1
1633 1656
1634 if cgversion == b'01': # bundle1 1657 if cgversion == b'01': # bundle1
1635 bversion = b'HG10' + bundlespec.wirecompression 1658 bversion = b'HG10' + bundlespec.wirecompression
1636 bcompression = None 1659 bcompression = None
1637 elif cgversion in (b'02', b'03'): 1660 elif cgversion in (b'02', b'03'):