# HG changeset patch # User Matt Mackall # Date 2011-03-31 20:24:06 # Node ID d69c9510d648321a30af673cbb113972e74fa284 # Parent 2dc6e09f2a7ddeb990617824c6a1855a0ff44910 changegroup: introduce bundler objects This makes the bundler pluggable at lower levels. diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -194,3 +194,18 @@ def readbundle(fh, fname): if version != '10': raise util.Abort(_('%s: unknown bundle version %s') % (fname, version)) return unbundle10(fh, alg) + +class bundle10(object): + def __init__(self, lookup): + self._lookup = lookup + def close(self): + return closechunk() + def fileheader(self, fname): + return chunkheader(len(fname)) + fname + def revchunk(self, revlog, node='', p1='', p2='', prefix='', data=''): + linknode = self._lookup(revlog, node) + meta = node + p1 + p2 + linknode + prefix + l = len(meta) + len(data) + yield chunkheader(l) + yield meta + yield data diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1521,19 +1521,19 @@ class localrepository(repo.repository): unit=_('files'), total=len(changedfiles)) return fstate[1][x] - # Now that we have all theses utility functions to help out and - # logically divide up the task, generate the group. + bundler = changegroup.bundle10(lookup) + def gengroup(): # Create a changenode group generator that will call our functions # back to lookup the owning changenode and collect information. - for chunk in cl.group(csets, lookup): + for chunk in cl.group(csets, bundler): yield chunk self.ui.progress(_('bundling'), None) # Create a generator for the manifestnodes that calls our lookup # and data collection functions back. count[0] = 0 - for chunk in mf.group(prune(mf, mfs), lookup): + for chunk in mf.group(prune(mf, mfs), bundler): yield chunk self.ui.progress(_('bundling'), None) @@ -1550,17 +1550,16 @@ class localrepository(repo.repository): first = True for chunk in filerevlog.group(prune(filerevlog, fstate[1]), - lookup): + bundler): if first: - if chunk == changegroup.closechunk(): + if chunk == bundler.close(): break count[0] += 1 - yield changegroup.chunkheader(len(fname)) - yield fname + yield bundler.fileheader(fname) first = False yield chunk # Signal that no more groups are left. - yield changegroup.closechunk() + yield bundler.close() self.ui.progress(_('bundling'), None) if csets: @@ -1618,16 +1617,18 @@ class localrepository(repo.repository): total=len(changedfiles), unit=_('files')) return cl.node(revlog.linkrev(revlog.rev(x))) + bundler = changegroup.bundle10(lookup) + def gengroup(): '''yield a sequence of changegroup chunks (strings)''' # construct a list of all changed files - for chunk in cl.group(nodes, lookup): + for chunk in cl.group(nodes, bundler): yield chunk self.ui.progress(_('bundling'), None) count[0] = 0 - for chunk in mf.group(gennodelst(mf), lookup): + for chunk in mf.group(gennodelst(mf), bundler): yield chunk self.ui.progress(_('bundling'), None) @@ -1638,16 +1639,15 @@ class localrepository(repo.repository): raise util.Abort(_("empty or missing revlog for %s") % fname) fstate[0] = fname first = True - for chunk in filerevlog.group(gennodelst(filerevlog), lookup): + for chunk in filerevlog.group(gennodelst(filerevlog), bundler): if first: - if chunk == changegroup.closechunk(): + if chunk == bundler.close(): break count[0] += 1 - yield changegroup.chunkheader(len(fname)) - yield fname + yield bundler.fileheader(fname) first = False yield chunk - yield changegroup.closechunk() + yield bundler.close() self.ui.progress(_('bundling'), None) if nodes: diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -1058,7 +1058,7 @@ class revlog(object): self._cache = (node, curr, text) return node - def group(self, nodelist, lookup): + def group(self, nodelist, bundler): """Calculate a delta group, yielding a sequence of changegroup chunks (strings). @@ -1074,7 +1074,7 @@ class revlog(object): # if we don't have any revisions touched by these changesets, bail if not revs: - yield changegroup.closechunk() + yield bundler.close() return # add the parent of the first rev @@ -1085,19 +1085,18 @@ class revlog(object): for r in xrange(len(revs) - 1): a, b = revs[r], revs[r + 1] nb = self.node(b) + p1, p2 = self.parents(nb) + prefix = '' - p = self.parents(nb) - meta = nb + p[0] + p[1] + lookup(self, nb) if a == nullrev: d = self.revision(nb) - meta += mdiff.trivialdiffheader(len(d)) + prefix = mdiff.trivialdiffheader(len(d)) else: d = self.revdiff(a, b) - yield changegroup.chunkheader(len(meta) + len(d)) - yield meta - yield d + for c in bundler.revchunk(self, nb, p1, p2, prefix, d): + yield c - yield changegroup.closechunk() + yield bundler.close() def addgroup(self, bundle, linkmapper, transaction): """