contrib/darcs2hg.py
author Raphael Marmier <raphael@marmier.net>
Mon, 03 Jul 2006 10:18:46 -0700
changeset 2550 45235e492cc6
parent 2352 61909dfb316d
child 2585 5ec2dded1bda
permissions -rwxr-xr-x
Disable automatic line endings conversion on windows The rationale behind this is that such conversion implies a particular situation in which all files in the repo are terminated by only LF. This is documented nowhere and it bit me sharply when I upgraded. Furthermore, it works on the assumption that a file containing no NULL characters are actually a text file. Therefore it cannot guarantee that no binary file will be harmed in the process. Currently, if a file already contains CRLF line endings when it is copied to the working dir from the repo, then the version in the working dir will be corrupted by an extra CR. I'm working on a patch that will turn this into a warning. But as a side effect, committing such a file back will strip it from its CR. In all case, unrequested data modification can occur under the feet of the user, which is bad(tm), ihmo.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2349
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     1
#!/usr/bin/env python
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     2
# Encoding: iso-8859-1
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     3
# vim: tw=80 ts=4 sw=4 noet
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     4
# -----------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     5
# Project   : Basic Darcs to Mercurial conversion script
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     6
# -----------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     7
# Author    : Sebastien Pierre <sebastien@xprima.com>
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     8
# Creation  : 24-May-2006
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
     9
# Last mod  : 26-May-2006
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    10
# History   :
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    11
#             26-May-2006 - Updated
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    12
#             24-May-2006 - First implementation
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    13
# -----------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    14
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    15
import os, sys
2352
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    16
import tempfile
2349
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    17
import xml.dom.minidom as xml_dom
2352
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    18
from time import strptime, mktime
2349
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    19
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    20
DARCS_REPO = None
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    21
HG_REPO    = None
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    22
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    23
USAGE = """\
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    24
%s DARCSREPO HGREPO
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    25
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    26
    Converts the given Darcs repository to a new Mercurial repository. The given
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    27
    HGREPO must not exist, as it will be created and filled up (this will avoid
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    28
    overwriting valuable data.
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    29
2352
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    30
""" % (os.path.basename(sys.argv[0]))
2349
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    31
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    32
# ------------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    33
#
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    34
# Utilities
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    35
#
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    36
# ------------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    37
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    38
def cmd(text, path=None):
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    39
	"""Executes a command, in the given directory (if any), and returns the
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    40
	command result as a string."""
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    41
	cwd = None
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    42
	if path:
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    43
		path = os.path.abspath(path)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    44
		cwd  = os.getcwd()
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    45
		os.chdir(path)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    46
	print text
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    47
	res = os.popen(text).read()
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    48
	if path:
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    49
		os.chdir(cwd)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    50
	return res
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    51
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    52
def writefile(path, data):
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    53
	"""Writes the given data into the given file."""
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    54
	f = file(path, "w") ; f.write(data)  ; f.close()
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    55
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    56
# ------------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    57
#
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    58
# Darcs interface
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    59
#
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    60
# ------------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    61
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    62
def darcs_changes(darcsRepo):
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    63
	"""Gets the changes list from the given darcs repository. This returns the
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    64
	chronological list of changes as (change name, change summary)."""
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    65
	changes    = cmd("darcs changes --reverse --xml-output", darcsRepo)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    66
	doc        = xml_dom.parseString(changes)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    67
	res        = []
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    68
	for patch_node in doc.childNodes[0].childNodes:
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    69
		name = filter(lambda n:n.nodeName == "name", patch_node.childNodes)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    70
		comm = filter(lambda n:n.nodeName == "comment", patch_node.childNodes)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    71
		if not name:continue
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    72
		else: name = name[0].childNodes[0].data
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    73
		if not comm: comm = ""
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    74
		else: comm = comm[0].childNodes[0].data
2352
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    75
		author = patch_node.getAttribute("author")
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    76
		date = patch_node.getAttribute("date")
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    77
		yield author, date, name, comm
2349
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    78
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    79
def darcs_pull(hg_repo, darcs_repo, change):
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    80
	cmd("darcs pull '%s' --all --patches='%s'" % (darcs_repo, change), hg_repo)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    81
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    82
# ------------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    83
#
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    84
# Mercurial interface
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    85
#
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    86
# ------------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    87
2352
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    88
def hg_commit( hg_repo, text, author, date ):
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    89
	fd, tmpfile = tempfile.mkstemp(prefix="darcs2hg_")
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    90
	writefile(tmpfile, text)
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    91
	cmd("hg add -X _darcs", hg_repo)
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    92
	cmd("hg remove -X _darcs --after", hg_repo)
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    93
	cmd("hg commit -l %s -u '%s' -d '%s 0'"  % (tmpfile, author, date), hg_repo)
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
    94
	os.unlink(tmpfile)
2349
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    95
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    96
# ------------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    97
#
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    98
# Main
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
    99
#
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   100
# ------------------------------------------------------------------------------
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   101
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   102
if __name__ == "__main__":
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   103
	args = sys.argv[1:]
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   104
	# We parse the arguments
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   105
	if len(args)   == 2:
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   106
		darcs_repo = os.path.abspath(args[0])
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   107
		hg_repo    = os.path.abspath(args[1])
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   108
	else:
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   109
		print USAGE
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   110
		sys.exit(-1)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   111
	# Initializes the target repo
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   112
	if not os.path.isdir(darcs_repo + "/_darcs"):
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   113
		print "No darcs directory found at: " + darc_repo
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   114
		sys.exit(-1)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   115
	if not os.path.isdir(hg_repo):
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   116
		os.mkdir(hg_repo)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   117
	else:
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   118
		print "Given HG repository must not exist. It will be created"
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   119
		sys.exit(-1)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   120
	cmd("hg init '%s'" % (hg_repo))
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   121
	cmd("darcs initialize", hg_repo)
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   122
	# Get the changes from the Darcs repository
2352
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
   123
	for author, date, summary, description in darcs_changes(darcs_repo):
2349
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   124
		text = summary + "\n" + description
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   125
		darcs_pull(hg_repo, darcs_repo, summary)
2352
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
   126
		epoch = int(mktime(strptime(date, '%Y%m%d%H%M%S')))
61909dfb316d various fixes to darcs conversion script
TK Soh <teekaysoh@yahoo.com>
parents: 2349
diff changeset
   127
		hg_commit(hg_repo, text, author, epoch)
2349
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   128
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   129
# EOF
88c881bda888 darcs2hg.py: import darcs project into mercurial
Sébastien Pierre <sebastien@xprima.com>
parents:
diff changeset
   130