[PATCH] Updated convert-repo script

Sébastien Pierre sebastien at xprima.com
Mon May 1 10:57:55 CDT 2006


Hi all, 

This is my first patch, so I don't know if I'm doing things right here.
Anyway, here it is:

Updated the `convert-repo` script to support the latest version of
git(1.3.0), and simplified the usage, so that we now simply have to give
the git directory, and a destination directory, and the conversion will
be automagically carried. I also added a more verbose output, to help
track problems.

This patch was generated against mercurial main repository.

 -- Sébastien

--
# HG changeset patch
# User sebastien at localhost.localdomain
# Node ID ca7df5efc7c17d517e7aa8c27369514be798e9d7
# Parent  0ce3cd330996e49ac3292aac4bfa4d4cd3f0a47a
Updated the `convert-repo` script to support the latest version of git
(1.3.0),
and simplified the usage, so that we now simply have to give the git
directory,
and a destination directory, and the conversion will be automagically
carried. I
also added a more verbose output, to help track problems.

diff -r 0ce3cd330996 -r ca7df5efc7c1 contrib/convert-repo
--- a/contrib/convert-repo	Fri Apr 28 12:38:11 2006 +0200
+++ b/contrib/convert-repo	Mon May 01 11:54:09 2006 -0400
@@ -1,24 +1,28 @@
 #!/usr/bin/env python
-#
-# This is a generalized framework for converting between SCM
-# repository formats.
-#
-# In its current form, it's hardcoded to convert incrementally between
-# git and Mercurial.
-#
-# To use, you must first import the first git version into Mercurial,
-# and establish a mapping between the git commit hash and the hash in
-# Mercurial for that version. This mapping is kept in a simple text
-# file with lines like so:
-#
-# <git hash> <mercurial hash>
-#
-# To convert the rest of the repo, run:
-#
-# convert-repo <git-dir> <hg-dir> <mapfile>
-#
-# This updates the mapfile on each commit copied, so it can be
-# interrupted and can be run repeatedly to copy new commits.
+
+__doc__ = """\
+
+convert-repo GIT-DIR HG-DIR [MAPFILE]
+
+The `convert-repo` script converts from a git repository to a Mercurial
+directory. The easiest way to use it is to give the location of the
original git
+directory, and then the destination Mercurial directory.
+
+If you specify a MAPFILE, you must first import the first git version
into
+Mercurial, and establish a mapping between the git commit hash and the
hash in
+Mercurial for that version. This mapping is kept in a simple text file
with
+lines like so:
+
+<git hash> <mercurial hash>
+
+This updates the mapfile on each commit copied, so it can be
interrupted and can
+be run repeatedly to copy new commits.
+
+This is a generalized framework for converting between SCM repository
formats.
+In its current form, it's hardcoded to convert incrementally between
git and
+Mercurial.
+
+"""
 
 import sys, os, zlib, sha, time
 from mercurial import hg, ui, util
@@ -28,17 +32,26 @@ class convert_git:
         self.path = path
 
     def getheads(self):
-        return [file(self.path + "/HEAD").read()[:-1]]
+        # On some version of git, the HEAD file last line is like
+        # ref: refs/heads/master
+        # And we only want "master" here
+        head = file(self.path + "/HEAD").read()[:-1]
+        head = head.split("/")[-1]
+        print "git:head", head
+        return [head]
 
     def catfile(self, rev, type):
         if rev == "0" * 40: raise IOError()
         fh = os.popen("GIT_DIR=%s git-cat-file %s %s 2>/dev/null" %
(self.path, type, rev))
+        print "git:cat-file", self.path, type
         return fh.read()
 
     def getfile(self, name, rev):
+        print "git:get-file", name, rev
         return self.catfile(rev, "blob")
 
     def getchanges(self, version):
+        print "git:get-changes", version
         fh = os.popen("GIT_DIR=%s git-diff-tree --root -m -r %s" %
(self.path, version))
         changes = []
         for l in fh:
@@ -51,6 +64,7 @@ class convert_git:
         return changes
 
     def getcommit(self, version):
+        print "git:get-commit", version
         c = self.catfile(version, "commit") # read the commit hash
         end = c.find("\n\n")
         message = c[end+2:]
@@ -281,9 +295,44 @@ class convert:
             # one so we don't end up with extra tag heads
             file(self.mapfile, "a").write("%s %s\n" % (c, nrev))
 
-gitpath, hgpath, mapfile = sys.argv[1:]
-if os.path.isdir(gitpath + "/.git"):
-    gitpath += "/.git"
-
-c = convert(convert_git(gitpath), convert_mercurial(hgpath), mapfile)
-c.convert()
+if __name__ == "__main__":
+
+    def command(cmd):
+        print "shell:", cmd
+        r = os.popen(cmd).read()
+        return r
+
+    # We only have the git and the mercurial directory
+    if len(sys.argv) == 3:
+        source, dest = sys.argv[1:]
+        # We may have to create the destination directory
+        if not os.path.isdir(dest) or not os.path.isdir(dest +
"/.git"):
+            command("git clone %s %s" % (source, dest))
+        # We get the git head and mercurial head
+        git_commit = command("GIT_DIR=%s/.git git log | grep 'commit '
| tail -n1 | cut -d ' ' -f2" % (source))
+        git_commit = git_commit.replace(" ", "").replace("\n", "")
+        print "Git commit is", git_commit
+        # And maybe create the Mercurial repository as well
+        command("cd %s ; git checkout -b mercurial %s" % (dest,
git_commit))
+        if not os.path.isdir(dest + "/.hg"):
+            command("cd %s ; hg init ; hg commit -A -X .git -m 'Initial
commit (from git)'; cd .." % (dest))
+        hg_commit  = command("cd %s ; hg log -v | grep changeset | tail
-n1 | cut -d ':' -f3 " % (dest))
+        hg_commit  = hg_commit.replace(" ", "").replace("\n", "")
+        print "Mercurial commit is", git_commit
+        mapfile = "%s/MAPFILE" % (dest)
+        f = open(mapfile, "w")
+        f.write("%s %s\n" % (git_commit, hg_commit))
+        f.close()
+    # We have a mapfile as well
+    elif len(sys.argv) == 4:
+        source, dest, mapfile = sys.argv[1:]
+    else:
+        print __doc__
+        sys.exit(-1)
+
+    # Do the actual conversion
+    if os.path.isdir(source + "/.git"): source += "/.git"
+    c = convert(convert_git(source), convert_mercurial(dest), mapfile)
+    c.convert()
+
+# vim: ts=4 sw=4 et
--
-------------- next part --------------
A non-text attachment was scrubbed...
Name: convert-repo-update.patch
Type: text/x-patch
Size: 5679 bytes
Desc: not available
Url : http://www.selenic.com/pipermail/mercurial/attachments/20060501/6c8f22ec/convert-repo-update-0001.bin


More information about the Mercurial mailing list