--- a/contrib/darcs2hg.py Sun Jul 09 21:41:00 2006 -0700
+++ b/contrib/darcs2hg.py Mon Jul 10 12:19:37 2006 -0400
@@ -4,12 +4,11 @@
# -----------------------------------------------------------------------------
# Project : Basic Darcs to Mercurial conversion script
# -----------------------------------------------------------------------------
-# Author : Sebastien Pierre <sebastien@xprima.com>
+# Authors : Sebastien Pierre <sebastien@xprima.com>
+# TK Soh <teekaysoh@gmail.com>
+# -----------------------------------------------------------------------------
# Creation : 24-May-2006
-# Last mod : 26-May-2006
-# History :
-# 26-May-2006 - Updated
-# 24-May-2006 - First implementation
+# Last mod : 05-Jun-2006
# -----------------------------------------------------------------------------
import os, sys
@@ -21,12 +20,14 @@
HG_REPO = None
USAGE = """\
-%s DARCSREPO HGREPO
+%s DARCSREPO HGREPO [SKIP]
Converts the given Darcs repository to a new Mercurial repository. The given
HGREPO must not exist, as it will be created and filled up (this will avoid
overwriting valuable data.
+ In case an error occurs within the process, you can resume the process by
+ giving the last successfuly applied change number.
""" % (os.path.basename(sys.argv[0]))
# ------------------------------------------------------------------------------
@@ -35,7 +36,7 @@
#
# ------------------------------------------------------------------------------
-def cmd(text, path=None):
+def cmd(text, path=None, silent=False):
"""Executes a command, in the given directory (if any), and returns the
command result as a string."""
cwd = None
@@ -43,7 +44,7 @@
path = os.path.abspath(path)
cwd = os.getcwd()
os.chdir(path)
- print text
+ if not silent: print "> ", text
res = os.popen(text).read()
if path:
os.chdir(cwd)
@@ -53,6 +54,14 @@
"""Writes the given data into the given file."""
f = file(path, "w") ; f.write(data) ; f.close()
+def error( *args ):
+ sys.stderr.write("ERROR: ")
+ for a in args: sys.stderr.write(str(a))
+ sys.stderr.write("\n")
+ sys.stderr.write("You can make manual fixes if necessary and then resume by"
+ " giving the last changeset number")
+ sys.exit(-1)
+
# ------------------------------------------------------------------------------
#
# Darcs interface
@@ -64,7 +73,6 @@
chronological list of changes as (change name, change summary)."""
changes = cmd("darcs changes --reverse --xml-output", darcsRepo)
doc = xml_dom.parseString(changes)
- res = []
for patch_node in doc.childNodes[0].childNodes:
name = filter(lambda n:n.nodeName == "name", patch_node.childNodes)
comm = filter(lambda n:n.nodeName == "comment", patch_node.childNodes)
@@ -73,12 +81,22 @@
if not comm: comm = ""
else: comm = comm[0].childNodes[0].data
author = patch_node.getAttribute("author")
- date = patch_node.getAttribute("date")
- hash = patch_node.getAttribute("hash")
- yield hash, author, date, name, comm
+ date = patch_node.getAttribute("date")
+ chash = os.path.splitext(patch_node.getAttribute("hash"))[0]
+ yield author, date, name, chash, comm
-def darcs_pull(hg_repo, darcs_repo, change):
- cmd("darcs pull '%s' --all --patches='%s'" % (darcs_repo, change), hg_repo)
+def darcs_tip(darcs_repo):
+ changes = cmd("darcs changes",darcs_repo,silent=True)
+ changes = filter(lambda l:l.strip().startswith("* "), changes.split("\n"))
+ return len(changes)
+
+def darcs_pull(hg_repo, darcs_repo, chash):
+ old_tip = darcs_tip(darcs_repo)
+ res = cmd("darcs pull '%s' --all --match='hash %s'" % (darcs_repo, chash), hg_repo)
+ print res
+ new_tip = darcs_tip(darcs_repo)
+ if not new_tip != old_tip + 1:
+ error("Darcs pull did not work as expected: " + res)
# ------------------------------------------------------------------------------
#
@@ -89,10 +107,24 @@
def hg_commit( hg_repo, text, author, date ):
fd, tmpfile = tempfile.mkstemp(prefix="darcs2hg_")
writefile(tmpfile, text)
+ old_tip = hg_tip(hg_repo)
cmd("hg add -X _darcs", hg_repo)
cmd("hg remove -X _darcs --after", hg_repo)
- cmd("hg commit -l %s -u '%s' -d '%s 0'" % (tmpfile, author, date), hg_repo)
+ res = cmd("hg commit -l %s -u '%s' -d '%s 0'" % (tmpfile, author, date), hg_repo)
os.unlink(tmpfile)
+ new_tip = hg_tip(hg_repo)
+ if not new_tip == old_tip + 1:
+ # Sometimes we may have empty commits, we simply skip them
+ if res.strip().lower().find("nothing changed") != -1:
+ pass
+ else:
+ error("Mercurial commit did not work as expected: " + res)
+
+def hg_tip( hg_repo ):
+ """Returns the latest local revision number in the given repository."""
+ tip = cmd("hg tip", hg_repo, silent=True)
+ tip = tip.split("\n")[0].split(":")[1].strip()
+ return int(tip)
# ------------------------------------------------------------------------------
#
@@ -106,26 +138,41 @@
if len(args) == 2:
darcs_repo = os.path.abspath(args[0])
hg_repo = os.path.abspath(args[1])
+ skip = None
+ elif len(args) == 3:
+ darcs_repo = os.path.abspath(args[0])
+ hg_repo = os.path.abspath(args[1])
+ skip = int(args[2])
else:
print USAGE
sys.exit(-1)
# Initializes the target repo
if not os.path.isdir(darcs_repo + "/_darcs"):
- print "No darcs directory found at: " + darc_repo
+ print "No darcs directory found at: " + darcs_repo
sys.exit(-1)
if not os.path.isdir(hg_repo):
os.mkdir(hg_repo)
- else:
- print "Given HG repository must not exist. It will be created"
+ elif skip == None:
+ print "Given HG repository must not exist when no SKIP is specified."
sys.exit(-1)
- cmd("hg init '%s'" % (hg_repo))
- cmd("darcs initialize", hg_repo)
+ if skip == None:
+ cmd("hg init '%s'" % (hg_repo))
+ cmd("darcs initialize", hg_repo)
# Get the changes from the Darcs repository
- for hash, author, date, summary, description in darcs_changes(darcs_repo):
- text = summary + "\n" + description
- darcs_pull(hg_repo, darcs_repo, hash)
- epoch = int(mktime(strptime(date, '%Y%m%d%H%M%S')))
- hg_commit(hg_repo, text, author, epoch)
+ change_number = 0
+ for author, date, summary, chash, description in darcs_changes(darcs_repo):
+ print "== changeset", change_number,
+ if skip != None and change_number <= skip:
+ print "(skipping)"
+ else:
+ text = summary + "\n" + description
+ darcs_pull(hg_repo, darcs_repo, chash)
+ # The commit hash has a date like 20021020201112
+ # --------------------------------YYYYMMDDHHMMSS
+ date = chash.split("-")[0]
+ epoch = int(mktime(strptime(date, '%Y%m%d%H%M%S')))
+ hg_commit(hg_repo, text, author, epoch)
+ change_number += 1
+ print "Darcs repository (_darcs) was not deleted. You can keep or remove it."
# EOF
-