changeset 42:71f1e5ed6213

Convert "lightweight" tags, since that's how cvs2git handle CVS tags. - add lightweight_tags attr to HgImportProcessor - modify reset_handler() to detect and record lightweight tags - add write_lightweight_tags() method to add them all in one commit - update test-fastimport-cvs2git-fixup
author Greg Ward <greg-hg@gerg.ca>
date Sun, 10 May 2009 12:00:23 -0400
parents a1ccf1817b65
children 000d4174071c
files hgfastimport/hgimport.py tests/test-fastimport-cvs2git-fixup tests/test-fastimport-cvs2git-fixup.out
diffstat 3 files changed, 97 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/hgfastimport/hgimport.py	Sun May 10 10:27:18 2009 -0400
+++ b/hgfastimport/hgimport.py	Sun May 10 12:00:23 2009 -0400
@@ -28,7 +28,7 @@
 import mercurial.hg
 import mercurial.commands
 from mercurial import util
-from mercurial.node import nullrev
+from mercurial.node import nullrev, hex
 
 from fastimport import processor
 from hgfastimport import hgechoprocessor
@@ -36,12 +36,14 @@
 class HgImportProcessor(processor.ImportProcessor):
     
     def __init__(self, ui, repo, **opts):
+        super(HgImportProcessor, self).__init__()
         self.ui = ui
         self.repo = repo
         self.opts = opts
         self.last_commit = None         # CommitCommand object
-        self.mark_map = {}              # map mark (e.g. ":1") to changelog node ID(?)
-        self.branch_map = {}            # map git branch name to changelog node ID(?)
+        self.mark_map = {}              # map mark (e.g. ":1") to revision number
+        self.branch_map = {}            # map git branch name to revision number
+        self.lightweight_tags = []      # list of (ref, mark) tuples
 
         self.numblobs = 0               # for progress reporting
         self.blobdir = None
@@ -52,6 +54,13 @@
 
     def teardown(self):
         """Cleanup after processing all streams."""
+        # Hmmm: this isn't really a cleanup step, it's a post-processing
+        # step.  But we currently have one processor per input
+        # stream... despite the fact that state like mark_map,
+        # branch_map, and lightweight_tags really should span input
+        # streams.
+        self.write_lightweight_tags()
+
         if self.blobdir and os.path.exists(self.blobdir):
             self.ui.status("Removing blob dir %r ...\n" % self.blobdir)
             shutil.rmtree(self.blobdir)
@@ -180,12 +189,51 @@
         return "%d %d" % res
         
     def reset_handler(self, cmd):
-        if cmd.from_ is not None:
-            self.branch_map[cmd.ref] = self.committish_rev(cmd.from_)
+        if cmd.ref.startswith("refs/heads/"):
+            # The usual case for 'reset': (re)create the named branch.
+            # 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:
+            #    # XXX filename? line number?
+            #    self.ui.warn("ignoring branch reset with no 'from'\n")
+        elif cmd.ref.startswith("refs/tags/"):
+            # Create a "lightweight tag" in Git terms.  As I understand
+            # it, that's a tag with no description and no history --
+            # rather like CVS tags.  cvs2git turns CVS tags into Git
+            # lightweight tags, so we should make sure they become
+            # Mercurial tags.  But we don't have to fake a history for
+            # them; save them up for the end.
+            self.lightweight_tags.append((cmd.ref, cmd.from_))
 
     def tag_handler(self, cmd):
         pass
 
+    def write_lightweight_tags(self):
+        if not self.lightweight_tags:   # avoid writing empty .hgtags
+            return
+
+        # XXX what about duplicate tags?  lightweight_tags is
+        # deliberately a list, to preserve order ... but do we need to
+        # worry about repeated tags?  (Certainly not for cvs2git output,
+        # since CVS has no tag history.)
+
+        # Create Mercurial tags from git-style "lightweight tags" in the
+        # input stream.
+        self.ui.status("updating tags\n")
+        mercurial.hg.clean(self.repo, self.repo.lookup("default"))
+        tagfile = open(self.repo.wjoin(".hgtags"), "ab")
+        for (ref, mark) in self.lightweight_tags:
+            tag = ref[len("refs/tags/"):]
+            rev = self.mark_map[mark]
+            node = self.repo.changelog.node(rev)
+            tagfile.write("%s %s\n" % (hex(node), tag))
+        tagfile.close()
+
+        files = [".hgtags"]
+        self.repo.rawcommit(
+            files=files, text="update tags", user="convert-repo", date=None)
+
 class HgImportCommitHandler(processor.CommitHandler):
 
     def __init__(self, parent, command, ui, repo, **opts):
