From 7c0d741a3e8db662419cc841e3068b2a8880a109 Mon Sep 17 00:00:00 2001 From: Michael Gebetsroither Date: Sat, 6 Oct 2007 23:16:51 +0200 Subject: hg-to-git speedup through selectable repack intervals Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- contrib/hg-to-git/hg-to-git.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 37337ff01..7a1c3e497 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -29,6 +29,8 @@ hgvers = {} hgchildren = {} # Current branch for each hg revision hgbranch = {} +# Number of new changesets converted from hg +hgnewcsets = 0 #------------------------------------------------------------------------------ @@ -40,6 +42,8 @@ def usage(): options: -s, --gitstate=FILE: name of the state to be saved/read for incrementals + -n, --nrepack=INT: number of changesets that will trigger + a repack (default=0, -1 to deactivate) required: hgprj: name of the HG project to import (directory) @@ -68,14 +72,16 @@ def getgitenv(user, date): #------------------------------------------------------------------------------ state = '' +opt_nrepack = 0 try: - opts, args = getopt.getopt(sys.argv[1:], 's:t:', ['gitstate=', 'tempdir=']) + opts, args = getopt.getopt(sys.argv[1:], 's:t:n:', ['gitstate=', 'tempdir=', 'nrepack=']) 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 len(args) != 1: raise('params') except: @@ -138,6 +144,7 @@ for cset in range(int(tip) + 1): # incremental, already seen if hgvers.has_key(str(cset)): continue + hgnewcsets += 1 # get info prnts = os.popen('hg log -r %d | grep ^parent: | cut -f 2 -d :' % cset).readlines() @@ -222,7 +229,8 @@ for cset in range(int(tip) + 1): print 'record', cset, '->', vvv hgvers[str(cset)] = vvv -os.system('git-repack -a -d') +if hgnewcsets >= opt_nrepack and opt_nrepack != -1: + os.system('git-repack -a -d') # write the state for incrementals if state: -- cgit v1.2.1 From 90e0653b1824f27559cbc5c9d1f2a00fdb9400ba Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 6 Dec 2007 07:26:29 -0800 Subject: hg-to-git: handle an empty dir in hg. Mark Drago had a subversion repository which was then converted to hg and now is moving in to git. The first commit in the svn repo was just the creation of the empty directory. This made its way in to the hg repository fine, but converting from hg to git would cause an error. The problem was that hg-to-git.py tries to commit the change, git-commit fails, and then hg-to-git.py tries to checkout the new revision and that fails (because it was not created). This may have only caused an error because it was the first commit in the repository. If an empty directory was added in the middle of the repo somewhere things might have worked out fine. This patch will use the new --allow-empty option to git-commit to record such an "empty" commit, to reproduce the history recorded in hg more faithfully. Tested-by: Mark Drago Signed-off-by: Junio C Hamano --- contrib/hg-to-git/hg-to-git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 7a1c3e497..9befb92c4 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -211,7 +211,7 @@ for cset in range(int(tip) + 1): os.system('git-ls-files -x .hg --deleted | git-update-index --remove --stdin') # commit - os.system(getgitenv(user, date) + 'git-commit -a -F %s' % filecomment) + os.system(getgitenv(user, date) + 'git commit --allow-empty -a -F %s' % filecomment) os.unlink(filecomment) # tag -- cgit v1.2.1 From 1bc7c13af9f936aa80893100120b542338a10bf4 Mon Sep 17 00:00:00 2001 From: Mark Drago Date: Mon, 14 Jan 2008 20:11:19 -0500 Subject: hg-to-git: improve popen calls This patch improves all of the popen calls in hg-to-git.py by specifying the template 'hg log' should use instead of calling 'hg log' and grepping for the desired data. Signed-off-by: Mark Drago Acked-by: Stelian Pop Signed-off-by: Junio C Hamano --- contrib/hg-to-git/hg-to-git.py | 46 ++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 9befb92c4..c35b15860 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -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 @@ -27,6 +27,8 @@ import re 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 @@ -99,17 +101,19 @@ if state: else: print 'State does not exist, first run' -tip = os.popen('hg tip | head -1 | cut -f 2 -d :').read().strip() +tip = os.popen('hg tip --template "{rev}"').read() print 'tip is', tip # Calculate the branches 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().split(' ') + prnts = map(lambda x: x[:x.find(':')], prnts) + if prnts[0] != '': parent = prnts[0].strip() else: parent = str(cset - 1) @@ -120,6 +124,8 @@ for cset in range(1, int(tip) + 1): else: mparent = None + hgparents[str(cset)] = (parent, mparent) + if mparent: # For merge changesets, take either one, preferably the 'master' branch if hgbranch[mparent] == 'master': @@ -147,34 +153,27 @@ for cset in range(int(tip) + 1): 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: @@ -224,8 +223,7 @@ for cset in range(int(tip) + 1): 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 -- cgit v1.2.1 From 13bf1a99764ea751f6fa75502309d8b91529623a Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Fri, 15 Feb 2008 22:20:44 +0100 Subject: hg-to-git: fix parent analysis Fix a bug in the hg-to-git convertor introduced by commit 1bc7c13af9f936aa80893100120b542338a10bf4: when searching the changeset parents, 'hg log' returns an extra space at the end of the line, which confuses the .split(' ') based tokenizer: Traceback (most recent call last): File "hg-to-git.py", line 123, in hgchildren[mparent] += ( str(cset), ) KeyError: '' Signed-off-by: Stelian Pop Signed-off-by: Junio C Hamano --- contrib/hg-to-git/hg-to-git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index c35b15860..d72ffbb77 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -111,7 +111,7 @@ 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 --template "{parents}"' % cset).read().split(' ') + 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() -- cgit v1.2.1 From 37a12dda24f7ab250869db7eb00157f78d40c724 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 26 May 2008 14:20:54 +0100 Subject: hg-to-git: add --verbose option This patch adds an option to make hg-to-git quiet by default. Note: it only suppresses those messages that would be printed when everything was up-to-date. Signed-off-by: Johannes Schindelin Acked-by: Stelian Pop Signed-off-by: Junio C Hamano --- contrib/hg-to-git/hg-to-git.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index d72ffbb77..f68ef725d 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -46,6 +46,7 @@ options: 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) @@ -75,15 +76,18 @@ 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') except: @@ -95,17 +99,20 @@ os.chdir(hgprj) 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 --template "{rev}"').read() -print 'tip is', tip +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" @@ -232,7 +239,8 @@ if hgnewcsets >= opt_nrepack and opt_nrepack != -1: # write the state for incrementals if state: - print 'Writing state' + if verbose: + print 'Writing state' f = open(state, 'w') pickle.dump(hgvers, f) -- cgit v1.2.1 From 6376cffaebe40947eea9afb4ae6df05a6ac59ae8 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sun, 6 Jul 2008 05:15:17 +0200 Subject: hg-to-git: avoid raising a string exception This fixes the following warning: hg-to-git.py:92: DeprecationWarning: raising a string exception is deprecated Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- contrib/hg-to-git/hg-to-git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index f68ef725d..25d99411c 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -89,7 +89,7 @@ try: if o in ('-v', '--verbose'): verbose = True if len(args) != 1: - raise('params') + raise Exception('params') except: usage() sys.exit(1) -- cgit v1.2.1 From 2553ede5a9b09260be69de72b60e5038f5452c44 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sun, 6 Jul 2008 05:15:18 +0200 Subject: hg-to-git: abort if the project directory is not a hg repo Check the exit code of the first hg command, and abort to avoid a later ValueError exception. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- contrib/hg-to-git/hg-to-git.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 25d99411c..130b1c4bc 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -106,7 +106,10 @@ if state: else: print 'State does not exist, first run' -tip = os.popen('hg tip --template "{rev}"').read() +sock = os.popen('hg tip --template "{rev}"') +tip = sock.read() +if sock.close(): + sys.exit(1) if verbose: print 'tip is', tip -- cgit v1.2.1 From 96f2395951fd81ad49217d49074dfbcf3f0df685 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sun, 6 Jul 2008 05:15:19 +0200 Subject: hg-to-git: rewrite "git-frotz" to "git frotz" This is not just nice but necessary since git-frotz is no longer in PATH. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- contrib/hg-to-git/hg-to-git.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 130b1c4bc..61540ef80 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -152,7 +152,7 @@ for cset in range(1, int(tip) + 1): if not hgvers.has_key("0"): print 'creating repository' - os.system('git-init-db') + os.system('git init-db') # loop through every hg changeset for cset in range(int(tip) + 1): @@ -194,10 +194,10 @@ for cset in range(int(tip) + 1): 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: @@ -206,7 +206,7 @@ for cset in range(int(tip) + 1): 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') @@ -215,9 +215,9 @@ for cset in range(int(tip) + 1): 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) @@ -225,20 +225,20 @@ for cset in range(int(tip) + 1): # 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 --quiet --pretty=format:%H').read() + 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: -- cgit v1.2.1 From af9a01e1c2f6a8814b817eb7f3d78814389a3212 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sun, 6 Jul 2008 05:15:20 +0200 Subject: hg-to-git: use git init instead of git init-db Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- contrib/hg-to-git/hg-to-git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'contrib/hg-to-git/hg-to-git.py') diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 61540ef80..7b03204ed 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -152,7 +152,7 @@ for cset in range(1, int(tip) + 1): 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): -- cgit v1.2.1