localrepo: refactor prepush logic
Simplifies the prepush check logic and makes it a lot more direct and
comprehensible. Instead of comparing the total local vs. remote head count, it
compares the number of new vs. removed heads.
--- a/mercurial/localrepo.py Fri Apr 09 10:35:53 2010 +0200
+++ b/mercurial/localrepo.py Thu Apr 08 17:21:42 2010 +0200
@@ -1500,8 +1500,13 @@
remote_heads = remote.heads()
inc = self.findincoming(remote, common, remote_heads, force=force)
+ cl = self.changelog
update, updated_heads = self.findoutgoing(remote, common, remote_heads)
- msng_cl, bases, heads = self.changelog.nodesbetween(update, revs)
+ msng_cl, bases, heads = cl.nodesbetween(update, revs)
+
+ outgoingnodeset = set(msng_cl)
+ # compute set of nodes which, if they were a head before, no longer are
+ nolongeraheadnodeset = set(p for n in msng_cl for p in cl.parents(n))
def checkbranch(lheads, rheads, branchname=None):
'''
@@ -1511,33 +1516,10 @@
lheads: local branch heads
rheads: remote branch heads
'''
-
- warn = 0
-
- if len(lheads) > len(rheads):
- warn = 1
- else:
- # add local heads involved in the push
- updatelheads = [self.changelog.heads(x, lheads)
- for x in update]
- newheads = set(sum(updatelheads, [])) & set(lheads)
-
- if not newheads:
- return True
-
- # add heads we don't have or that are not involved in the push
- for r in rheads:
- if r in self.changelog.nodemap:
- desc = self.changelog.heads(r, heads)
- l = [h for h in heads if h in desc]
- if not l:
- newheads.add(r)
- else:
- newheads.add(r)
- if len(newheads) > len(rheads):
- warn = 1
-
- if warn:
+ newlheads = [n for n in lheads if n in outgoingnodeset]
+ formerrheads = [n for n in rheads if n in nolongeraheadnodeset]
+ if len(newlheads) > len(formerrheads):
+ # we add more new heads than we demote former heads to non-head
if branchname is not None:
msg = _("abort: push creates new remote heads"
" on branch '%s'!\n") % branchname
@@ -1601,7 +1583,7 @@
if revs is None:
# use the fast path, no race possible on push
- nodes = self.changelog.findmissing(common.keys())
+ nodes = cl.findmissing(common.keys())
cg = self._changegroup(nodes, 'push')
else:
cg = self.changegroupsubset(update, revs, 'push')