Patchwork [2,of,2,V2] ui: path option to declare which revisions to push by default

login
register
mail settings
Submitter Gregory Szorc
Date June 26, 2016, 1:51 a.m.
Message ID <45f9ebf67a1f8d4bd2f9.1466905874@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/15627/
State Accepted
Headers show

Comments

Gregory Szorc - June 26, 2016, 1:51 a.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1466905662 25200
#      Sat Jun 25 18:47:42 2016 -0700
# Node ID 45f9ebf67a1f8d4bd2f9565c563da2ac2757ecf8
# Parent  b4d373225616128b6d8b29ba893976504c4f79c9
ui: path option to declare which revisions to push by default

Now that we have a mechanism for declaring path sub-options, we can
start to pile on features!

Many power users have expressed frustration that bare `hg push`
attempts to push all local revisions to the remote. This patch
introduces the "pushrev" path sub-option to control which revisions
are pushed when no "-r" argument is specified.

The value of this sub-option is a revset, naturally.

A future feature addition could potentially introduce a "pushnames"
sub-options that declares the list of names (branches, bookmarks,
topics, etc) to push by default. The entire "what to push by default"
feature should probably be considered before this patch lands.
Pierre-Yves David - June 26, 2016, 2:21 a.m.
On 06/26/2016 03:51 AM, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1466905662 25200
> #      Sat Jun 25 18:47:42 2016 -0700
> # Node ID 45f9ebf67a1f8d4bd2f9565c563da2ac2757ecf8
> # Parent  b4d373225616128b6d8b29ba893976504c4f79c9
> ui: path option to declare which revisions to push by default

excellent, pushed.
Yuya Nishihara - June 26, 2016, 8:12 a.m.
On Sat, 25 Jun 2016 18:51:14 -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1466905662 25200
> #      Sat Jun 25 18:47:42 2016 -0700
> # Node ID 45f9ebf67a1f8d4bd2f9565c563da2ac2757ecf8
> # Parent  b4d373225616128b6d8b29ba893976504c4f79c9
> ui: path option to declare which revisions to push by default

> +    elif path.pushrev:
> +        # It doesn't make any sense to specify ancestor revisions. So limit
> +        # to DAG heads to make discovery simpler.
> +        revs = scmutil.revrange(repo, ['heads(%s)' % path.pushrev])

Better to use revset.formatspec('heads(%r)') to report parse error
appropriately.

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5937,16 +5937,24 @@  def push(ui, repo, dest=None, **opts):
     revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
     other = hg.peer(repo, opts, dest)
 
     if revs:
         revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
         if not revs:
             raise error.Abort(_("specified revisions evaluate to an empty set"),
                              hint=_("use different revision arguments"))
+    elif path.pushrev:
+        # It doesn't make any sense to specify ancestor revisions. So limit
+        # to DAG heads to make discovery simpler.
+        revs = scmutil.revrange(repo, ['heads(%s)' % path.pushrev])
+        revs = [repo[rev].node() for rev in revs]
+        if not revs:
+            raise error.Abort(_('default push revset for path evaluates to an '
+                                'empty set'))
 
     repo._subtoppath = dest
     try:
         # push subrepos depth-first for coherent ordering
         c = repo['']
         subs = c.substate # only repos that are committed
         for s in sorted(subs):
             result = c.sub(s).push(opts)
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1277,16 +1277,25 @@  behavior for that specific path. Example
     my_server:pushurl = ssh://example.com/my_path
 
 The following sub-options can be defined:
 
 ``pushurl``
    The URL to use for push operations. If not defined, the location
    defined by the path's main entry is used.
 
+``pushrev``
+   A revset defining which revisions to push by default.
+
+   When :hg:`push` is executed without a ``-r`` argument, the revset
+   defined by this sub-option is evaluated to determine what to push.
+
+   For example, a value of ``.`` will push the working directory's
+   revision by default.
+
 The following special named paths exist:
 
 ``default``
    The URL or directory to use when no source or remote is specified.
 
    :hg:`clone` will automatically define this path to the location the
    repository was cloned from.
 
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -1276,16 +1276,20 @@  def pushurlpathoption(ui, path, value):
     # push.
     if u.fragment:
         ui.warn(_('("#fragment" in paths.%s:pushurl not supported; '
                   'ignoring)\n') % path.name)
         u.fragment = None
 
     return str(u)
 
+@pathsuboption('pushrev', 'pushrev')
+def pushrevpathoption(ui, path, value):
+    return value
+
 class path(object):
     """Represents an individual path and its configuration."""
 
     def __init__(self, ui, name, rawloc=None, suboptions=None):
         """Construct a path from its config options.
 
         ``ui`` is the ``ui`` instance the path is coming from.
         ``name`` is the symbolic name of the path.
diff --git a/tests/test-default-push.t b/tests/test-default-push.t
--- a/tests/test-default-push.t
+++ b/tests/test-default-push.t
@@ -100,9 +100,36 @@  Windows needs a leading slash to make a 
   $ hg push
   pushing to file:/*/$TESTTMP/pushurlsource/../pushurldest (glob)
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
 
+:pushrev is used when no -r is passed
+
+  $ cat >> .hg/hgrc << EOF
+  > default:pushrev = .
+  > EOF
+  $ hg -q up -r 0
+  $ echo head1 > foo
+  $ hg -q commit -A -m head1
+  $ hg -q up -r 0
+  $ echo head2 > foo
+  $ hg -q commit -A -m head2
+  $ hg push -f
+  pushing to file:/*/$TESTTMP/pushurlsource/../pushurldest (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+
+  $ hg --config 'paths.default:pushrev=draft()' push -f
+  pushing to file:/*/$TESTTMP/pushurlsource/../pushurldest (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+
   $ cd ..
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -1510,16 +1510,25 @@  Test section lookup
         my_server:pushurl = ssh://example.com/my_path
   
       The following sub-options can be defined:
   
       "pushurl"
          The URL to use for push operations. If not defined, the location
          defined by the path's main entry is used.
   
+      "pushrev"
+         A revset defining which revisions to push by default.
+  
+         When "hg push" is executed without a "-r" argument, the revset defined
+         by this sub-option is evaluated to determine what to push.
+  
+         For example, a value of "." will push the working directory's revision
+         by default.
+  
       The following special named paths exist:
   
       "default"
          The URL or directory to use when no source or remote is specified.
   
          'hg clone' will automatically define this path to the location the
          repository was cloned from.