##// END OF EJS Templates
darcs2hg: pause and resume support, date extraction from commit hash, does not break on empty commits
Sébastien Pierre -
r2587:fe3e8735 default
parent child Browse files
Show More
@@ -4,12 +4,11 b''
4 4 # -----------------------------------------------------------------------------
5 5 # Project : Basic Darcs to Mercurial conversion script
6 6 # -----------------------------------------------------------------------------
7 # Author : Sebastien Pierre <sebastien@xprima.com>
7 # Authors : Sebastien Pierre <sebastien@xprima.com>
8 # TK Soh <teekaysoh@gmail.com>
9 # -----------------------------------------------------------------------------
8 10 # Creation : 24-May-2006
9 # Last mod : 26-May-2006
10 # History :
11 # 26-May-2006 - Updated
12 # 24-May-2006 - First implementation
11 # Last mod : 05-Jun-2006
13 12 # -----------------------------------------------------------------------------
14 13
15 14 import os, sys
@@ -21,12 +20,14 b' DARCS_REPO = None'
21 20 HG_REPO = None
22 21
23 22 USAGE = """\
24 %s DARCSREPO HGREPO
23 %s DARCSREPO HGREPO [SKIP]
25 24
26 25 Converts the given Darcs repository to a new Mercurial repository. The given
27 26 HGREPO must not exist, as it will be created and filled up (this will avoid
28 27 overwriting valuable data.
29 28
29 In case an error occurs within the process, you can resume the process by
30 giving the last successfuly applied change number.
30 31 """ % (os.path.basename(sys.argv[0]))
31 32
32 33 # ------------------------------------------------------------------------------
@@ -35,7 +36,7 b' USAGE = """\\'
35 36 #
36 37 # ------------------------------------------------------------------------------
37 38
38 def cmd(text, path=None):
39 def cmd(text, path=None, silent=False):
39 40 """Executes a command, in the given directory (if any), and returns the
40 41 command result as a string."""
41 42 cwd = None
@@ -43,7 +44,7 b' def cmd(text, path=None):'
43 44 path = os.path.abspath(path)
44 45 cwd = os.getcwd()
45 46 os.chdir(path)
46 print text
47 if not silent: print "> ", text
47 48 res = os.popen(text).read()
48 49 if path:
49 50 os.chdir(cwd)
@@ -53,6 +54,14 b' def writefile(path, data):'
53 54 """Writes the given data into the given file."""
54 55 f = file(path, "w") ; f.write(data) ; f.close()
55 56
57 def error( *args ):
58 sys.stderr.write("ERROR: ")
59 for a in args: sys.stderr.write(str(a))
60 sys.stderr.write("\n")
61 sys.stderr.write("You can make manual fixes if necessary and then resume by"
62 " giving the last changeset number")
63 sys.exit(-1)
64
56 65 # ------------------------------------------------------------------------------
57 66 #
58 67 # Darcs interface
@@ -64,7 +73,6 b' def darcs_changes(darcsRepo):'
64 73 chronological list of changes as (change name, change summary)."""
65 74 changes = cmd("darcs changes --reverse --xml-output", darcsRepo)
66 75 doc = xml_dom.parseString(changes)
67 res = []
68 76 for patch_node in doc.childNodes[0].childNodes:
69 77 name = filter(lambda n:n.nodeName == "name", patch_node.childNodes)
70 78 comm = filter(lambda n:n.nodeName == "comment", patch_node.childNodes)
@@ -74,11 +82,21 b' def darcs_changes(darcsRepo):'
74 82 else: comm = comm[0].childNodes[0].data
75 83 author = patch_node.getAttribute("author")
76 84 date = patch_node.getAttribute("date")
77 hash = patch_node.getAttribute("hash")
78 yield hash, author, date, name, comm
85 chash = os.path.splitext(patch_node.getAttribute("hash"))[0]
86 yield author, date, name, chash, comm
87
88 def darcs_tip(darcs_repo):
89 changes = cmd("darcs changes",darcs_repo,silent=True)
90 changes = filter(lambda l:l.strip().startswith("* "), changes.split("\n"))
91 return len(changes)
79 92
80 def darcs_pull(hg_repo, darcs_repo, change):
81 cmd("darcs pull '%s' --all --patches='%s'" % (darcs_repo, change), hg_repo)
93 def darcs_pull(hg_repo, darcs_repo, chash):
94 old_tip = darcs_tip(darcs_repo)
95 res = cmd("darcs pull '%s' --all --match='hash %s'" % (darcs_repo, chash), hg_repo)
96 print res
97 new_tip = darcs_tip(darcs_repo)
98 if not new_tip != old_tip + 1:
99 error("Darcs pull did not work as expected: " + res)
82 100
83 101 # ------------------------------------------------------------------------------
84 102 #
@@ -89,10 +107,24 b' def darcs_pull(hg_repo, darcs_repo, chan'
89 107 def hg_commit( hg_repo, text, author, date ):
90 108 fd, tmpfile = tempfile.mkstemp(prefix="darcs2hg_")
91 109 writefile(tmpfile, text)
110 old_tip = hg_tip(hg_repo)
92 111 cmd("hg add -X _darcs", hg_repo)
93 112 cmd("hg remove -X _darcs --after", hg_repo)
94 cmd("hg commit -l %s -u '%s' -d '%s 0'" % (tmpfile, author, date), hg_repo)
113 res = cmd("hg commit -l %s -u '%s' -d '%s 0'" % (tmpfile, author, date), hg_repo)
95 114 os.unlink(tmpfile)
115 new_tip = hg_tip(hg_repo)
116 if not new_tip == old_tip + 1:
117 # Sometimes we may have empty commits, we simply skip them
118 if res.strip().lower().find("nothing changed") != -1:
119 pass
120 else:
121 error("Mercurial commit did not work as expected: " + res)
122
123 def hg_tip( hg_repo ):
124 """Returns the latest local revision number in the given repository."""
125 tip = cmd("hg tip", hg_repo, silent=True)
126 tip = tip.split("\n")[0].split(":")[1].strip()
127 return int(tip)
96 128
97 129 # ------------------------------------------------------------------------------
98 130 #
@@ -106,26 +138,41 b' if __name__ == "__main__":'
106 138 if len(args) == 2:
107 139 darcs_repo = os.path.abspath(args[0])
108 140 hg_repo = os.path.abspath(args[1])
141 skip = None
142 elif len(args) == 3:
143 darcs_repo = os.path.abspath(args[0])
144 hg_repo = os.path.abspath(args[1])
145 skip = int(args[2])
109 146 else:
110 147 print USAGE
111 148 sys.exit(-1)
112 149 # Initializes the target repo
113 150 if not os.path.isdir(darcs_repo + "/_darcs"):
114 print "No darcs directory found at: " + darc_repo
151 print "No darcs directory found at: " + darcs_repo
115 152 sys.exit(-1)
116 153 if not os.path.isdir(hg_repo):
117 154 os.mkdir(hg_repo)
118 else:
119 print "Given HG repository must not exist. It will be created"
155 elif skip == None:
156 print "Given HG repository must not exist when no SKIP is specified."
120 157 sys.exit(-1)
158 if skip == None:
121 159 cmd("hg init '%s'" % (hg_repo))
122 160 cmd("darcs initialize", hg_repo)
123 161 # Get the changes from the Darcs repository
124 for hash, author, date, summary, description in darcs_changes(darcs_repo):
162 change_number = 0
163 for author, date, summary, chash, description in darcs_changes(darcs_repo):
164 print "== changeset", change_number,
165 if skip != None and change_number <= skip:
166 print "(skipping)"
167 else:
125 168 text = summary + "\n" + description
126 darcs_pull(hg_repo, darcs_repo, hash)
169 darcs_pull(hg_repo, darcs_repo, chash)
170 # The commit hash has a date like 20021020201112
171 # --------------------------------YYYYMMDDHHMMSS
172 date = chash.split("-")[0]
127 173 epoch = int(mktime(strptime(date, '%Y%m%d%H%M%S')))
128 174 hg_commit(hg_repo, text, author, epoch)
175 change_number += 1
176 print "Darcs repository (_darcs) was not deleted. You can keep or remove it."
129 177
130 178 # EOF
131
General Comments 0
You need to be logged in to leave comments. Login now