# HG changeset patch # User Greg Ward # Date 1241971223 14400 # Node ID 71f1e5ed621305f17d7611914d887c9dd5395853 # Parent a1ccf1817b651e8c0a5a6b8960c0d16df1b559e4 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 diff -r a1ccf1817b65 -r 71f1e5ed6213 hgfastimport/hgimport.py --- 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): diff -r a1ccf1817b65 -r 71f1e5ed6213 tests/test-fastimport-cvs2git-fixup --- 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" diff -r a1ccf1817b65 -r 71f1e5ed6213 tests/test-fastimport-cvs2git-fixup.out --- 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 -| 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 +| branch: '' tags: +| files: main.cpp +| desc: added iostream.h | -| o changeset: 2:9c706dffba0e -| | branch: REL-2-2-3 -| | user: 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 +| | 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 -| date: Mon May 27 21:04:54 2002 +0000 -| description: -| create branch 'REL-2-2-3' (manufactured commit) -| +| o rev: 1 +|/ author: cvs2git +| branch: 'REL-2-2-3' tags: +| files: +| desc: create branch 'REL-2-2-3' (manufactured commit) | -o changeset: 0:8c270455072a - user: Example - date: Wed Jun 06 02:06:20 2001 +0000 - files: Makefile - description: - added Makefile - +o rev: 0 + author: 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 -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 -date: Mon May 27 21:04:55 2002 +0000 -summary: create tag 'REL-2-2-3-P1' (manufactured commit) +rev: 2 +author: 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