Patchwork [3,of,4,RFC,path,options] ui.paths: add a "pushrevset" path option

login
register
mail settings
Submitter Gregory Szorc
Date March 1, 2015, 11:23 p.m.
Message ID <4da24a2a9e7b82e5cd00.1425252227@vm-ubuntu-main.gateway.sonic.net>
Download mbox | patch
Permalink /patch/7873/
State Deferred
Headers show

Comments

Gregory Szorc - March 1, 2015, 11:23 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1423515351 28800
#      Mon Feb 09 12:55:51 2015 -0800
# Node ID 4da24a2a9e7b82e5cd0082e4d69255c0cd5b805b
# Parent  d5f40bb2b253311c24a4a1c9dd26b4893fb8a74c
ui.paths: add a "pushrevset" path option

If a path has the "pushrevset" option defined and an `hg push`
has not defined an explicit revision to push, a bookmark to
push, or a branch to push, we will now attempt to push the
revision(s) specified by the "pushrevset" revset defined in the
path's config.

This patch begins the process of giving power users more control
over what is pushed to a remote by default.

The implementation is not complete. For example, a revset defining
bookmarks will push the underlying revisions without bookmark updates.
This limitation will need to be addressed by a separate option.

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5092,8 +5092,10 @@  def push(ui, repo, dest=None, **opts):
     other = hg.peer(repo, opts, url)
 
     if revs:
         revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
+    elif path.pushrevset:
+        revs = [repo[rev].node() for rev in repo.revs(path.pushrevset)]
 
     repo._subtoppath = url
     try:
         # push subrepos depth-first for coherent ordering
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1102,8 +1102,23 @@  The following per-path options are recog
     location assigned to the main path option will be used.
 
     Note: ``#revision`` fragments are not allowed in ``purlurl``.
 
+``pushrevset``
+    A revset defining the revisions to push to this path by default.
+
+    By default, :hg:`push` will attempt to push all local changesets
+    to a remote. If this is set, :hg:`push` with no ``-r`` argument
+    will use the revset specified by this option to determine what to
+    push.
+
+    e.g. use ``.pushrev = .`` to default to pushing the changeset the
+    working copy is based upon.
+
+    Note: Bookmarks will not be pushed if this option is set, even if the
+    revset specifies bookmarks to push. This is because revsets evaluate
+    to changesets, not names.
+
 ``phases``
 ----------
 
 Specifies default handling of phases. See :hg:`help phases` for more
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -959,9 +959,10 @@  class paths(object):
             if '.' in name:
                 continue
 
             yield path(name, url=loc,
-                       pushurl=ui.config('paths', '%s.pushurl' % name))
+                       pushurl=ui.config('paths', '%s.pushurl' % name),
+                       pushrevset=ui.config('paths', '%s.pushrevset' % name))
 
     def __getitem__(self, key):
         for path in self:
             if path.name == key:
@@ -1022,9 +1023,10 @@  class paths(object):
 
 class path(object):
     """Represents an individual path and its configuration."""
 
-    def __init__(self, name, url=None, local=None, pushurl=None):
+    def __init__(self, name, url=None, local=None, pushurl=None,
+                 pushrevset=None):
         """Construct a path from its config options.
 
         The primary URL for the path is defined as either a URL via ``url``
         (preferred) or from a local, relative filesystem path (``local``).
@@ -1046,4 +1048,5 @@  class path(object):
             raise util.Abort(_('pushurl may not have #revision fragment: %s') %
                                pushurl)
 
         self.pushurl = pushurl or url
+        self.pushrevset = pushrevset
diff --git a/tests/test-push-path-config.t b/tests/test-push-path-config.t
--- a/tests/test-push-path-config.t
+++ b/tests/test-push-path-config.t
@@ -47,4 +47,88 @@  Push should use "pushurl"
   remote: adding changesets
   remote: adding manifests
   remote: adding file changes
   remote: added 1 changesets with 1 changes to 1 files
+
+Push should use "pushrevset"
+
+  $ cat >> .hg/hgrc << EOF
+  > pushrevset1 = ssh://user@dummy/$TESTTMP/server
+  > pushrevset1.pushrevset = .
+  > EOF
+
+  $ echo head1 > foo
+  $ hg commit -m 'head 1'
+  $ hg -q up -r 0
+  $ echo head2 > foo
+  $ hg commit -m 'head 2'
+  created new head
+
+  $ hg push pushrevset1
+  pushing to ssh://user@dummy/$TESTTMP/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+
+We can override pushrevset via -r
+
+  $ hg push -r 1 -f pushrevset1
+  pushing to ssh://user@dummy/$TESTTMP/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+
+A pushrevset with multiple branches configured will push those branches
+
+  $ hg -q up -r 0
+  $ hg branch b1
+  marked working directory as branch b1
+  (branches are permanent and global, did you want a bookmark?)
+  $ echo b1_1 > foo
+  $ hg commit -m 'branch 1 commit 1'
+  $ hg -q up -r 0
+  $ hg branch b2
+  marked working directory as branch b2
+  (branches are permanent and global, did you want a bookmark?)
+  $ echo b2_1 > foo
+  $ hg commit -m 'branch 2 commit 1'
+  $ hg -q up -r 0
+  $ hg branch b3
+  marked working directory as branch b3
+  (branches are permanent and global, did you want a bookmark?)
+  $ echo b3_1 > foo
+  $ hg commit -m 'branch 3 commit 1'
+
+  $ hg push -b b1 -b b2 -b b3 --new-branch ssh://user@dummy/$TESTTMP/server
+  pushing to ssh://user@dummy/$TESTTMP/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 3 changesets with 3 changes to 1 files (+3 heads)
+
+  $ cat >> .hg/hgrc << EOF
+  > twobranches = ssh://user@dummy/$TESTTMP/server
+  > twobranches.pushrevset = b1 or b2
+  > EOF
+
+  $ hg -q up b1
+  $ echo b1_2 > foo
+  $ hg commit -m 'branch 1 commit 2'
+  $ hg -q up b2
+  $ echo b2_2 > foo
+  $ hg commit -m 'branch 2 commit 2'
+  $ hg -q up b3
+  $ echo b3_2 > foo
+  $ hg commit -m 'branch 3 commit 2'
+
+  $ hg push twobranches
+  pushing to ssh://user@dummy/$TESTTMP/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 1 files