[PATCH 2 of 3] convert: fix history topology when using hg.tagsbranch

Edouard Gomez ed.gomez at free.fr
Sat Aug 15 12:55:05 CDT 2009

# HG changeset patch
# User Edouard Gomez <ed.gomez at free.fr>
# Date 1250357378 -7200
# Node ID 8364ac5a9ef0137ed138594db5ae214c6549e02d
# Parent  d16f1dfd1cf389767394b46e45985eecc07a480e
convert: fix history topology when using hg.tagsbranch

When using hg.tagsbranch, all conversions fail at
transcribing the source repo topology with conversion
scenarios interleaving:
 - initial repo conversion,
 - then upstream tag
 - then later incremental conversion

The problem is caused by the usage of the last source
revid as source revid for the tagnode in the revision

On a later incremental conversion, when resolving some
child commit of the true last source revid, convert
will parent the nodes to the tag node. If using
tagsbranch you get a bad topology where all incremental
commit nodes end up in the tag branch.

This patch addresses the problem using a fake id
provided by the source class which is used for all
tagnodes when using hg.tagsbranch. That way no regular
commits will ever happen in the tag branch.

diff --git a/hgext/convert/common.py b/hgext/convert/common.py
--- a/hgext/convert/common.py
+++ b/hgext/convert/common.py
@@ -154,6 +154,19 @@
         return None
+    def gettagsnodename(self):
+        """Return a source node name that can be used to track 'tagsbranch'
+        head.
+        The default implementation returns '0'
+        If '0' is not valid for the source format, override the function so
+        that it returns a revid that fullfil the following conditions:
+          - it must be parseable by the revmap parser as source revid
+          - it must not match a possible source revid
+        """
+        return '0'
 class converter_sink(object):
     """Conversion sink (target) interface"""
diff --git a/hgext/convert/convcmd.py b/hgext/convert/convcmd.py
--- a/hgext/convert/convcmd.py
+++ b/hgext/convert/convcmd.py
@@ -340,7 +340,11 @@
                 # 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
+                    if isinstance(self.dest, mercurial_sink) and self.dest.tagsbranch != 'default':
+                        tagsnodename = self.source.gettagsnodename()
+                    else:
+                        tagsnodename = c
+                    self.map[tagsnodename] = nrev
diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
--- a/hgext/convert/subversion.py
+++ b/hgext/convert/subversion.py
@@ -510,6 +510,9 @@
     def revid(self, revnum, module=None):
         return 'svn:%s%s@%s' % (self.uuid, module or self.module, revnum)
+    def gettagsnodename(self):
+        return self.revid(0)
     def revnum(self, rev):
         return int(rev.split('@')[-1])

More information about the Mercurial-devel mailing list