[PATCH] Make convert-repo put tags on the branches where they apply

Brendan Cully brendan at kublai.com
Mon Feb 26 15:08:16 CST 2007


# HG changeset patch
# User Brendan Cully <brendan at kublai.com>
# Date 1172523968 28800
# Node ID ad1458bedd2f2866121af09d3c0c2be69d8113a0
# Parent  eb0967c6e77b66a1096584c882725cb779caf90f
Make convert-repo put tags on the branches where they apply

diff -r eb0967c6e77b -r ad1458bedd2f contrib/convert-repo
--- a/contrib/convert-repo	Mon Feb 26 21:57:33 2007 +0100
+++ b/contrib/convert-repo	Mon Feb 26 13:06:08 2007 -0800
@@ -25,6 +25,7 @@
 
 import sys, os, zlib, sha, time, re, locale, socket
 os.environ["HGENCODING"] = "utf-8"
+sys.path.insert(0, '/home/brendan/dev/hg/crew')
 from mercurial import hg, ui, util, fancyopts
 
 class Abort(Exception): pass
@@ -32,6 +33,7 @@ class NoRepo(Exception): pass
 
 class commit:
     def __init__(self, **parts):
+        self.branch = None
         for x in "author date desc parents".split():
             if not x in parts:
                 abort("commit missing field %s\n" % x)
@@ -417,10 +419,8 @@ class convert_mercurial:
 
         text = commit.desc
         extra = {}
-        try:
+        if commit.branch is not None:
             extra["branch"] = commit.branch
-        except AttributeError:
-            pass
 
         while parents:
             p1 = p2
@@ -432,10 +432,11 @@ class convert_mercurial:
 
         return p2
 
-    def puttags(self, tags):
-        try:
-            old = self.repo.wfile(".hgtags").read()
-            oldlines = old.splitlines(1)
+    def puttags(self, tags, rev, branch):
+        rev = hg.bin(rev)
+        try:
+            old = self.repo.filectx(".hgtags", rev)
+            oldlines = old.data().splitlines(1)
             oldlines.sort()
         except:
             oldlines = []
@@ -455,8 +456,11 @@ class convert_mercurial:
             f.close()
             if not oldlines: self.repo.add([".hgtags"])
             date = "%s 0" % int(time.mktime(time.gmtime()))
+            extra = {}
+            if branch:
+                extra['branch'] = branch
             self.repo.rawcommit([".hgtags"], "update tags", "convert-repo",
-                                date, self.repo.changelog.tip(), hg.nullid)
+                                date, rev, hg.nullid, extra=extra)
             return hg.hex(self.repo.changelog.tip())
 
 converters = [convert_cvs, convert_git, convert_mercurial]
@@ -560,6 +564,26 @@ class convert:
 
         return s
 
+    def ancestors(self, rev):
+        visit = [rev]
+        seen = {rev: 1}
+        while visit:
+            n = visit.pop(0)
+            for p in self.commitcache[n].parents:
+                if p not in seen:
+                    visit.append(p)
+                    seen[p] = 1
+        return seen.keys()
+            
+    def branchtags(self, tags, rev):
+        'Find tags for already-committed nodes on the same branch as rev'
+        ctags = {}
+        parents = self.ancestors(rev)
+        for name, tagrev in tags.iteritems():
+            if tagrev in self.map and tagrev in parents:
+                ctags[name] = self.map[tagrev]
+        return ctags
+
     def copy(self, rev):
         c = self.commitcache[rev]
         files = self.source.getchanges(rev)
@@ -588,6 +612,7 @@ class convert:
         c = None
 
         status("converting...\n")
+        tags = self.source.gettags()
         for c in t:
             num -= 1
             desc = self.commitcache[c].desc
@@ -595,20 +620,14 @@ class convert:
                 desc = desc.splitlines()[0]
             status("%d %s\n" % (num, desc))
             self.copy(c)
-
-        tags = self.source.gettags()
-        ctags = {}
-        for k in tags:
-            v = tags[k]
-            if v in self.map:
-                ctags[k] = self.map[v]
-
-        if c and ctags:
-            nrev = self.dest.puttags(ctags)
-            # write another hash correspondence to override the previous
-            # one so we don't end up with extra tag heads
-            if nrev:
-                file(self.mapfile, "a").write("%s %s\n" % (c, nrev))
+            if c in tags.values():
+                tbranch = self.commitcache[c].branch
+                nrev = self.dest.puttags(self.branchtags(tags, c), self.map[c], tbranch)
+                # write another hash correspondence to override the previous
+                # one so we don't end up with extra tag heads
+                if nrev:
+                    self.map[c] = nrev
+                    file(self.mapfile, "a").write("%s %s\n" % (c, nrev))
 
 def command(src, dest=None, mapfile=None, **opts):
     srcc = converter(src)


More information about the Mercurial-devel mailing list