Patchwork D10161: push: allow to specify multiple destinations

login
register
mail settings
Submitter phabricator
Date March 11, 2021, 4:54 p.m.
Message ID <differential-rev-PHID-DREV-be4mvrwb5nvgzdo2zn4k-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48476/
State Superseded
Headers show

Comments

phabricator - March 11, 2021, 4:54 p.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  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.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10161

AFFECTED FILES
  mercurial/commands.py
  tests/test-exchange-multi-source.t

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

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
@@ -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
 ==================
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5615,11 +5615,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
@@ -5655,6 +5655,9 @@ 
     Please see :hg:`help urls` for important details about ``ssh://``
     URLs. If DESTINATION is omitted, a default path will be used.
 
+    When multiple DESTINATION are passed, they will be pushed to on after the
+    other. The command will stop at the first failure encountered.
+
     .. container:: verbose
 
         The --pushvars option sends strings to the server that become
@@ -5699,7 +5702,11 @@ 
                 # 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.paths.getpath(dest, default=(b'default-push', b'default'))
         if not path:
             raise error.ConfigError(
@@ -5746,9 +5753,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
 
@@ -5768,15 +5775,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