[PATCH 02 of 16] exchangeutil: extract pull function from localrepo
pierre-yves.david at logilab.fr
pierre-yves.david at logilab.fr
Wed Apr 17 15:58:37 UTC 2013
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1366194524 -7200
# Wed Apr 17 12:28:44 2013 +0200
# Node ID 4f01e4913967eb0961f07f7d77e026dbac5a439c
# Parent 8c78d95ab62f3edc06871132a1011109d3b2c3ce
exchangeutil: extract pull function from localrepo
The `localrepo` class if far too big. Push and pull logic will be extracted and
reworked to better fit with the fact we exchange more than bundle now.
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.
diff --git a/mercurial/exchangeutil.py b/mercurial/exchangeutil.py
--- a/mercurial/exchangeutil.py
+++ b/mercurial/exchangeutil.py
@@ -4,12 +4,12 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from i18n import _
-from node import hex
-import util, scmutil
+from node import hex, nullid
+import util, scmutil, base85
import discovery, phases, obsolete, bookmarks
def push(repo, remote, force=False, revs=None, newbranch=False):
'''Push outgoing changesets (limited by revs) from the current
@@ -210,5 +210,91 @@ def push(repo, remote, force=False, revs
else:
repo.ui.warn(_('updating bookmark %s'
' failed!\n') % k)
return ret
+
+def pull(repo, remote, heads=None, force=False):
+ # 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, remote, heads=heads,
+ force=force)
+ common, fetch, rheads = tmp
+ if not fetch:
+ repo.ui.status(_("no changes found\n"))
+ added = []
+ 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'):
+ 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')
+ # we use unfiltered changelog here because hidden revision must
+ # be taken in account for phase synchronization. They may
+ # becomes public and becomes visible again.
+ cl = repo.unfiltered().changelog
+ clstart = len(cl)
+ result = repo.addchangegroup(cg, 'pull', remote.url())
+ clend = len(cl)
+ added = [cl.node(r) for r in xrange(clstart, clend)]
+
+ # compute target subset
+ if heads is None:
+ # We pulled every thing possible
+ # sync on everything common
+ subset = common + added
+ 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)
+
+ if obsolete._enabled:
+ repo.ui.debug('fetching remote obsolete markers\n')
+ remoteobs = remote.listkeys('obsolete')
+ if 'dump0' in remoteobs:
+ if tr is None:
+ tr = repo.transaction(trname)
+ for key in sorted(remoteobs, reverse=True):
+ if key.startswith('dump'):
+ data = base85.b85decode(remoteobs[key])
+ repo.obsstore.mergemarkers(tr, data)
+ repo.invalidatevolatilesets()
+ if tr is not None:
+ tr.close()
+ finally:
+ if tr is not None:
+ tr.release()
+ lock.release()
+
+ return result
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -6,11 +6,11 @@
# GNU General Public License version 2 or any later version.
from node import hex, nullid, short
from i18n import _
import peer, changegroup, subrepo, discovery, pushkey, obsolete, repoview
import changelog, dirstate, filelog, manifest, context, bookmarks, phases
-import lock, transaction, store, encoding, base85, exchangeutil
+import lock, transaction, store, encoding, exchangeutil
import scmutil, util, extensions, hook, error, revset
import match as matchmod
import merge as mergemod
import tags as tagsmod
from lock import release
@@ -1650,94 +1650,11 @@ class localrepository(object):
r.append(l)
return r
def pull(self, remote, heads=None, force=False):
- # 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, remote, heads=heads,
- force=force)
- common, fetch, rheads = tmp
- if not fetch:
- self.ui.status(_("no changes found\n"))
- added = []
- 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'):
- 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')
- # we use unfiltered changelog here because hidden revision must
- # be taken in account for phase synchronization. They may
- # becomes public and becomes visible again.
- cl = self.unfiltered().changelog
- clstart = len(cl)
- result = self.addchangegroup(cg, 'pull', remote.url())
- clend = len(cl)
- added = [cl.node(r) for r in xrange(clstart, clend)]
-
- # compute target subset
- if heads is None:
- # We pulled every thing possible
- # sync on everything common
- subset = common + added
- 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)
-
- if obsolete._enabled:
- self.ui.debug('fetching remote obsolete markers\n')
- remoteobs = remote.listkeys('obsolete')
- if 'dump0' in remoteobs:
- if tr is None:
- tr = self.transaction(trname)
- for key in sorted(remoteobs, reverse=True):
- if key.startswith('dump'):
- data = base85.b85decode(remoteobs[key])
- self.obsstore.mergemarkers(tr, data)
- self.invalidatevolatilesets()
- if tr is not None:
- tr.close()
- finally:
- if tr is not None:
- tr.release()
- lock.release()
-
- return result
+ return exchangeutil.pull (self, remote, heads, force)
def checkpush(self, force, revs):
"""Extensions can override this function if additional checks have
to be performed before pushing, or call it if they override push
command.
More information about the Mercurial-devel
mailing list