--- a/tests/test-fastimport-cvs2git-fixup	Sun May 10 10:27:18 2009 -0400
+++ b/tests/test-fastimport-cvs2git-fixup	Sun May 10 12:00:23 2009 -0400
@@ -124,13 +124,16 @@
 
 echo "% hg glog"
 cd realcvs
-hg glog -v
+template="rev:    {rev}\nauthor: {author}\nbranch: '{branches}'  tags:   {tags}\nfiles:  {files}\ndesc:   {desc}\n\n"
+hg glog -v --template="$template"
 
 echo "% hg branches"
-hg branches
+# Exclude default since its changeset ID is different with every run.
+# (Same thing with tags and tip below.)
+hg branches | grep -v "^default"
 
 echo "% hg heads -v"
-hg heads
+hg heads --template="$template"
 
 echo "% hg tags -v"
-hg tags
+hg tags | grep -v "^tip"
--- a/tests/test-fastimport-cvs2git-fixup.out	Sun May 10 10:27:18 2009 -0400
+++ b/tests/test-fastimport-cvs2git-fixup.out	Sun May 10 12:00:23 2009 -0400
@@ -9,60 +9,54 @@
 Done commit of rev 2
 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 Done commit of rev 3
+updating tags
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 Removing blob dir 'HGTMP/test-fastimport-cvs2git-fixup/realcvs/.hg/blobs' ...
 % hg glog
-@  changeset:   3:158529dd7d57
-|  tag:         tip
-|  parent:      0:8c270455072a
-|  user:        Other <other@example.com>
-|  date:        Mon May 27 22:01:08 2002 +0000
-|  files:       main.cpp
-|  description:
-|  added iostream.h
+@  rev:    4
+|  author: convert-repo
+|  branch: ''  tags:   tip
+|  files:  .hgtags
+|  desc:   update tags
 |
+o  rev:    3
+|  author: Other <other@example.com>
+|  branch: ''  tags:
+|  files:  main.cpp
+|  desc:   added iostream.h
 |
-| o  changeset:   2:9c706dffba0e
-| |  branch:      REL-2-2-3
-| |  user:        cvs2git <cvs2git>
-| |  date:        Mon May 27 21:04:55 2002 +0000
-| |  files:       Tools/Debug/C++/DebugCpp.doxygen
-| |  description:
-| |  create tag 'REL-2-2-3-P1' (manufactured commit)
-| |
+| o  rev:    2
+| |  author: cvs2git <cvs2git>
+| |  branch: 'REL-2-2-3'  tags:   REL-2-2-3-P1
+| |  files:  Tools/Debug/C++/DebugCpp.doxygen
+| |  desc:   create tag 'REL-2-2-3-P1' (manufactured commit)
 | |
-| o  changeset:   1:fd354e4cf420
-|/   branch:      REL-2-2-3
-|    user:        cvs2git <cvs2git>
-|    date:        Mon May 27 21:04:54 2002 +0000
-|    description:
-|    create branch 'REL-2-2-3' (manufactured commit)
-|
+| o  rev:    1
+|/   author: cvs2git <cvs2git>
+|    branch: 'REL-2-2-3'  tags:
+|    files:
+|    desc:   create branch 'REL-2-2-3' (manufactured commit)
 |
-o  changeset:   0:8c270455072a
-   user:        Example <example>
-   date:        Wed Jun 06 02:06:20 2001 +0000
-   files:       Makefile
-   description:
-   added Makefile
-
+o  rev:    0
+   author: Example <example>
+   branch: ''  tags:
+   files:  Makefile
+   desc:   added Makefile
 
 % hg branches
-default                        3:158529dd7d57
 REL-2-2-3                      2:9c706dffba0e
 % hg heads -v
-changeset:   3:158529dd7d57
-tag:         tip
-parent:      0:8c270455072a
-user:        Other <other@example.com>
-date:        Mon May 27 22:01:08 2002 +0000
-summary:     added iostream.h
+rev:    4
+author: convert-repo
+branch: ''  tags:   tip
+files:  .hgtags
+desc:   update tags
 
-changeset:   2:9c706dffba0e
-branch:      REL-2-2-3
-user:        cvs2git <cvs2git>
-date:        Mon May 27 21:04:55 2002 +0000
-summary:     create tag 'REL-2-2-3-P1' (manufactured commit)
+rev:    2
+author: cvs2git <cvs2git>
+branch: 'REL-2-2-3'  tags:   REL-2-2-3-P1
+files:  Tools/Debug/C++/DebugCpp.doxygen
+desc:   create tag 'REL-2-2-3-P1' (manufactured commit)
 
 % hg tags -v
-tip                                3:158529dd7d57
 REL-2-2-3-P1                       2:9c706dffba0e