From patchwork Wed Apr 2 17:59:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [4, of, 5, (4, more, to, go)] localrepo: move the changegroupsubset method in changegroup module From: Pierre-Yves David X-Patchwork-Id: 4197 Message-Id: To: mercurial-devel@selenic.com Cc: pierre-yves.david@ens-lyon.org Date: Wed, 02 Apr 2014 10:59:05 -0700 # HG changeset patch # User Pierre-Yves David # Date 1396387503 25200 # Tue Apr 01 14:25:03 2014 -0700 # Node ID af6d0a35ce48ff09960e92c41a58c93730ddf00f # Parent b5bc4afcee8a99dc6c5480c293a9557ca4234ca6 localrepo: move the changegroupsubset method in changegroup module This is a gratuitous code move aimed at reducing the localrepo bloatness. The method had few callers, not enough to be kept in local repo. The peer API remains unchanged. diff --git a/hgext/shelve.py b/hgext/shelve.py --- a/hgext/shelve.py +++ b/hgext/shelve.py @@ -23,11 +23,11 @@ shelve". from mercurial.i18n import _ from mercurial.node import nullid, nullrev, bin, hex from mercurial import changegroup, cmdutil, scmutil, phases, commands from mercurial import error, hg, mdiff, merge, patch, repair, util -from mercurial import templatefilters +from mercurial import templatefilters, changegroup from mercurial import lock as lockmod from hgext import rebase import errno cmdtable = {} @@ -225,11 +225,11 @@ def createcmd(ui, repo, pats, opts): fp = shelvedfile(repo, name, 'files').opener('wb') fp.write('\0'.join(shelvedfiles)) bases = list(publicancestors(repo[node])) - cg = repo.changegroupsubset(bases, [node], 'shelve') + cg = changegroup.changegroupsubset(repo, bases, [node], 'shelve') changegroup.writebundle(cg, shelvedfile(repo, name, 'hg').filename(), 'HG10UN') cmdutil.export(repo, [node], fp=shelvedfile(repo, name, 'patch').opener('wb'), opts=mdiff.diffopts(git=True)) diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -4,13 +4,14 @@ # # 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 nullrev, hex +from node import nullrev, nullid, hex import mdiff, util, dagutil import struct, os, bz2, zlib, tempfile +import discovery _BUNDLE10_DELTA_HEADER = "20s20s20s20s" def readexactly(stream, n): '''read n bytes from stream.read and abort if less was available''' @@ -452,5 +453,31 @@ def getsubset(repo, outgoing, bundler, s repo.hook('preoutgoing', throw=True, source=source) _changegroupinfo(repo, csets, source) gengroup = bundler.generate(commonrevs, csets, fastpathlinkrev, source) return unbundle10(util.chunkbuffer(gengroup), 'UN') + +def changegroupsubset(repo, roots, heads, source): + """Compute a changegroup consisting of all the nodes that are + descendants of any of the roots and ancestors of any of the heads. + Return a chunkbuffer object whose read() method will return + successive changegroup chunks. + + It is fairly complex as determining which filenodes and which + manifest nodes need to be included for the changeset to be complete + is non-trivial. + + Another wrinkle is doing the reverse, figuring out which changeset in + the changegroup a particular filenode or manifestnode belongs to. + """ + cl = repo.changelog + if not roots: + roots = [nullid] + # TODO: remove call to nodesbetween. + csets, roots, heads = cl.nodesbetween(roots, heads) + discbases = [] + for n in roots: + discbases.extend([p for p in cl.parents(n) if p != nullid]) + outgoing = discovery.outgoing(cl, discbases, heads) + bundler = bundle10(repo) + return getsubset(repo, outgoing, bundler, source) + diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -141,11 +141,11 @@ class locallegacypeer(localpeer): def changegroup(self, basenodes, source): return self._repo.changegroup(basenodes, source) def changegroupsubset(self, bases, heads, source): - return self._repo.changegroupsubset(bases, heads, source) + return changegroup.changegroupsubset(self._repo, bases, heads, source) class localrepository(object): supportedformats = set(('revlogv1', 'generaldelta')) _basesupported = supportedformats | set(('store', 'fncache', 'shared', @@ -1677,35 +1677,10 @@ class localrepository(object): pass def push(self, remote, force=False, revs=None, newbranch=False): return exchange.push(self, remote, force, revs, newbranch) - def changegroupsubset(self, roots, heads, source): - """Compute a changegroup consisting of all the nodes that are - descendants of any of the roots and ancestors of any of the heads. - Return a chunkbuffer object whose read() method will return - successive changegroup chunks. - - It is fairly complex as determining which filenodes and which - manifest nodes need to be included for the changeset to be complete - is non-trivial. - - Another wrinkle is doing the reverse, figuring out which changeset in - the changegroup a particular filenode or manifestnode belongs to. - """ - cl = self.changelog - if not roots: - roots = [nullid] - # TODO: remove call to nodesbetween. - csets, roots, heads = cl.nodesbetween(roots, heads) - discbases = [] - for n in roots: - discbases.extend([p for p in cl.parents(n) if p != nullid]) - outgoing = discovery.outgoing(cl, discbases, heads) - bundler = changegroup.bundle10(self) - return changegroup.getsubset(self, outgoing, bundler, source) - def getlocalbundle(self, source, outgoing, bundlecaps=None): """Like getbundle, but taking a discovery.outgoing as an argument. This is only implemented for local repos and reuses potentially precomputed sets in outgoing.""" @@ -1735,11 +1710,12 @@ class localrepository(object): discovery.outgoing(cl, common, heads), bundlecaps=bundlecaps) def changegroup(self, basenodes, source): # to avoid a race we use changegroupsubset() (issue1320) - return self.changegroupsubset(basenodes, self.heads(), source) + return changegroup.changegroupsubset(self, basenodes, self.heads(), + source) @unfilteredmethod def addchangegroup(self, source, srctype, url, emptyok=False): """Add the changegroup returned by source.read() to this repo. srctype is a string like 'push', 'pull', or 'unbundle'. url is diff --git a/mercurial/repair.py b/mercurial/repair.py --- a/mercurial/repair.py +++ b/mercurial/repair.py @@ -12,11 +12,11 @@ from mercurial.i18n import _ import os import errno def _bundle(repo, bases, heads, node, suffix, compress=True): """create a bundle with the specified revisions as a backup""" - cg = repo.changegroupsubset(bases, heads, 'strip') + cg = changegroup.changegroupsubset(repo, bases, heads, 'strip') backupdir = repo.join("strip-backup") if not os.path.isdir(backupdir): os.mkdir(backupdir) name = os.path.join(backupdir, "%s-%s.hg" % (short(node), suffix)) if compress: diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -455,11 +455,11 @@ def changegroup(repo, proto, roots): return streamres(proto.groupchunks(cg)) def changegroupsubset(repo, proto, bases, heads): bases = decodelist(bases) heads = decodelist(heads) - cg = repo.changegroupsubset(bases, heads, 'serve') + cg = changegroupmod.changegroupsubset(repo, bases, heads, 'serve') return streamres(proto.groupchunks(cg)) def debugwireargs(repo, proto, one, two, others): # only accept optional args from the known set opts = options('debugwireargs', ['three', 'four'], others)