[PATCH 2 of 9 (38 total)] push: introduce a pushoperation object
pierre-yves.david at ens-lyon.org
pierre-yves.david at ens-lyon.org
Sat Feb 1 19:32:58 CST 2014
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1391128991 28800
# Thu Jan 30 16:43:11 2014 -0800
# Node ID 70e5daae7c52156584ee20eccc2a13e1e0752483
# Parent 01be490091fdb20f20723e445238f280c7a2f56a
push: introduce a pushoperation object
This object will hold all data and state gathered through the push. This will
allow us to split the long function into multiple small one. Smaller function
will be easier to maintains and wrap. The idea is to blindly store all
information related to the push in this object so that each step and extension
can use them if necessary.
We start by putting the `repo` variable in the object. More migration in other
changeset.
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -9,21 +9,36 @@ from i18n import _
from node import hex
import errno
import util, scmutil, changegroup
import discovery, phases, obsolete, bookmarks
+
+class pushoperation(object):
+ """A object that represent a single push operation
+
+ It purpose is to carry push related state and very common operation.
+
+ A new should be created at the begining of each push and discarded
+ afterward.
+ """
+
+ def __init__(self, repo):
+ # repo we push from
+ self.repo = repo
+
def push(repo, remote, force=False, revs=None, newbranch=False):
'''Push outgoing changesets (limited by revs) from a local
repository to remote. Return an integer:
- None means nothing to push
- 0 means HTTP error
- 1 means we pushed and remote head count is unchanged *or*
we have outgoing changesets but refused to push
- other values as described by addchangegroup()
'''
+ pushop = pushoperation(repo)
if remote.local():
- missing = set(repo.requirements) - remote.local().supported
+ missing = set(pushop.repo.requirements) - remote.local().supported
if missing:
msg = _("required features are not"
" supported in the destination:"
" %s") % (', '.join(sorted(missing)))
raise util.Abort(msg)
@@ -36,38 +51,38 @@ def push(repo, remote, force=False, revs
# unbundle assumes local user cannot lock remote repo (new ssh
# servers, http servers).
if not remote.canpush():
raise util.Abort(_("destination does not support push"))
- unfi = repo.unfiltered()
+ unfi = pushop.repo.unfiltered()
def localphasemove(nodes, phase=phases.public):
"""move <nodes> to <phase> in the local source repo"""
if locallock is not None:
- phases.advanceboundary(repo, phase, nodes)
+ phases.advanceboundary(pushop.repo, phase, nodes)
else:
# repo is not locked, do not change any phases!
# Informs the user that phases should have been moved when
# applicable.
- actualmoves = [n for n in nodes if phase < repo[n].phase()]
+ actualmoves = [n for n in nodes if phase < pushop.repo[n].phase()]
phasestr = phases.phasenames[phase]
if actualmoves:
- repo.ui.status(_('cannot lock source repo, skipping local'
- ' %s phase update\n') % phasestr)
+ pushop.repo.ui.status(_('cannot lock source repo, skipping '
+ 'local %s phase update\n') % phasestr)
# get local lock as we might write phase data
locallock = None
try:
- locallock = repo.lock()
+ locallock = pushop.repo.lock()
except IOError, err:
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
- repo.ui.debug(msg)
+ pushop.repo.ui.debug(msg)
try:
- repo.checkpush(force, revs)
+ pushop.repo.checkpush(force, revs)
lock = None
unbundle = remote.capable('unbundle')
if not unbundle:
lock = remote.lock()
try:
@@ -107,29 +122,29 @@ def push(repo, remote, force=False, revs
raise util.Abort(mso % ctx)
elif ctx.troubled():
raise util.Abort(_(mst)
% (ctx.troubles()[0],
ctx))
- newbm = repo.ui.configlist('bookmarks', 'pushing')
+ newbm = pushop.repo.ui.configlist('bookmarks', 'pushing')
discovery.checkheads(unfi, remote, outgoing,
remoteheads, newbranch,
bool(inc), newbm)
# TODO: get bundlecaps from remote
bundlecaps = None
# create a changegroup from local
if revs is None and not (outgoing.excluded
- or repo.changelog.filteredrevs):
+ or pushop.repo.changelog.filteredrevs):
# push everything,
# use the fast path, no race possible on push
- bundler = changegroup.bundle10(repo, bundlecaps)
- cg = repo._changegroupsubset(outgoing,
- bundler,
- 'push',
- fastpath=True)
+ bundler = changegroup.bundle10(pushop.repo, bundlecaps)
+ cg = pushop.repo._changegroupsubset(outgoing,
+ bundler,
+ 'push',
+ fastpath=True)
else:
- cg = repo.getlocalbundle('push', outgoing, bundlecaps)
+ cg = pushop.repo.getlocalbundle('push', outgoing, bundlecaps)
# apply changegroup to remote
if unbundle:
# local repo finds heads on server, finds out what
# revs it must push. once revs transferred, if server
@@ -141,11 +156,11 @@ def push(repo, remote, force=False, revs
# 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())
+ ret = remote.addchangegroup(cg, 'push', pushop.repo.url())
if ret:
# push succeed, synchronize target of the push
cheads = outgoing.missingheads
elif revs is None:
@@ -165,21 +180,21 @@ def push(repo, remote, force=False, revs
# missing = ((commonheads::missingheads) - commonheads)
#
# We can pick:
# * missingheads part of common (::commonheads)
common = set(outgoing.common)
- nm = repo.changelog.nodemap
+ nm = pushop.repo.changelog.nodemap
cheads = [node for node in revs if nm[node] in common]
# and
# * commonheads parents on missing
revset = unfi.set('%ln and parents(roots(%ln))',
outgoing.commonheads,
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)
+ if (pushop.repo.ui.configbool('ui', '_usedassubrepo', False)
and remotephases # server supports phases
and ret is None # nothing was pushed
and remotephases.get('publishing', False)):
# When:
# - this is a subrepo push
@@ -193,11 +208,12 @@ def push(repo, remote, force=False, revs
remotephases = {'publishing': 'True'}
if not remotephases: # old server or public only repo
localphasemove(cheads)
# don't push any phase data as there is nothing to push
else:
- ana = phases.analyzeremotephases(repo, cheads, remotephases)
+ ana = phases.analyzeremotephases(pushop.repo, cheads,
+ remotephases)
pheads, droots = ana
### Apply remote phase on local
if remotephases.get('publishing', False):
localphasemove(cheads)
else: # publish = False
@@ -214,18 +230,18 @@ def push(repo, remote, force=False, revs
r = remote.pushkey('phases',
newremotehead.hex(),
str(phases.draft),
str(phases.public))
if not r:
- repo.ui.warn(_('updating %s to public failed!\n')
+ pushop.repo.ui.warn(_('updating %s to public failed!\n')
% newremotehead)
- repo.ui.debug('try to push obsolete markers to remote\n')
- obsolete.syncpush(repo, remote)
+ pushop.repo.ui.debug('try to push obsolete markers to remote\n')
+ obsolete.syncpush(pushop.repo, remote)
finally:
if lock is not None:
lock.release()
finally:
if locallock is not None:
locallock.release()
- bookmarks.updateremote(repo.ui, unfi, remote, revs)
+ bookmarks.updateremote(pushop.repo.ui, unfi, remote, revs)
return ret
More information about the Mercurial-devel
mailing list