[PATCH 11 of 16] push: extract outgoing computation and validation in its own method
pierre-yves.david at logilab.fr
pierre-yves.david at logilab.fr
Wed Apr 17 10:58:46 CDT 2013
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1366213905 -7200
# Wed Apr 17 17:51:45 2013 +0200
# Node ID 74fe7f2c9abe580306ed39c0968fa87188a9bbaa
# Parent bdd829b196108ee5099021f0a4c7b56c7a3af078
push: extract outgoing computation and validation in its own method
Another step toward god function diet.
diff --git a/mercurial/exchangeutil.py b/mercurial/exchangeutil.py
--- a/mercurial/exchangeutil.py
+++ b/mercurial/exchangeutil.py
@@ -21,10 +21,13 @@ class pushoperation(object):
self.remote = remote
self.force = force
self.revs = revs
self.newbranch = newbranch
+ self._outgoing = None # discovery.outgoing object
+ self._remoteheads = None # know remote head before the push
+
def perform(self):
'''Push outgoing changesets (limited by revs) from the current
repository to remote. Return an integer:
- None means nothing to push
- 0 means HTTP error
@@ -50,81 +53,50 @@ class pushoperation(object):
lock = None
unbundle = remote.capable('unbundle')
if not unbundle:
lock = remote.lock()
try:
- # discovery
- fci = discovery.findcommonincoming
- commoninc = fci(unfi, remote, force=self.force)
- common, inc, remoteheads = commoninc
- fco = discovery.findcommonoutgoing
- outgoing = fco(unfi, remote, onlyheads=self.revs,
- commoninc=commoninc, force=self.force)
+ self._outgoing, self._remoteheads = self._processoutgoing()
- if not outgoing.missing:
+ if not self._outgoing.missing:
# nothing to push
- scmutil.nochangesfound(unfi.ui, unfi, outgoing.excluded)
+ scmutil.nochangesfound(unfi.ui, unfi,
+ self._outgoing.excluded)
ret = None
else:
- # something to push
- if not self.force:
- # if self.obsstore == False --> no obsolete
- # then, save the iteration
- if unfi.obsstore:
- # this message are here for 80 char limit reason
- mso = _("push includes obsolete changeset: %s!")
- mst = "push includes %s changeset: %s!"
- # plain versions for i18n tool to detect them
- _("push includes unstable changeset: %s!")
- _("push includes bumped changeset: %s!")
- _("push includes divergent changeset: %s!")
- # If we are to push if there is at least one
- # obsolete or unstable changeset in missing, at
- # least one of the missinghead will be obsolete or
- # unstable. So checking heads only is ok
- for node in outgoing.missingheads:
- ctx = unfi[node]
- if ctx.obsolete():
- raise util.Abort(mso % ctx)
- elif ctx.troubled():
- raise util.Abort(_(mst)
- % (ctx.troubles()[0],
- ctx))
- discovery.checkheads(unfi, remote, outgoing,
- remoteheads, self.newbranch,
- bool(inc))
-
# create a changegroup from local
- if self.revs is None and not outgoing.excluded:
+ if self.revs is None and not self._outgoing.excluded:
# push everything,
# use the fast path, no race possible on push
- cg = repo._changegroup(outgoing.missing, 'push')
+ cg = repo._changegroup(self._outgoing.missing, 'push')
else:
- cg = repo.getlocalbundle('push', outgoing)
+ cg = repo.getlocalbundle('push', self._outgoing)
# apply changegroup to remote
if unbundle:
# local repo finds heads on server, finds out what
# revs it must push. once revs transferred, if server
# finds it has different heads (someone else won
# commit/push race), server aborts.
if self.force:
remoteheads = ['force']
+ else:
+ remoteheads = self._remoteheads
# ssh: return remote's addchangegroup()
# http: return remote's addchangegroup() or 0 for error
ret = remote.unbundle(cg, remoteheads, 'push')
else:
# we return an integer indicating remote head count
# change
ret = remote.addchangegroup(cg, 'push', repo.url())
if ret:
# push succeed, synchronize target of the push
- cheads = outgoing.missingheads
+ cheads = self._outgoing.missingheads
elif self.revs is None:
# All out push fails. synchronize all common
- cheads = outgoing.commonheads
+ cheads = self._outgoing.commonheads
else:
# I want cheads = heads(::missingheads and ::commonheads)
# (missingheads is revs with secret changeset filtered out)
#
# This can be expressed as:
@@ -136,17 +108,17 @@ class pushoperation(object):
# common = (::commonheads)
# missing = ((commonheads::missingheads) - commonheads)
#
# We can pick:
# * missingheads part of common (::commonheads)
- common = set(outgoing.common)
+ common = set(self._outgoing.common)
cheads = [node for node in self.revs if node in common]
# and
# * commonheads parents on missing
revset = unfi.set('%ln and parents(roots(%ln))',
- outgoing.commonheads,
- outgoing.missing)
+ self._outgoing.commonheads,
+ self._outgoing.missing)
cheads.extend(c.node() for c in revset)
# even when we don't push, exchanging phase data is useful
remotephases = remote.listkeys('phases')
if (repo.ui.configbool('ui', '_usedassubrepo', False)
and remotephases # server supports phases
@@ -196,10 +168,51 @@ class pushoperation(object):
finally:
locallock.release()
self._pushbookmarks()
return ret
+ def _processoutgoing(self):
+ """call discovery to find outgoing changeset and validate it content
+ """
+ unfi = self.repo.unfiltered()
+ fci = discovery.findcommonincoming
+ commoninc = fci(unfi, self.remote, force=self.force)
+ common, inc, remoteheads = commoninc
+ fco = discovery.findcommonoutgoing
+ outgoing = fco(unfi, self.remote, onlyheads=self.revs,
+ commoninc=commoninc, force=self.force)
+ if (not self.force) and outgoing.missing:
+ # something to push, validate it
+ #
+ # if self.obsstore == False --> no obsolete
+ # then, save the iteration
+ if unfi.obsstore:
+ # this message are here for 80 char limit reason
+ mso = _("push includes obsolete changeset: %s!")
+ mst = "push includes %s changeset: %s!"
+ # plain versions for i18n tool to detect them
+ _("push includes unstable changeset: %s!")
+ _("push includes bumped changeset: %s!")
+ _("push includes divergent changeset: %s!")
+ # If we are to push if there is at least one
+ # obsolete or unstable changeset in missing, at
+ # least one of the missinghead will be obsolete or
+ # unstable. So checking heads only is ok
+ for node in outgoing.missingheads:
+ ctx = unfi[node]
+ if ctx.obsolete():
+ raise util.Abort(mso % ctx)
+ elif ctx.troubled():
+ raise util.Abort(_(mst)
+ % (ctx.troubles()[0],
+ ctx))
+ discovery.checkheads(unfi, self.remote, outgoing,
+ remoteheads, self.newbranch, bool(inc))
+ return outgoing, remoteheads
+
+
+
def _pushobsolescence(self):
"""Send local obsolescence marker to remote"""
self.repo.ui.debug('try to push obsolete markers to remote\n')
if (obsolete._enabled and self.repo.obsstore and
'obsolete' in self.remote.listkeys('namespaces')):
More information about the Mercurial-devel
mailing list