[patch 10/10] Add an optional map of specific revisions for changegroup to include

Chris Mason mason at suse.com
Tue Aug 9 12:43:03 CDT 2005


# HG changeset patch
# User mason at suse.com

Add an optional map of specific revisions for changegroup to include

The default logic in changegroup simply finds all newer revisions than
each of the basenodes passed in.  When trying to create a changegroup
with only specific revs, changegroup needs to know exactly which
revisions to include.

Also, it is possible for a specific file revision to be linked to more
than one changeset.  The default logic might not include some file
revisions because they are actually linked into an older changeset.

This patch sends a revision map to changegroup, the revision map is a
hash of filenames containing a hash of changeset revisions:

revmap['filename'][changeset id] = filerev

revmap['filename'] is passed to the revlog.group() method so the proper
file revisions can be found for a given list of changesets.

Index: mine/mercurial/hg.py
===================================================================
--- mine.orig/mercurial/hg.py	2005-07-29 15:06:09.000000000 -0400
+++ mine/mercurial/hg.py	2005-07-29 15:06:55.000000000 -0400
@@ -1211,7 +1211,7 @@ class localrepository:
         cg = self.changegroup(update)
         return remote.addchangegroup(cg)
 
-    def changegroup(self, basenodes):
+    def changegroup(self, basenodes, revmap=None):
         class genread:
             def __init__(self, generator):
                 self.g = generator
@@ -1229,7 +1229,10 @@ class localrepository:
                 return d
 
         def gengroup():
-            nodes = self.newer(basenodes)
+            if not revmap:
+                nodes = self.newer(basenodes)
+            else:
+                nodes = basenodes
 
             # construct the link map
             linkmap = {}
@@ -1249,10 +1252,19 @@ class localrepository:
             revs = [ self.changelog.rev(n) for n in nodes ]
 
             for y in self.changelog.group(linkmap): yield y
-            for y in self.manifest.group(linkmap): yield y
+            if revmap:
+                m = revmap['.hg/00manifest']
+                for y in self.manifest.group(linkmap, m): yield y
+            else:
+                for y in self.manifest.group(linkmap): yield y
             for f in changed:
+                m = None
+                if revmap:
+                    if f not in revmap:
+                        continue
+                    m = revmap[f]
                 yield struct.pack(">l", len(f) + 4) + f
-                g = self.file(f).group(linkmap)
+                g = self.file(f).group(linkmap, m)
                 for y in g:
                     yield y
 
Index: mine/mercurial/revlog.py
===================================================================
--- mine.orig/mercurial/revlog.py	2005-07-29 15:06:55.000000000 -0400
+++ mine/mercurial/revlog.py	2005-07-29 15:06:55.000000000 -0400
@@ -392,7 +392,7 @@ class revlog:
             elif lx > ly:
                 lx = x.next()
 
-    def group(self, linkmap):
+    def group(self, linkmap, map=None):
         # given a list of changeset revs, return a set of deltas and
         # metadata corresponding to nodes. the first delta is
         # parent(nodes[0]) -> nodes[0] the receiver is guaranteed to
@@ -401,12 +401,26 @@ class revlog:
 
         revs = []
         needed = {}
+        rev2ch = {}
 
-        # find file nodes/revs that match changeset revs
-        for i in xrange(0, self.count()):
-            if self.index[i][3] in linkmap:
-                revs.append(i)
-                needed[i] = 1
+        if map:
+            for l in linkmap:
+                c = linkmap[l] 
+                if c not in map:
+                    continue
+                r = map[c]
+                n = self.rev(r)
+                if n not in needed:
+                    needed[n] = 1
+                    revs.append(n)
+                    rev2ch[r] = c
+            revs.sort()
+        else:
+            # find file nodes/revs that match changeset revs
+            for i in xrange(0, self.count()):
+                if self.index[i][3] in linkmap:
+                    revs.append(i)
+                    needed[i] = 1
 
         # if we don't have any revisions touched by these changesets, bail
         if not revs:
@@ -495,7 +509,10 @@ class revlog:
                 d = chunks[b]
 
             p = self.parents(n)
-            meta = n + p[0] + p[1] + linkmap[self.linkrev(n)]
+            if map:
+                meta = n + p[0] + p[1] + rev2ch[n]
+            else:
+                meta = n + p[0] + p[1] + linkmap[self.linkrev(n)]
             l = struct.pack(">l", len(meta) + len(d) + 4)
             yield l
             yield meta

--


More information about the Mercurial mailing list