contrib/darcs2hg.py
changeset 2349 88c881bda888
child 2352 61909dfb316d
equal deleted inserted replaced
2348:1772852d7d14 2349:88c881bda888
       
     1 #!/usr/bin/env python
       
     2 # Encoding: iso-8859-1
       
     3 # vim: tw=80 ts=4 sw=4 noet
       
     4 # -----------------------------------------------------------------------------
       
     5 # Project   : Basic Darcs to Mercurial conversion script
       
     6 # -----------------------------------------------------------------------------
       
     7 # Author    : Sebastien Pierre <sebastien@xprima.com>
       
     8 # Creation  : 24-May-2006
       
     9 # Last mod  : 26-May-2006
       
    10 # History   :
       
    11 #             26-May-2006 - Updated
       
    12 #             24-May-2006 - First implementation
       
    13 # -----------------------------------------------------------------------------
       
    14 
       
    15 import os, sys
       
    16 import xml.dom.minidom as xml_dom
       
    17 
       
    18 DARCS_REPO = None
       
    19 HG_REPO    = None
       
    20 
       
    21 USAGE = """\
       
    22 %s DARCSREPO HGREPO
       
    23 
       
    24     Converts the given Darcs repository to a new Mercurial repository. The given
       
    25     HGREPO must not exist, as it will be created and filled up (this will avoid
       
    26     overwriting valuable data.
       
    27 
       
    28 """ % (os.path.basename(__file__))
       
    29 
       
    30 # ------------------------------------------------------------------------------
       
    31 #
       
    32 # Utilities
       
    33 #
       
    34 # ------------------------------------------------------------------------------
       
    35 
       
    36 def cmd(text, path=None):
       
    37 	"""Executes a command, in the given directory (if any), and returns the
       
    38 	command result as a string."""
       
    39 	cwd = None
       
    40 	if path:
       
    41 		path = os.path.abspath(path)
       
    42 		cwd  = os.getcwd()
       
    43 		os.chdir(path)
       
    44 	print text
       
    45 	res = os.popen(text).read()
       
    46 	if path:
       
    47 		os.chdir(cwd)
       
    48 	return res
       
    49 
       
    50 def writefile(path, data):
       
    51 	"""Writes the given data into the given file."""
       
    52 	f = file(path, "w") ; f.write(data)  ; f.close()
       
    53 
       
    54 # ------------------------------------------------------------------------------
       
    55 #
       
    56 # Darcs interface
       
    57 #
       
    58 # ------------------------------------------------------------------------------
       
    59 
       
    60 def darcs_changes(darcsRepo):
       
    61 	"""Gets the changes list from the given darcs repository. This returns the
       
    62 	chronological list of changes as (change name, change summary)."""
       
    63 	changes    = cmd("darcs changes --reverse --xml-output", darcsRepo)
       
    64 	doc        = xml_dom.parseString(changes)
       
    65 	res        = []
       
    66 	for patch_node in doc.childNodes[0].childNodes:
       
    67 		name = filter(lambda n:n.nodeName == "name", patch_node.childNodes)
       
    68 		comm = filter(lambda n:n.nodeName == "comment", patch_node.childNodes)
       
    69 		if not name:continue
       
    70 		else: name = name[0].childNodes[0].data
       
    71 		if not comm: comm = ""
       
    72 		else: comm = comm[0].childNodes[0].data
       
    73 		res.append([name, comm])
       
    74 	return res
       
    75 
       
    76 def darcs_pull(hg_repo, darcs_repo, change):
       
    77 	cmd("darcs pull '%s' --all --patches='%s'" % (darcs_repo, change), hg_repo)
       
    78 
       
    79 # ------------------------------------------------------------------------------
       
    80 #
       
    81 # Mercurial interface
       
    82 #
       
    83 # ------------------------------------------------------------------------------
       
    84 
       
    85 def hg_commit( hg_repo, text ):
       
    86 	writefile("/tmp/msg", text)
       
    87 	cmd("hg add -X _darcs *", hg_repo)
       
    88 	cmd("hg commit -l /tmp/msg", hg_repo)
       
    89 	os.unlink("/tmp/msg")
       
    90 
       
    91 # ------------------------------------------------------------------------------
       
    92 #
       
    93 # Main
       
    94 #
       
    95 # ------------------------------------------------------------------------------
       
    96 
       
    97 if __name__ == "__main__":
       
    98 	args = sys.argv[1:]
       
    99 	# We parse the arguments
       
   100 	if len(args)   == 2:
       
   101 		darcs_repo = os.path.abspath(args[0])
       
   102 		hg_repo    = os.path.abspath(args[1])
       
   103 	else:
       
   104 		print USAGE
       
   105 		sys.exit(-1)
       
   106 	# Initializes the target repo
       
   107 	if not os.path.isdir(darcs_repo + "/_darcs"):
       
   108 		print "No darcs directory found at: " + darc_repo
       
   109 		sys.exit(-1)
       
   110 	if not os.path.isdir(hg_repo):
       
   111 		os.mkdir(hg_repo)
       
   112 	else:
       
   113 		print "Given HG repository must not exist. It will be created"
       
   114 		sys.exit(-1)
       
   115 	cmd("hg init '%s'" % (hg_repo))
       
   116 	cmd("darcs initialize", hg_repo)
       
   117 	# Get the changes from the Darcs repository
       
   118 	for summary, description in darcs_changes(darcs_repo):
       
   119 		text = summary + "\n" + description
       
   120 		darcs_pull(hg_repo, darcs_repo, summary)
       
   121 		hg_commit(hg_repo, text)
       
   122 
       
   123 # EOF
       
   124