Merge branch 'jc/maint-1.6.0-blank-at-eof' (early part) into jc/maint-blank-at-eof
[gitweb.git] / contrib / hg-to-git / hg-to-git.py
index 9befb92c410794a3e81cc571b82f9f35e0def091..2a6839d81ee970cb799859c7a833f8f8cb780864 100755 (executable)
@@ -1,6 +1,6 @@
 #! /usr/bin/python
 
-""" hg-to-svn.py - A Mercurial to GIT converter
+""" hg-to-git.py - A Mercurial to GIT converter
 
     Copyright (C)2007 Stelian Pop <stelian@popies.net>
 
 """
 
 import os, os.path, sys
-import tempfile, popen2, pickle, getopt
+import tempfile, pickle, getopt
 import re
 
 # Maps hg version -> git version
 hgvers = {}
 # List of children for each hg revision
 hgchildren = {}
+# List of parents for each hg revision
+hgparents = {}
 # Current branch for each hg revision
 hgbranch = {}
 # Number of new changesets converted from hg
@@ -44,6 +46,7 @@ def usage():
                          for incrementals
     -n, --nrepack=INT:   number of changesets that will trigger
                          a repack (default=0, -1 to deactivate)
+    -v, --verbose:       be verbose
 
 required:
     hgprj:  name of the HG project to import (directory)
@@ -73,17 +76,20 @@ def getgitenv(user, date):
 
 state = ''
 opt_nrepack = 0
+verbose = False
 
 try:
-    opts, args = getopt.getopt(sys.argv[1:], 's:t:n:', ['gitstate=', 'tempdir=', 'nrepack='])
+    opts, args = getopt.getopt(sys.argv[1:], 's:t:n:v', ['gitstate=', 'tempdir=', 'nrepack=', 'verbose'])
     for o, a in opts:
         if o in ('-s', '--gitstate'):
             state = a
             state = os.path.abspath(state)
         if o in ('-n', '--nrepack'):
             opt_nrepack = int(a)
+        if o in ('-v', '--verbose'):
+            verbose = True
     if len(args) != 1:
-        raise('params')
+        raise Exception('params')
 except:
     usage()
     sys.exit(1)
@@ -93,23 +99,31 @@ def getgitenv(user, date):
 
 if state:
     if os.path.exists(state):
-        print 'State does exist, reading'
+        if verbose:
+            print 'State does exist, reading'
         f = open(state, 'r')
         hgvers = pickle.load(f)
     else:
         print 'State does not exist, first run'
 
-tip = os.popen('hg tip | head -1 | cut -f 2 -d :').read().strip()
-print 'tip is', tip
+sock = os.popen('hg tip --template "{rev}"')
+tip = sock.read()
+if sock.close():
+    sys.exit(1)
+if verbose:
+    print 'tip is', tip
 
 # Calculate the branches
-print 'analysing the branches...'
+if verbose:
+    print 'analysing the branches...'
 hgchildren["0"] = ()
+hgparents["0"] = (None, None)
 hgbranch["0"] = "master"
 for cset in range(1, int(tip) + 1):
     hgchildren[str(cset)] = ()
-    prnts = os.popen('hg log -r %d | grep ^parent: | cut -f 2 -d :' % cset).readlines()
-    if len(prnts) > 0:
+    prnts = os.popen('hg log -r %d --template "{parents}"' % cset).read().strip().split(' ')
+    prnts = map(lambda x: x[:x.find(':')], prnts)
+    if prnts[0] != '':
         parent = prnts[0].strip()
     else:
         parent = str(cset - 1)
@@ -120,6 +134,8 @@ def getgitenv(user, date):
     else:
         mparent = None
 
+    hgparents[str(cset)] = (parent, mparent)
+
     if mparent:
         # For merge changesets, take either one, preferably the 'master' branch
         if hgbranch[mparent] == 'master':
@@ -136,7 +152,7 @@ def getgitenv(user, date):
 
 if not hgvers.has_key("0"):
     print 'creating repository'
-    os.system('git-init-db')
+    os.system('git init')
 
 # loop through every hg changeset
 for cset in range(int(tip) + 1):
@@ -147,34 +163,27 @@ def getgitenv(user, date):
     hgnewcsets += 1
 
     # get info
-    prnts = os.popen('hg log -r %d | grep ^parent: | cut -f 2 -d :' % cset).readlines()
-    if len(prnts) > 0:
-        parent = prnts[0].strip()
-    else:
-        parent = str(cset - 1)
-    if len(prnts) > 1:
-        mparent = prnts[1].strip()
-    else:
-        mparent = None
-
+    log_data = os.popen('hg log -r %d --template "{tags}\n{date|date}\n{author}\n"' % cset).readlines()
+    tag = log_data[0].strip()
+    date = log_data[1].strip()
+    user = log_data[2].strip()
+    parent = hgparents[str(cset)][0]
+    mparent = hgparents[str(cset)][1]
+
+    #get comment
     (fdcomment, filecomment) = tempfile.mkstemp()
-    csetcomment = os.popen('hg log -r %d -v | grep -v ^changeset: | grep -v ^parent: | grep -v ^user: | grep -v ^date | grep -v ^files: | grep -v ^description: | grep -v ^tag:' % cset).read().strip()
+    csetcomment = os.popen('hg log -r %d --template "{desc}"' % cset).read().strip()
     os.write(fdcomment, csetcomment)
     os.close(fdcomment)
 
-    date = os.popen('hg log -r %d | grep ^date: | cut -f 2- -d :' % cset).read().strip()
-
-    tag = os.popen('hg log -r %d | grep ^tag: | cut -f 2- -d :' % cset).read().strip()
-
-    user = os.popen('hg log -r %d | grep ^user: | cut -f 2- -d :' % cset).read().strip()
-
     print '-----------------------------------------'
     print 'cset:', cset
     print 'branch:', hgbranch[str(cset)]
     print 'user:', user
     print 'date:', date
     print 'comment:', csetcomment
-    print 'parent:', parent
+    if parent:
+       print 'parent:', parent
     if mparent:
         print 'mparent:', mparent
     if tag:
@@ -185,10 +194,10 @@ def getgitenv(user, date):
     if cset != 0:
         if hgbranch[str(cset)] == "branch-" + str(cset):
             print 'creating new branch', hgbranch[str(cset)]
-            os.system('git-checkout -b %s %s' % (hgbranch[str(cset)], hgvers[parent]))
+            os.system('git checkout -b %s %s' % (hgbranch[str(cset)], hgvers[parent]))
         else:
             print 'checking out branch', hgbranch[str(cset)]
-            os.system('git-checkout %s' % hgbranch[str(cset)])
+            os.system('git checkout %s' % hgbranch[str(cset)])
 
     # merge
     if mparent:
@@ -197,7 +206,7 @@ def getgitenv(user, date):
         else:
             otherbranch = hgbranch[parent]
         print 'merging', otherbranch, 'into', hgbranch[str(cset)]
-        os.system(getgitenv(user, date) + 'git-merge --no-commit -s ours "" %s %s' % (hgbranch[str(cset)], otherbranch))
+        os.system(getgitenv(user, date) + 'git merge --no-commit -s ours "" %s %s' % (hgbranch[str(cset)], otherbranch))
 
     # remove everything except .git and .hg directories
     os.system('find . \( -path "./.hg" -o -path "./.git" \) -prune -o ! -name "." -print | xargs rm -rf')
@@ -206,9 +215,9 @@ def getgitenv(user, date):
     os.system('hg update -C %d' % cset)
 
     # add new files
-    os.system('git-ls-files -x .hg --others | git-update-index --add --stdin')
+    os.system('git ls-files -x .hg --others | git update-index --add --stdin')
     # delete removed files
-    os.system('git-ls-files -x .hg --deleted | git-update-index --remove --stdin')
+    os.system('git ls-files -x .hg --deleted | git update-index --remove --stdin')
 
     # commit
     os.system(getgitenv(user, date) + 'git commit --allow-empty -a -F %s' % filecomment)
@@ -216,25 +225,25 @@ def getgitenv(user, date):
 
     # tag
     if tag and tag != 'tip':
-        os.system(getgitenv(user, date) + 'git-tag %s' % tag)
+        os.system(getgitenv(user, date) + 'git tag %s' % tag)
 
     # delete branch if not used anymore...
     if mparent and len(hgchildren[str(cset)]):
         print "Deleting unused branch:", otherbranch
-        os.system('git-branch -d %s' % otherbranch)
+        os.system('git branch -d %s' % otherbranch)
 
     # retrieve and record the version
-    vvv = os.popen('git-show | head -1').read()
-    vvv = vvv[vvv.index(' ') + 1 : ].strip()
+    vvv = os.popen('git show --quiet --pretty=format:%H').read()
     print 'record', cset, '->', vvv
     hgvers[str(cset)] = vvv
 
 if hgnewcsets >= opt_nrepack and opt_nrepack != -1:
-    os.system('git-repack -a -d')
+    os.system('git repack -a -d')
 
 # write the state for incrementals
 if state:
-    print 'Writing state'
+    if verbose:
+        print 'Writing state'
     f = open(state, 'w')
     pickle.dump(hgvers, f)