push: allow to specify multiple destinations
I end up needing that on a regular basis and it turn out to be very simple to
implement. See documentation and test for details.
Differential Revision: https://phab.mercurial-scm.org/D10161
--- a/mercurial/commands.py Wed Mar 17 15:20:45 2021 +0100
+++ b/mercurial/commands.py Wed Mar 10 05:50:20 2021 +0100
@@ -5623,11 +5623,11 @@
),
]
+ remoteopts,
- _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
+ _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]...'),
helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
helpbasic=True,
)
-def push(ui, repo, dest=None, **opts):
+def push(ui, repo, *dests, **opts):
"""push changes to the specified destination
Push changesets from the local repository to the specified
@@ -5663,6 +5663,9 @@
Please see :hg:`help urls` for important details about ``ssh://``
URLs. If DESTINATION is omitted, a default path will be used.
+ When passed multiple destinations, push will process them one after the
+ other, but stop should an error occur.
+
.. container:: verbose
The --pushvars option sends strings to the server that become
@@ -5706,7 +5709,12 @@
# if we try to push a deleted bookmark, translate it to null
# this lets simultaneous -r, -b options continue working
opts.setdefault(b'rev', []).append(b"null")
- if True:
+
+ if not dests:
+ dests = [None]
+ some_pushed = False
+ result = 0
+ for dest in dests:
path = ui.getpath(dest, default=(b'default-push', b'default'))
if not path:
raise error.ConfigError(
@@ -5753,9 +5761,9 @@
c = repo[b'.']
subs = c.substate # only repos that are committed
for s in sorted(subs):
- result = c.sub(s).push(opts)
- if result == 0:
- return not result
+ sub_result = c.sub(s).push(opts)
+ if sub_result == 0:
+ return 1
finally:
del repo._subtoppath
@@ -5775,15 +5783,24 @@
opargs=opargs,
)
- result = not pushop.cgresult
+ if pushop.cgresult == 0:
+ result = 1
+ elif pushop.cgresult is not None:
+ some_pushed = True
if pushop.bkresult is not None:
if pushop.bkresult == 2:
result = 2
elif not result and pushop.bkresult:
result = 2
+
+ if result:
+ break
+
finally:
other.close()
+ if result == 0 and not some_pushed:
+ result = 1
return result
--- a/tests/test-exchange-multi-source.t Wed Mar 17 15:20:45 2021 +0100
+++ b/tests/test-exchange-multi-source.t Wed Mar 10 05:50:20 2021 +0100
@@ -71,6 +71,9 @@
Test simple bare operation
==========================
+pull
+----
+
$ hg clone main-repo test-repo-bare --rev 0 -U
adding changesets
adding manifests
@@ -121,9 +124,90 @@
o A 0
+push
+----
+
+ $ cp -R ./branch-E ./branch-E-push
+ $ cp -R ./branch-G ./branch-G-push
+ $ cp -R ./branch-H ./branch-H-push
+ $ hg push --force -R test-repo-bare ./branch-E-push ./branch-G-push ./branch-H-push
+ pushing to ./branch-E-push
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 3 changesets with 3 changes to 3 files (+2 heads)
+ pushing to ./branch-G-push
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 4 changesets with 4 changes to 4 files (+2 heads)
+ pushing to ./branch-H-push
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 4 changesets with 4 changes to 4 files (+2 heads)
+ $ hg log -R ./branch-E-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o H 7
+ |
+ | o E 4
+ | |
+ | o D 3
+ |/
+ o C 2
+ |
+ | o G 6
+ | |
+ | o F 5
+ |/
+ o B 1
+ |
+ o A 0
+
+ $ hg log -R ./branch-G-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o H 7
+ |
+ | o E 6
+ | |
+ | o D 5
+ |/
+ o C 4
+ |
+ | o G 3
+ | |
+ | o F 2
+ |/
+ o B 1
+ |
+ o A 0
+
+ $ hg log -R ./branch-H-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o G 7
+ |
+ o F 6
+ |
+ | o E 5
+ | |
+ | o D 4
+ | |
+ | | o H 3
+ | |/
+ | o C 2
+ |/
+ o B 1
+ |
+ o A 0
+
+ $ rm -rf ./*-push
+
Test operation with a target
============================
+pull
+----
+
$ hg clone main-repo test-repo-rev --rev 0 -U
adding changesets
adding manifests
@@ -199,6 +283,125 @@
o A 0
+push
+----
+
+We only push a specific branch with --rev
+
+ $ cp -R ./branch-E ./branch-E-push
+ $ cp -R ./branch-G ./branch-G-push
+ $ cp -R ./branch-H ./branch-H-push
+ $ 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
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files (+1 heads)
+ pushing to ./branch-G-push
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 2 changesets with 2 changes to 2 files (+1 heads)
+ pushing to ./branch-H-push
+ searching for changes
+ no changes found
+ $ hg log -R ./branch-E-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o H 5
+ |
+ | o E 4
+ | |
+ | o D 3
+ |/
+ o C 2
+ |
+ o B 1
+ |
+ o A 0
+
+ $ hg log -R ./branch-G-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o H 5
+ |
+ o C 4
+ |
+ | o G 3
+ | |
+ | o F 2
+ |/
+ o B 1
+ |
+ o A 0
+
+ $ hg log -R ./branch-H-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o H 3
+ |
+ o C 2
+ |
+ o B 1
+ |
+ o A 0
+
+ $ rm -rf ./*-push
+
+Same push, but the first one is a no-op
+
+ $ cp -R ./branch-E ./branch-E-push
+ $ cp -R ./branch-G ./branch-G-push
+ $ cp -R ./branch-H ./branch-H-push
+ $ 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
+ adding changesets
+ adding manifests
+ adding file changes
+ added 2 changesets with 2 changes to 2 files (+1 heads)
+ pushing to ./branch-H-push
+ searching for changes
+ no changes found
+ pushing to ./branch-E-push
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files (+1 heads)
+ $ hg log -R ./branch-E-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o H 5
+ |
+ | o E 4
+ | |
+ | o D 3
+ |/
+ o C 2
+ |
+ o B 1
+ |
+ o A 0
+
+ $ hg log -R ./branch-G-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o H 5
+ |
+ o C 4
+ |
+ | o G 3
+ | |
+ | o F 2
+ |/
+ o B 1
+ |
+ o A 0
+
+ $ hg log -R ./branch-H-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
+ o H 3
+ |
+ o C 2
+ |
+ o B 1
+ |
+ o A 0
+
+ $ rm -rf ./*-push
+
Test with --update
==================