changeset 44:61ff7b929cea

Handle fixup commits and branch creation as produced by cvs2git. Update test script to test real cvs2git output, not my idealized version of it.
author Greg Ward <greg-hg@gerg.ca>
date Mon, 11 May 2009 17:46:19 -0400
parents 000d4174071c
children 783890f8a6fb
files hgfastimport/hgimport.py tests/test-fastimport-cvs2git-fixup tests/test-fastimport-cvs2git-fixup.out
diffstat 3 files changed, 47 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/hgfastimport/hgimport.py	Mon May 11 13:59:20 2009 -0400
+++ b/hgfastimport/hgimport.py	Mon May 11 17:46:19 2009 -0400
@@ -109,20 +109,10 @@
         # of the fixup branch should be configurable!
         fixup = (cmd.ref == "refs/heads/TAG.FIXUP")
 
-        if fixup and self.last_commit is not None:
-            # If this is a fixup commit, pretend it is on the same
-            # branch as the previous commit.  This gives sensible
-            # behaviour for selecting the first parent and for
-            # determining the Mercurial branch name.
-            cmd.ref = self.last_commit.ref
-
         if cmd.from_:
             first_parent = self.committish_rev(cmd.from_)
         else:
             first_parent = self.branch_map.get(cmd.ref, nullrev)
-        #self.ui.write("First parent: %s\n" % first_parent)
-        # Update to the first parent
-        mercurial.hg.clean(self.repo, self.repo.lookup(first_parent))
         #self.ui.write("Bing\n")
         if cmd.merges:
             #self.ui.write("foo")
@@ -130,11 +120,38 @@
                 raise NotImplementedError("Can't handle more than two parents")
             second_parent = self.committish_rev(cmd.merges[0])
             #self.ui.write("Second parent: %s\n" % second_parent)
-            mercurial.commands.debugsetparents(self.ui, self.repo, 
-                first_parent, second_parent)
+        else:
+            second_parent = nullrev
+
+        if first_parent is nullrev and second_parent is not nullrev:
+            # First commit on a new branch that has 'merge' but no 'from':
+            # special case meaning branch starts with no files; the contents of
+            # the first commit (this one) determine the list of files at branch
+            # time.
+            first_parent = second_parent
+            second_parent = nullrev
+            no_files = True             # XXX not handled
+
+        self.ui.debug("commit %s: first_parent = %r, second_parent = %r\n"
+                      % (cmd.id, first_parent, second_parent))
+        assert ((first_parent != second_parent) or
+                (first_parent == second_parent == -1)), \
+               ("commit %s: first_parent == second parent = %r"
+                % (cmd.id, first_parent))
+
+        # Update to the first parent
+        mercurial.hg.clean(self.repo, self.repo.lookup(first_parent))
+        mercurial.commands.debugsetparents(
+            self.ui, self.repo, first_parent, second_parent)
+
         #self.ui.write("Bing\n")
         if cmd.ref == "refs/heads/master":
             branch = "default"
+        elif fixup and first_parent is not nullrev:
+            # If this is a fixup commit, pretend it happened on the same branch
+            # as its first parent.  (We don't want a Mercurial named branch
+            # called "TAG.FIXUP" in the output repository.)
+            branch = self.repo.changectx(first_parent).branch()
         else:
             branch = cmd.ref[len("refs/heads/"):]
         #self.ui.write("Branch: %s\n" % branch)
@@ -189,6 +206,12 @@
             # XXX what should we do if cmd.from_ is None?
             if cmd.from_ is not None:
                 self.branch_map[cmd.ref] = self.committish_rev(cmd.from_)
+            else:
+                # pretend the branch never existed... is this right?!?
+                try:
+                    del self.branch_map[cmd.ref]
+                except KeyError:
+                    pass
             #else:
             #    # XXX filename? line number?
             #    self.ui.warn("ignoring branch reset with no 'from'\n")
--- a/tests/test-fastimport-cvs2git-fixup	Mon May 11 13:59:20 2009 -0400
+++ b/tests/test-fastimport-cvs2git-fixup	Mon May 11 17:46:19 2009 -0400
@@ -27,18 +27,18 @@
 
 EOF
 
-# XXX this is the dump that cvs2git actually produces.  Subtle
-# bogosities:
+# This is the dump that cvs2git actually produces.  There are some
+# oddities to it:
 #  - commit 1619 has no first parent, but the "merge" directive
 #    (second parent) points to the commit that should be its first parent
 #  - commit 1620 should have 1619 as its first parent, but 1619 is
 #    set to the second parent... and there is no first parent
 #
-# I'm not using this one; I'm just recording it here to vent about
-# cvs2git.  See below for the dump that I want cvs2git to produce,
-# and the one that is correctly handled by hg-fastimport.
-#cat > git-dump.dat <<EOF
-cat > /dev/null <<EOF
+# but git-fast-import accepts it, and the spec allows it.  Therefore,
+# hg-fastimport must accept it and handle it correctly.
+
+#cat > /dev/null <<EOF
+cat > git-dump-1.dat <<EOF
 commit refs/heads/master
 mark :1000000373
 committer Example <example> 991793180 +0000
@@ -76,9 +76,9 @@
 M 100644 :11363 main.cpp
 EOF
 
-# XXX this is the dump that I think cvs2git *should* produce, not what
-# it actually does produce (hmmm)
-cat > git-dump.dat <<EOF
+# This is another way of expressing the same thing.  git-fast-import
+# treats them the same, therefore hg-fastimport should too.
+cat > git-dump-2.dat <<EOF
 commit refs/heads/master
 mark :1000000373
 committer Example <example> 991793180 +0000
@@ -119,7 +119,7 @@
 echo "% import cvs2git with branch/tag"
 set -e
 hg init realcvs
-hg -R realcvs fastimport git-blob.dat git-dump.dat \
+hg -R realcvs fastimport git-blob.dat git-dump-1.dat \
   | sed "s|$HGTMP|HGTMP|g"
 
 echo "% hg glog"
--- a/tests/test-fastimport-cvs2git-fixup.out	Mon May 11 13:59:20 2009 -0400
+++ b/tests/test-fastimport-cvs2git-fixup.out	Mon May 11 17:46:19 2009 -0400
@@ -1,6 +1,6 @@
 % import cvs2git with branch/tag
 Reading source: git-blob.dat
-Reading source: git-dump.dat
+Reading source: git-dump-1.dat
 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 Done commit of rev 0
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved