Patchwork [2,of,9,(38,total)] push: introduce a pushoperation object

login
register
mail settings
Submitter Pierre-Yves David
Date Feb. 2, 2014, 1:32 a.m.
Message ID <70e5daae7c52156584ee.1391304778@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/3427/
State Accepted
Commit 42df1fe32552634c5a3ba0b7a82897d3f5691f1f
Headers show

Comments

Pierre-Yves David - Feb. 2, 2014, 1:32 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@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.

Patch

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