[PATCH 2 of 2] push: introduce --readonly to make push behave more like pull
Mads Kiilerich
mads at kiilerich.com
Sat Aug 20 19:33:14 EDT 2016
# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1471735620 -7200
# Sun Aug 21 01:27:00 2016 +0200
# Branch stable
# Node ID 48f4ae36a49929c2389bfb75064f96d16159b2d0
# Parent 7880f56ca7495a2d0365a8280935eccd1e63f0c8
push: introduce --readonly to make push behave more like pull
Push and pull are almost symmetric ... except when they are not.
For example, push makes it possible to use a revset to specify the revisions to
push. Push can also be more suitable for distributing changes to multiple
mirrors than pull is. Finally, push will by default publish draft changesets.
Often, it is correct and desirable that push tries to update phases and thus
locks the repository while pushing ... put that also means that there can't be
multiple concurrent pushes and that pushing from non-publishing repositories
depends on correct configuration of the target repository.
We thus introduce --readonly to prevent push from locking the source repository
and thus prevent it from publishing. Push with --readonly is thus more
symmetric to pull.
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5878,6 +5878,7 @@ def pull(ui, repo, source="default", **o
('b', 'branch', [],
_('a specific branch you would like to push'), _('BRANCH')),
('', 'new-branch', False, _('allow pushing a new branch')),
+ ('', 'readonly', False, _("no source repo locking or phase update")),
] + remoteopts,
_('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
def push(ui, repo, dest=None, **opts):
@@ -5886,8 +5887,9 @@ def push(ui, repo, dest=None, **opts):
Push changesets from the local repository to the specified
destination.
- This operation is symmetrical to pull: it is identical to a pull
- in the destination repository from the current one.
+ This operation is almost symmetrical to pull: it is identical to a pull
+ in the destination repository from the current one, except that pushed
+ changesets in draft phase are made public unless --readonly is used.
By default, push will not allow creation of new heads at the
destination, since multiple heads would make it unclear which head
@@ -5969,7 +5971,8 @@ def push(ui, repo, dest=None, **opts):
pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
newbranch=opts.get('new_branch'),
bookmarks=opts.get('bookmark', ()),
- opargs=opts.get('opargs'))
+ opargs=opts.get('opargs'),
+ readonly=opts.get('readonly'))
result = not pushop.cgresult
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -275,7 +275,7 @@ class pushoperation(object):
"""
def __init__(self, repo, remote, force=False, revs=None, newbranch=False,
- bookmarks=()):
+ bookmarks=(), readonly=False):
# repo we push from
self.repo = repo
self.ui = repo.ui
@@ -289,6 +289,8 @@ class pushoperation(object):
self.bookmarks = bookmarks
# allow push of new branch
self.newbranch = newbranch
+ # no locking of source repo and no publishing phase update
+ self.readonly = readonly
# did a local lock get acquired?
self.locallocked = None
# step already performed
@@ -379,7 +381,7 @@ bookmsgmap = {'update': (_("updating boo
def push(repo, remote, force=False, revs=None, newbranch=False, bookmarks=(),
- opargs=None):
+ opargs=None, readonly=False):
'''Push outgoing changesets (limited by revs) from a local
repository to remote. Return an integer:
- None means nothing to push
@@ -391,7 +393,7 @@ def push(repo, remote, force=False, revs
if opargs is None:
opargs = {}
pushop = pushoperation(repo, remote, force, revs, newbranch, bookmarks,
- **opargs)
+ readonly, **opargs)
if pushop.remote.local():
missing = (set(pushop.repo.requirements)
- pushop.remote.local().supported)
@@ -413,23 +415,26 @@ def push(repo, remote, force=False, revs
raise error.Abort(_("destination does not support push"))
# get local lock as we might write phase data
localwlock = locallock = None
- try:
- # bundle2 push may receive a reply bundle touching bookmarks or other
- # things requiring the wlock. Take it now to ensure proper ordering.
- maypushback = pushop.ui.configbool('experimental', 'bundle2.pushback')
- if _canusebundle2(pushop) and maypushback:
- localwlock = pushop.repo.wlock()
- locallock = pushop.repo.lock()
- pushop.locallocked = True
- except IOError as err:
- pushop.locallocked = False
- if err.errno != errno.EACCES:
- raise
- # source repo cannot be locked.
- # We do not abort the push, but just disable the local phase
- # synchronisation.
- msg = 'cannot lock source repository: %s\n' % err
- pushop.ui.debug(msg)
+ if not pushop.readonly:
+ try:
+ # bundle2 push may receive a reply bundle touching bookmarks or
+ # other things requiring the wlock. Take it now to ensure proper
+ # ordering.
+ maypushback = pushop.ui.configbool('experimental',
+ 'bundle2.pushback')
+ if _canusebundle2(pushop) and maypushback:
+ localwlock = pushop.repo.wlock()
+ locallock = pushop.repo.lock()
+ pushop.locallocked = True
+ except IOError as err:
+ pushop.locallocked = False
+ if err.errno != errno.EACCES:
+ raise
+ # source repo cannot be locked.
+ # We do not abort the push, but just disable the local phase
+ # synchronisation.
+ msg = 'cannot lock source repository: %s\n' % err
+ pushop.ui.debug(msg)
try:
if pushop.locallocked:
pushop.trmanager = transactionmanager(pushop.repo,
@@ -988,7 +993,7 @@ def _localphasemove(pushop, nodes, phase
pushop.trmanager.transaction(),
phase,
nodes)
- else:
+ elif not pushop.readonly:
# repo is not locked, do not change any phases!
# Informs the user that phases should have been moved when
# applicable.
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -898,6 +898,7 @@ class hgsubrepo(abstractsubrepo):
force = opts.get('force')
newbranch = opts.get('new_branch')
ssh = opts.get('ssh')
+ readonly = opts.get('readonly')
# push subrepos depth-first for coherent ordering
c = self._repo['']
@@ -916,7 +917,8 @@ class hgsubrepo(abstractsubrepo):
self.ui.status(_('pushing subrepo %s to %s\n') %
(subrelpath(self), dsturl))
other = hg.peer(self._repo, {'ssh': ssh}, dsturl)
- res = exchange.push(self._repo, other, force, newbranch=newbranch)
+ res = exchange.push(self._repo, other, force, newbranch=newbranch,
+ readonly=readonly)
# the repo is now clean
self._cachestorehash(dsturl)
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -217,7 +217,7 @@ Show all commands + options
log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
merge: force, rev, preview, tool
pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
- push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
+ push: force, rev, bookmark, branch, new-branch, readonly, ssh, remotecmd, insecure
remove: after, force, subrepos, include, exclude
serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
diff --git a/tests/test-phases-exchange.t b/tests/test-phases-exchange.t
--- a/tests/test-phases-exchange.t
+++ b/tests/test-phases-exchange.t
@@ -1194,7 +1194,7 @@ 2. Test that failed phases movement are
#endif
-Test that clone behaves like pull and doesn't
+Test that clone and push --readonly behave like pull and don't
publish changesets as plain push does
$ hg -R Upsilon phase -q --force --draft 2
@@ -1214,7 +1214,7 @@ publish changesets as plain push does
|
~
- $ hg -R Upsilon push Pi -r 8
+ $ hg -R Upsilon push Pi -r 8 --readonly
pushing to Pi
searching for changes
adding changesets
@@ -1223,6 +1223,6 @@ publish changesets as plain push does
added 1 changesets with 1 changes to 1 files
$ hgph Upsilon -r 'min(draft())'
- o 9 draft a-G - 3e27b6f1eee1
+ o 8 draft a-F - b740e3e5c05d
|
~
More information about the Mercurial-devel
mailing list