# HG changeset patch # User Pierre-Yves David # Date 1391127169 28800 # Node ID 6b4c789d618d5a9682730461ba07f370502ced09 # Parent 7d0bbb6dd73006d423c061fc4147e16135189e97 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. diff -r 7d0bbb6dd730 -r 6b4c789d618d mercurial/exchange.py --- 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 diff -r 7d0bbb6dd730 -r 6b4c789d618d mercurial/localrepo.py --- 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