[PATCH 2 of 2] push: introduce --multihead for pushing multiple heads without force
Mads Kiilerich
mads at kiilerich.com
Thu Oct 15 04:25:17 CDT 2015
# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1444900849 -7200
# Thu Oct 15 11:20:49 2015 +0200
# Node ID 2906d84ee5299a02864e253bf407196a3a35eb53
# Parent 5c78d0e30a35d0a2d50148681f3de10470ab088d
push: introduce --multihead for pushing multiple heads without force
Pushing of multiple heads can happen frequently. One example is when recreating
a named branch from another starting point after having closed the old branch
head. Another example is when history of a "pull request" is modified after
pushing to non-publishing repositories, for example on bitbucket, and you just
want to make the updated changes available to the world. That could only be
done by pushing with --force.
--force is scary. Smart developers know that "use a bigger hammer" rarely is
the _right_ answer. Telling them to use --force for relatively frequent
semi-power-user operations seems wrong.
Instead, introduce a new option for push that _just_ make it push multiple
heads without forcing other scary things that --force might do for this or
other commands.
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5303,6 +5303,7 @@ def pull(ui, repo, source="default", **o
@command('^push',
[('f', 'force', None, _('force push')),
+ ('', 'multihead', None, _('force push of multiple branch heads')),
('r', 'rev', [],
_('a changeset intended to be included in the destination'),
_('REV')),
@@ -5332,7 +5333,7 @@ def push(ui, repo, dest=None, **opts):
.. note::
- Extra care should be taken with the -f/--force option,
+ Extra care should be taken with the --multihead or -f/--force option,
which will push all new heads on all branches, an action which will
almost always cause confusion for collaborators.
@@ -5388,6 +5389,7 @@ def push(ui, repo, dest=None, **opts):
del repo._subtoppath
pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
newbranch=opts.get('new_branch'),
+ multihead=opts.get('multihead'),
bookmarks=opts.get('bookmark', ()))
result = not pushop.cgresult
diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -238,8 +238,8 @@ def _oldheadssummary(repo, remoteheads,
unsynced = set()
return {None: (oldheads, newheads, unsynced)}
-def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
- newbookmarks=[]):
+def checkheads(repo, remote, outgoing, remoteheads, newbranch, multihead,
+ inc=False, newbookmarks=[]):
"""Check that a push won't add any outgoing head
raise Abort error and display ui message as needed.
@@ -303,7 +303,6 @@ def checkheads(repo, remote, outgoing, r
oldhs = set(remoteheads)
oldhs.update(unsyncedheads)
candidate_newhs.update(unsyncedheads)
- dhs = None # delta heads, the new heads on branch
discardedheads = set()
if not repo.obsstore:
newhs = candidate_newhs
@@ -355,7 +354,10 @@ def checkheads(repo, remote, outgoing, r
else:
repo.ui.status(_("remote has heads on branch '%s' that are "
"not known locally: %s\n") % (branch, heads))
- if remoteheads is None:
+ dhs = None # delta heads, the new heads on branch
+ if multihead:
+ pass
+ elif remoteheads is None:
if len(newhs) > 1:
dhs = list(newhs)
if errormsg is None:
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -74,7 +74,7 @@ class pushoperation(object):
"""
def __init__(self, repo, remote, force=False, revs=None, newbranch=False,
- bookmarks=()):
+ multihead=False, bookmarks=()):
# repo we push from
self.repo = repo
self.ui = repo.ui
@@ -88,6 +88,8 @@ class pushoperation(object):
self.bookmarks = bookmarks
# allow push of new branch
self.newbranch = newbranch
+ # allow push of multiple heads
+ self.multihead = multihead
# did a local lock get acquired?
self.locallocked = None
# step already performed
@@ -177,7 +179,8 @@ bookmsgmap = {'update': (_("updating boo
}
-def push(repo, remote, force=False, revs=None, newbranch=False, bookmarks=()):
+def push(repo, remote, force=False, revs=None, newbranch=False,
+ multihead=False, bookmarks=()):
'''Push outgoing changesets (limited by revs) from a local
repository to remote. Return an integer:
- None means nothing to push
@@ -186,7 +189,8 @@ def push(repo, remote, force=False, revs
we have outgoing changesets but refused to push
- other values as described by addchangegroup()
'''
- pushop = pushoperation(repo, remote, force, revs, newbranch, bookmarks)
+ pushop = pushoperation(repo, remote, force, revs, newbranch, multihead,
+ bookmarks)
if pushop.remote.local():
missing = (set(pushop.repo.requirements)
- pushop.remote.local().supported)
@@ -445,6 +449,7 @@ def _pushcheckoutgoing(pushop):
discovery.checkheads(unfi, pushop.remote, outgoing,
pushop.remoteheads,
pushop.newbranch,
+ pushop.multihead,
bool(pushop.incoming),
newbm)
return True
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -213,7 +213,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, multihead, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
remove: after, force, subrepos, include, exclude
serve: accesslog, daemon, daemon-pipefds, 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-push-warn.t b/tests/test-push-warn.t
--- a/tests/test-push-warn.t
+++ b/tests/test-push-warn.t
@@ -151,7 +151,7 @@ Specifying a revset that evaluates to nu
(merge or see "hg help push" for details about pushing new heads)
[255]
- $ hg push -v -f -r 3 -r 4 ../c
+ $ hg push -v --multihead -r 3 -r 4 ../c
pushing to ../c
searching for changes
2 changesets found
@@ -389,7 +389,7 @@ Pushing multi headed new branch:
abort: push creates new branch 'f' with multiple heads
(merge or see "hg help push" for details about pushing new heads)
[255]
- $ hg push --branch f --new-branch --force ../f
+ $ hg push --branch f --new-branch --multi ../f
pushing to ../f
searching for changes
adding changesets
More information about the Mercurial-devel
mailing list