changeset 20469:6b4c789d618d

exchange: extract pull function from localrepo The localrepo class if far too big. Push and pull logic are extracted and reworked to better fit with the fact we exchange more than bundle now. This changeset extract the pulh code. later changeset will slowly slice it into smaller brick. The localrepo.pull method is kept for now to limit impact on user code. But it will be ultimately removed, now that the public API is hold by peer.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Thu, 30 Jan 2014 16:12:49 -0800
parents 7d0bbb6dd730
children 78f4c2b7052f
files mercurial/exchange.py mercurial/localrepo.py
diffstat 2 files changed, 88 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/exchange.py	Thu Jan 30 23:12:03 2014 -0800
+++ b/mercurial/exchange.py	Thu Jan 30 16:12:49 2014 -0800
@@ -6,7 +6,7 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-from node import hex
+from node import hex, nullid
 import errno
 import util, scmutil, changegroup
 import discovery, phases, obsolete, bookmarks
@@ -372,3 +372,89 @@
             ui.status(_("updating bookmark %s\n") % b)
         else:
             ui.warn(_('updating bookmark %s failed!\n') % b)
+
+
+def pull(repo, remote, heads=None, force=False):
+    if remote.local():
+        missing = set(remote.requirements) - repo.supported
+        if missing:
+            msg = _("required features are not"
+                    " supported in the destination:"
+                    " %s") % (', '.join(sorted(missing)))
+            raise util.Abort(msg)
+
+    # don't open transaction for nothing or you break future useful
+    # rollback call
+    tr = None
+    trname = 'pull\n' + util.hidepassword(remote.url())
+    lock = repo.lock()
+    try:
+        tmp = discovery.findcommonincoming(repo.unfiltered(), remote,
+                                           heads=heads, force=force)
+        common, fetch, rheads = tmp
+        if not fetch:
+            repo.ui.status(_("no changes found\n"))
+            result = 0
+        else:
+            tr = repo.transaction(trname)
+            if heads is None and list(common) == [nullid]:
+                repo.ui.status(_("requesting all changes\n"))
+            elif heads is None and remote.capable('changegroupsubset'):
+                # issue1320, avoid a race if remote changed after discovery
+                heads = rheads
+
+            if remote.capable('getbundle'):
+                # TODO: get bundlecaps from remote
+                cg = remote.getbundle('pull', common=common,
+                                      heads=heads or rheads)
+            elif heads is None:
+                cg = remote.changegroup(fetch, 'pull')
+            elif not remote.capable('changegroupsubset'):
+                raise util.Abort(_("partial pull cannot be done because "
+                                       "other repository doesn't support "
+                                       "changegroupsubset."))
+            else:
+                cg = remote.changegroupsubset(fetch, heads, 'pull')
+            result = repo.addchangegroup(cg, 'pull', remote.url())
+
+        # compute target subset
+        if heads is None:
+            # We pulled every thing possible
+            # sync on everything common
+            subset = common + rheads
+        else:
+            # We pulled a specific subset
+            # sync on this subset
+            subset = heads
+
+        # Get remote phases data from remote
+        remotephases = remote.listkeys('phases')
+        publishing = bool(remotephases.get('publishing', False))
+        if remotephases and not publishing:
+            # remote is new and unpublishing
+            pheads, _dr = phases.analyzeremotephases(repo, subset,
+                                                     remotephases)
+            phases.advanceboundary(repo, phases.public, pheads)
+            phases.advanceboundary(repo, phases.draft, subset)
+        else:
+            # Remote is old or publishing all common changesets
+            # should be seen as public
+            phases.advanceboundary(repo, phases.public, subset)
+
+        def gettransaction():
+            if tr is None:
+                return repo.transaction(trname)
+            return tr
+
+        obstr = obsolete.syncpull(repo, remote, gettransaction)
+        if obstr is not None:
+            tr = obstr
+
+        if tr is not None:
+            tr.close()
+    finally:
+        if tr is not None:
+            tr.release()
+        lock.release()
+
+    return result
--- a/mercurial/localrepo.py	Thu Jan 30 23:12:03 2014 -0800
+++ b/mercurial/localrepo.py	Thu Jan 30 16:12:49 2014 -0800
@@ -1659,89 +1659,7 @@
         return r
 
     def pull(self, remote, heads=None, force=False):
-        if remote.local():
-            missing = set(remote.requirements) - self.supported
-            if missing:
-                msg = _("required features are not"
-                        " supported in the destination:"
-                        " %s") % (', '.join(sorted(missing)))
-                raise util.Abort(msg)
-
-        # don't open transaction for nothing or you break future useful
-        # rollback call
-        tr = None
-        trname = 'pull\n' + util.hidepassword(remote.url())
-        lock = self.lock()
-        try:
-            tmp = discovery.findcommonincoming(self.unfiltered(), remote,
-                                               heads=heads, force=force)
-            common, fetch, rheads = tmp
-            if not fetch:
-                self.ui.status(_("no changes found\n"))
-                result = 0
-            else:
-                tr = self.transaction(trname)
-                if heads is None and list(common) == [nullid]:
-                    self.ui.status(_("requesting all changes\n"))
-                elif heads is None and remote.capable('changegroupsubset'):
-                    # issue1320, avoid a race if remote changed after discovery
-                    heads = rheads
-
-                if remote.capable('getbundle'):
-                    # TODO: get bundlecaps from remote
-                    cg = remote.getbundle('pull', common=common,
-                                          heads=heads or rheads)
-                elif heads is None:
-                    cg = remote.changegroup(fetch, 'pull')
-                elif not remote.capable('changegroupsubset'):
-                    raise util.Abort(_("partial pull cannot be done because "
-                                           "other repository doesn't support "
-                                           "changegroupsubset."))
-                else:
-                    cg = remote.changegroupsubset(fetch, heads, 'pull')
-                result = self.addchangegroup(cg, 'pull', remote.url())
-
-            # compute target subset
-            if heads is None:
-                # We pulled every thing possible
-                # sync on everything common
-                subset = common + rheads
-            else:
-                # We pulled a specific subset
-                # sync on this subset
-                subset = heads
-
-            # Get remote phases data from remote
-            remotephases = remote.listkeys('phases')
-            publishing = bool(remotephases.get('publishing', False))
-            if remotephases and not publishing:
-                # remote is new and unpublishing
-                pheads, _dr = phases.analyzeremotephases(self, subset,
-                                                         remotephases)
-                phases.advanceboundary(self, phases.public, pheads)
-                phases.advanceboundary(self, phases.draft, subset)
-            else:
-                # Remote is old or publishing all common changesets
-                # should be seen as public
-                phases.advanceboundary(self, phases.public, subset)
-
-            def gettransaction():
-                if tr is None:
-                    return self.transaction(trname)
-                return tr
-
-            obstr = obsolete.syncpull(self, remote, gettransaction)
-            if obstr is not None:
-                tr = obstr
-
-            if tr is not None:
-                tr.close()
-        finally:
-            if tr is not None:
-                tr.release()
-            lock.release()
-
-        return result
+        return exchange.pull (self, remote, heads, force)
 
     def checkpush(self, force, revs):
         """Extensions can override this function if additional checks have