Merge lp:~vmiklos/bzr-fastimport/darcs into lp:~bzr/bzr-fastimport/fastimport.dev

Proposed by Miklos Vajna
Status: Merged
Merged at revision: not available
Proposed branch: lp:~vmiklos/bzr-fastimport/darcs
Merge into: lp:~bzr/bzr-fastimport/fastimport.dev
Diff against target: 797 lines
4 files modified
exporters/darcs/darcs-fast-export (+359/-305)
exporters/darcs/darcs-fast-export.txt (+4/-0)
exporters/darcs/t/lib-httpd.sh (+67/-0)
exporters/darcs/t/test2-git-http.sh (+22/-0)
To merge this branch: bzr merge lp:~vmiklos/bzr-fastimport/darcs
Reviewer Review Type Date Requested Status
Ian Clatworthy Approve
Review via email: mp+13776@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Miklos Vajna (vmiklos) wrote :

The external change is the http read support (the relevant testcase was a real challenge ;) ), but internal one is a massive refactoring to a Python class.

lp:~vmiklos/bzr-fastimport/darcs updated
257. By Ian Clatworthy

Get fastimport working on non-chk repositories again for bzr versions after 2.0.0

258. By Ian Clatworthy

Handle multi-level branches

Revision history for this message
Ian Clatworthy (ian-clatworthy) :
review: Approve
lp:~vmiklos/bzr-fastimport/darcs updated
259. By Ian Clatworthy

http read support for darcs-fast-export

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'exporters/darcs/darcs-fast-export'
--- exporters/darcs/darcs-fast-export 2009-09-23 22:09:43 +0000
+++ exporters/darcs/darcs-fast-export 2009-10-22 10:35:17 +0000
@@ -4,7 +4,7 @@
44
5 darcs-fast-export - darcs backend for fast data importers5 darcs-fast-export - darcs backend for fast data importers
66
7 Copyright (c) 2008 Miklos Vajna <vmiklos@frugalware.org>7 Copyright (c) 2008, 2009 Miklos Vajna <vmiklos@frugalware.org>
8 Copyright (c) 2008 Matthias Andree <matthias.andree@gmx.de>8 Copyright (c) 2008 Matthias Andree <matthias.andree@gmx.de>
99
10 This program is free software; you can redistribute it and/or modify10 This program is free software; you can redistribute it and/or modify
@@ -33,312 +33,366 @@
33import subprocess33import subprocess
34import optparse34import optparse
35import re35import re
36import urllib
37import StringIO
3638
37sys = reload(sys)39sys = reload(sys)
38sys.setdefaultencoding("utf-8")40sys.setdefaultencoding("utf-8")
3941
40def __get_zone():42class Handler:
41 now = time.localtime()43 def __init__(self):
42 if time.daylight and now[-1]:44 self.hashes = []
43 offset = time.altzone45 self.authormap = {}
44 else:46 self.export_marks = []
45 offset = time.timezone47 self.import_marks = []
46 hours, minutes = divmod(abs(offset), 3600)48
47 if offset > 0:49 def __get_zone(self):
48 sign = "-"50 now = time.localtime()
49 else:51 if time.daylight and now[-1]:
50 sign = "+"52 offset = time.altzone
51 return sign, hours, minutes53 else:
5254 offset = time.timezone
53def get_zone_str():55 hours, minutes = divmod(abs(offset), 3600)
54 sign, hours, minutes = __get_zone()56 if offset > 0:
55 return "%s%02d%02d" % (sign, hours, minutes // 60)57 sign = "-"
5658 else:
57def get_zone_int():59 sign = "+"
58 sign, hours, minutes = __get_zone()60 return sign, hours, minutes
59 ret = hours*3600+minutes*6061
60 if sign == "-":62 def get_zone_str(self):
61 ret *= -163 sign, hours, minutes = self.__get_zone()
62 return ret64 return "%s%02d%02d" % (sign, hours, minutes // 60)
6365
64def get_patchname(patch):66 def get_zone_int(self):
65 ret = []67 sign, hours, minutes = self.__get_zone()
66 s = ""68 ret = hours*3600+minutes*60
67 if patch.attributes['inverted'].value == 'True':69 if sign == "-":
68 s = "UNDO: "70 ret *= -1
69 cs = patch.getElementsByTagName("name")[0].childNodes71 return ret
70 if cs.length > 0:72
71 ret.append(s + cs[0].data)73 def get_patchname(self, patch):
72 lines = patch.getElementsByTagName("comment")74 ret = []
73 if lines:75 s = ""
74 for i in lines[0].childNodes[0].data.split('\n'):76 if patch.attributes['inverted'].value == 'True':
75 if not i.startswith("Ignore-this: "):77 s = "UNDO: "
76 ret.append(i)78 cs = patch.getElementsByTagName("name")[0].childNodes
77 return "\n".join(ret).encode('utf-8')79 if cs.length > 0:
7880 ret.append(s + cs[0].data)
79def get_author(patch):81 lines = patch.getElementsByTagName("comment")
80 """darcs allows any freeform string, but fast-import has a more82 if lines:
81 strict format, so fix up broken author names here."""83 for i in lines[0].childNodes[0].data.split('\n'):
8284 if not i.startswith("Ignore-this: "):
83 author = patch.attributes['author'].value85 ret.append(i)
84 if author in authormap:86 return "\n".join(ret).encode('utf-8')
85 author = authormap[author]87
86 if not len(author):88 def get_author(self, patch):
87 author = "darcs-fast-export <darcs-fast-export>"89 """darcs allows any freeform string, but fast-import has a more
88 # add missing name90 strict format, so fix up broken author names here."""
89 elif not ">" in author:91
90 author = "%s <%s>" % (author.split('@')[0], author)92 author = patch.attributes['author'].value
91 # avoid double quoting93 if author in self.authormap:
92 elif author[0] == '"' and author[-1] == '"':94 author = self.authormap[author]
93 author = author[1:-1]95 if not len(author):
94 # name after email96 author = "darcs-fast-export <darcs-fast-export>"
95 elif author[-1] != '>':97 # add missing name
96 author = author[author.index('>')+2:] + ' ' + author[:author.index('>')+1]98 elif not ">" in author:
97 return author.encode('utf-8')99 author = "%s <%s>" % (author.split('@')[0], author)
98100 # avoid double quoting
99def get_date(patch):101 elif author[0] == '"' and author[-1] == '"':
100 try:102 author = author[1:-1]
101 date = time.strptime(patch, "%Y%m%d%H%M%S")103 # name after email
102 except ValueError:104 elif author[-1] != '>':
103 date = time.strptime(patch[:19] + patch[-5:], '%a %b %d %H:%M:%S %Y')105 author = author[author.index('>')+2:] + ' ' + author[:author.index('>')+1]
104 return int(time.mktime(date)) + get_zone_int()106 return author.encode('utf-8')
105107
106def progress(s):108 def get_date(self, patch):
107 print "progress [%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), s)
108 sys.stdout.flush()
109
110def log(s):
111 logsock.write("[%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), s))
112 logsock.flush()
113
114hashes = []
115def parse_inventory(sock=None):
116 prev = None
117 nextprev = False
118 buf = []
119 if not sock:
120 sock = open(os.path.join("_darcs", "hashed_inventory"))
121 for i in sock.readlines():
122 if i.startswith("hash"):
123 buf.insert(0, i[6:-1])
124 if i.startswith("Starting with inventory:"):
125 nextprev = True
126 elif nextprev:
127 prev = i[:-1]
128 nextprev = False
129 sock.close()
130 for i in buf:
131 hashes.insert(0, i)
132 if prev:
133 sock = gzip.open(os.path.join("_darcs", "inventories", prev))
134 parse_inventory(sock)
135
136# Option Parser
137usage="%prog [options] darcsrepo"
138opp = optparse.OptionParser(usage=usage)
139opp.add_option("--import-marks", metavar="IFILE",
140 help="read state for incremental imports from IFILE")
141opp.add_option("--export-marks", metavar="OFILE",
142 help="write state for incremental imports from OFILE")
143opp.add_option("--encoding",
144 help="encoding of log [default: %default], if unspecified and input isn't utf-8, guess")
145opp.add_option("--authors-file", metavar="F",
146 help="read author transformations in old=new format from F")
147opp.add_option("--working", metavar="W",
148 help="working directory which is removed at the end of non-incremental conversions")
149opp.add_option("--logfile", metavar="L",
150 help="log file which contains the output of external programs invoked during the conversion")
151opp.add_option("--git-branch", metavar="B",
152 help="git branch [default: refs/heads/master]")
153opp.add_option("--progress", metavar="P",
154 help="insert progress statements after every n commit [default: 100]")
155(options, args) = opp.parse_args()
156if len(args) < 1:
157 opp.error("darcsrepo required")
158
159export_marks = []
160import_marks = []
161if options.import_marks:
162 sock = open(options.import_marks)
163 for i in sock.readlines():
164 line = i.strip()
165 if not len(line):
166 continue
167 import_marks.append(line.split(' ')[1])
168 export_marks.append(line)
169 sock.close()
170
171# read author mapping file in gitauthors format,
172# i. e. in=out (one per # line)
173authormap = {}
174if options.authors_file:
175 sock = open(options.authors_file)
176 authormap = dict([i.strip().split('=',1) for i in sock])
177 sock.close()
178
179origin = os.path.abspath(args[0])
180if options.working:
181 working = os.path.abspath(options.working)
182else:
183 working = "%s.darcs" % origin
184patchfile = "%s.patch" % origin
185if options.logfile:
186 logfile = os.path.abspath(options.logfile)
187else:
188 logfile = "%s.log" % origin
189logsock = open(logfile, "a")
190if options.git_branch:
191 git_branch = options.git_branch
192else:
193 git_branch = "refs/heads/master"
194
195if options.progress:
196 prognum = int(options.progress)
197else:
198 prognum = 100
199
200progress("getting list of patches")
201if not len(import_marks):
202 sock = os.popen("darcs changes --xml --reverse --repo %s" % origin)
203else:
204 sock = os.popen("darcs changes --xml --reverse --repo %s --from-match 'hash %s'" % (origin, import_marks[-1]))
205buf = sock.read()
206sock.close()
207# this is hackish. we need to escape some bad chars, otherwise the xml
208# will not be valid
209buf = buf.replace('\x1b', '^[')
210if options.encoding:
211 xmldoc = xml.dom.minidom.parseString(unicode(buf, options.encoding).encode('utf-8'))
212else:
213 try:
214 xmldoc = xml.dom.minidom.parseString(buf)
215 except xml.parsers.expat.ExpatError:
216 try:109 try:
217 import chardet110 date = time.strptime(patch, "%Y%m%d%H%M%S")
218 except ImportError:111 except ValueError:
219 sys.exit("Error, encoding is not utf-8. Please " +112 date = time.strptime(patch[:19] + patch[-5:], '%a %b %d %H:%M:%S %Y')
220 "either specify it with the --encoding " +113 return int(time.mktime(date)) + self.get_zone_int()
221 "option or install chardet.")114
222 progress("encoding is not utf8, guessing charset")115 def progress(self, s):
223 encoding = chardet.detect(buf)['encoding']116 print "progress [%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), s)
224 progress("detected encoding is %s" % encoding)117 sys.stdout.flush()
225 xmldoc = xml.dom.minidom.parseString(unicode(buf, encoding).encode('utf-8'))118
226sys.stdout.flush()119 def log(self, s):
227120 self.logsock.write("[%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), s))
228darcs2 = False121 self.logsock.flush()
229oldfashionedpatch = True122
230cwd = os.getcwd()123 def parse_inventory(self, sock=None):
231if os.path.exists(os.path.join(origin, "_darcs", "format")):124 prev = None
232 sock = open(os.path.join(origin, "_darcs", "format"))125 nextprev = False
233 format = [x.strip() for x in sock]126 buf = []
234 sock.close()127 if not sock:
235 darcs2 = 'darcs-2' in format128 sock = self.open(os.path.join(self.origin, "_darcs", "hashed_inventory"))
236 oldfashionedpatch = not 'hashed' in format129 for i in sock.readlines():
237if not oldfashionedpatch:130 if i.startswith("hash"):
238 progress("parsing the inventory")131 buf.insert(0, i[6:-1])
239 os.chdir(origin)132 if i.startswith("Starting with inventory:"):
240 parse_inventory()133 nextprev = True
241if not options.import_marks or not os.path.exists(working):134 elif nextprev:
242 # init the tmp darcs repo135 prev = i[:-1]
243 os.mkdir(working)136 nextprev = False
244 os.chdir(working)137 sock.close()
245 if darcs2:138 for i in buf:
246 os.system("darcs init --darcs-2")139 self.hashes.insert(0, i)
247 else:140 if prev:
248 os.system("darcs init --old-fashioned-inventory")141 sock = self.gzip_open(os.path.join(self.origin, "_darcs", "inventories", prev))
249else:142 self.parse_inventory(sock)
250 os.chdir(working)143
251if options.import_marks:144 # this is like gzip.open but supports urls as well
252 sock = os.popen("darcs pull -a --match 'hash %s' %s" % (import_marks[-1], origin))145 def gzip_open(self, path):
253 log("Building/updating working directory:\n%s" % sock.read())146 if os.path.exists(path):
254 sock.close()147 return gzip.open(path)
255148 buf = urllib.urlopen(path).read()
256# this is the number of the NEXT patch149 sock = StringIO.StringIO(buf)
257count = 1150 return gzip.GzipFile(fileobj=sock)
258patches = xmldoc.getElementsByTagName('patch')151
259if len(import_marks):152 # this is like os.path.exists but supports urls as well
260 patches = patches[1:]153 def path_exists(self, path):
261 count = len(import_marks) + 1154 if os.path.exists(path):
262if len(export_marks):155 return True
263 # this is the mark number of the NEXT patch156 else:
264 markcount = int(export_marks[-1].split(' ')[0][1:]) + 1157 return urllib.urlopen(path).getcode() == 200
265else:158
266 markcount = count159 # this is like open, but supports urls as well
267# this may be huge and we need it many times160 def open(self, path):
268patchnum = len(patches)161 if os.path.exists(path):
269162 return open(path)
270if not len(import_marks):163 else:
271 progress("starting export, repo has %d patches" % patchnum)164 return urllib.urlopen(path)
272else:165
273 progress("continuing export, %d patches to convert" % patchnum)166 def handle_opts(self):
274paths = []167 # Option Parser
275for i in patches:168 usage="%prog [options] darcsrepo"
276 # apply the patch169 opp = optparse.OptionParser(usage=usage)
277 hash = i.attributes['hash'].value170 opp.add_option("--import-marks", metavar="IFILE",
278 buf = ["\nNew patches:\n"]171 help="read state for incremental imports from IFILE")
279 if oldfashionedpatch:172 opp.add_option("--export-marks", metavar="OFILE",
280 sock = gzip.open(os.path.join(origin, "_darcs", "patches", hash))173 help="write state for incremental imports from OFILE")
281 else:174 opp.add_option("--encoding",
282 sock = gzip.open(os.path.join(origin, "_darcs", "patches", hashes[count-1]))175 help="encoding of log [default: %default], if unspecified and input isn't utf-8, guess")
283 buf.append(sock.read())176 opp.add_option("--authors-file", metavar="F",
284 sock.close()177 help="read author transformations in old=new format from F")
285 sock = os.popen("darcs changes --context")178 opp.add_option("--working", metavar="W",
286 buf.append(sock.read())179 help="working directory which is removed at the end of non-incremental conversions")
287 sock.close()180 opp.add_option("--logfile", metavar="L",
288 sock = subprocess.Popen(["darcs", "apply", "--allow-conflicts"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)181 help="log file which contains the output of external programs invoked during the conversion")
289 sock.stdin.write("".join(buf))182 opp.add_option("--git-branch", metavar="B",
290 sock.stdin.close()183 help="git branch [default: refs/heads/master]")
291 log("Applying %s:\n%s" % (hash, sock.stdout.read()))184 opp.add_option("--progress", metavar="P",
292 sock.stdout.close()185 help="insert progress statements after every n commit [default: 100]")
293 message = get_patchname(i)186 (self.options, self.args) = opp.parse_args()
294 # export the commit187 if len(self.args) < 1:
295 print "commit %s" % git_branch188 opp.error("darcsrepo required")
296 print "mark :%s" % markcount189
297 if options.export_marks:190 # read author mapping file in gitauthors format,
298 export_marks.append(":%s %s" % (markcount, hash))191 # i. e. in=out (one per # line)
299 date = get_date(i.attributes['date'].value)192 if self.options.authors_file:
300 print "committer %s %s %s" % (get_author(i), date, get_zone_str())193 sock = open(self.options.authors_file)
301 print "data %d\n%s" % (len(message), message)194 self.authormap = dict([i.strip().split('=',1) for i in sock])
302 if markcount > 1:195 sock.close()
303 print "from :%s" % (markcount-1)196
304 # export the files197 if "://" not in self.args[0]:
305 for j in paths:198 self.origin = os.path.abspath(self.args[0])
306 print "D %s" % j199 else:
307 paths = []200 self.origin = self.args[0].strip('/')
308 for (root, dirs, files) in os.walk ("."):201 if self.options.working:
309 for f in files:202 self.working = os.path.abspath(self.options.working)
310 j = os.path.normpath(os.path.join(root, f))203 else:
311 if j.startswith("_darcs") or "-darcs-backup" in j:204 if "://" not in self.origin:
312 continue205 self.working = "%s.darcs" % self.origin
313 paths.append(j)206 else:
314 sock = open(j)207 self.working = "%s.darcs" % os.path.split(self.origin)[-1]
315 buf = sock.read()208 if self.options.logfile:
316 sock.close()209 logfile = os.path.abspath(self.options.logfile)
317 # darcs does not track the executable bit :/210 else:
318 print "M 644 inline %s" % j211 if "://" not in self.origin:
319 print "data %s\n%s" % (len(buf), buf)212 logfile = "%s.log" % self.origin
320 if message[:4] == "TAG ":213 else:
321 tag = re.sub('[^\xe9-\xf8\w.\-]+', '_', message[4:].strip().split('\n')[0]).strip('_')214 logfile = "%s.log" % os.path.split(self.origin)[-1]
322 print "tag %s" % tag215 self.logsock = open(logfile, "a")
323 print "from :%s" % markcount216 if self.options.git_branch:
324 print "tagger %s %s %s" % (get_author(i), date, get_zone_str())217 self.git_branch = self.options.git_branch
325 print "data %d\n%s" % (len(message), message)218 else:
326 if count % prognum == 0:219 self.git_branch = "refs/heads/master"
327 progress("%d/%d patches" % (count, patchnum))220
328 count += 1221 if self.options.progress:
329 markcount += 1222 self.prognum = int(self.options.progress)
330223 else:
331os.chdir(cwd)224 self.prognum = 100
332225
333if not options.export_marks:226 def handle_import_marks(self):
334 shutil.rmtree(working)227 if self.options.import_marks:
335logsock.close()228 sock = open(self.options.import_marks)
336229 for i in sock.readlines():
337if options.export_marks:230 line = i.strip()
338 progress("writing export marks")231 if not len(line):
339 sock = open(options.export_marks, 'w')232 continue
340 sock.write("\n".join(export_marks))233 self.import_marks.append(line.split(' ')[1])
341 sock.write("\n")234 self.export_marks.append(line)
342 sock.close()235 sock.close()
343236
344progress("finished")237 def get_patches(self):
238 self.progress("getting list of patches")
239 if not len(self.import_marks):
240 sock = os.popen("darcs changes --xml --reverse --repo %s" % self.origin)
241 else:
242 sock = os.popen("darcs changes --xml --reverse --repo %s --from-match 'hash %s'" % (self.origin, self.import_marks[-1]))
243 buf = sock.read()
244 sock.close()
245 # this is hackish. we need to escape some bad chars, otherwise the xml
246 # will not be valid
247 buf = buf.replace('\x1b', '^[')
248 if self.options.encoding:
249 xmldoc = xml.dom.minidom.parseString(unicode(buf, self.options.encoding).encode('utf-8'))
250 else:
251 try:
252 xmldoc = xml.dom.minidom.parseString(buf)
253 except xml.parsers.expat.ExpatError:
254 try:
255 import chardet
256 except ImportError:
257 sys.exit("Error, encoding is not utf-8. Please " +
258 "either specify it with the --encoding " +
259 "option or install chardet.")
260 self.progress("encoding is not utf8, guessing charset")
261 encoding = chardet.detect(buf)['encoding']
262 self.progress("detected encoding is %s" % encoding)
263 xmldoc = xml.dom.minidom.parseString(unicode(buf, encoding).encode('utf-8'))
264 sys.stdout.flush()
265 return xmldoc.getElementsByTagName('patch')
266
267 def setup_workdir(self):
268 darcs2 = False
269 self.oldfashionedpatch = True
270 self.cwd = os.getcwd()
271 if self.path_exists(os.path.join(self.origin, "_darcs", "format")):
272 sock = self.open(os.path.join(self.origin, "_darcs", "format"))
273 format = [x.strip() for x in sock]
274 sock.close()
275 darcs2 = 'darcs-2' in format
276 self.oldfashionedpatch = not 'hashed' in format
277 if not self.oldfashionedpatch:
278 self.progress("parsing the inventory")
279 if "://" not in self.origin:
280 os.chdir(self.origin)
281 self.parse_inventory()
282 if not self.options.import_marks or not os.path.exists(self.working):
283 # init the tmp darcs repo
284 os.mkdir(self.working)
285 os.chdir(self.working)
286 if darcs2:
287 os.system("darcs init --darcs-2")
288 else:
289 os.system("darcs init --old-fashioned-inventory")
290 else:
291 os.chdir(self.working)
292 if self.options.import_marks:
293 sock = os.popen("darcs pull -a --match 'hash %s' %s" % (self.import_marks[-1], self.origin))
294 self.log("Building/updating working directory:\n%s" % sock.read())
295 sock.close()
296
297 def export_patches(self):
298 patches = self.get_patches()
299 # this is the number of the NEXT patch
300 count = 1
301 if len(self.import_marks):
302 patches = patches[1:]
303 count = len(self.import_marks) + 1
304 if len(self.export_marks):
305 # this is the mark number of the NEXT patch
306 markcount = int(self.export_marks[-1].split(' ')[0][1:]) + 1
307 else:
308 markcount = count
309 # this may be huge and we need it many times
310 patchnum = len(patches)
311
312 if not len(self.import_marks):
313 self.progress("starting export, repo has %d patches" % patchnum)
314 else:
315 self.progress("continuing export, %d patches to convert" % patchnum)
316 paths = []
317 for i in patches:
318 # apply the patch
319 hash = i.attributes['hash'].value
320 buf = ["\nNew patches:\n"]
321 if self.oldfashionedpatch:
322 sock = self.gzip_open(os.path.join(self.origin, "_darcs", "patches", hash))
323 else:
324 sock = self.gzip_open(os.path.join(self.origin, "_darcs", "patches", self.hashes[count-1]))
325 buf.append(sock.read())
326 sock.close()
327 sock = os.popen("darcs changes --context")
328 buf.append(sock.read())
329 sock.close()
330 sock = subprocess.Popen(["darcs", "apply", "--allow-conflicts"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
331 sock.stdin.write("".join(buf))
332 sock.stdin.close()
333 self.log("Applying %s:\n%s" % (hash, sock.stdout.read()))
334 sock.stdout.close()
335 message = self.get_patchname(i)
336 # export the commit
337 print "commit %s" % self.git_branch
338 print "mark :%s" % markcount
339 if self.options.export_marks:
340 self.export_marks.append(":%s %s" % (markcount, hash))
341 date = self.get_date(i.attributes['date'].value)
342 print "committer %s %s %s" % (self.get_author(i), date, self.get_zone_str())
343 print "data %d\n%s" % (len(message), message)
344 if markcount > 1:
345 print "from :%s" % (markcount-1)
346 # export the files
347 for j in paths:
348 print "D %s" % j
349 paths = []
350 for (root, dirs, files) in os.walk ("."):
351 for f in files:
352 j = os.path.normpath(os.path.join(root, f))
353 if j.startswith("_darcs") or "-darcs-backup" in j:
354 continue
355 paths.append(j)
356 sock = open(j)
357 buf = sock.read()
358 sock.close()
359 # darcs does not track the executable bit :/
360 print "M 644 inline %s" % j
361 print "data %s\n%s" % (len(buf), buf)
362 if message[:4] == "TAG ":
363 tag = re.sub('[^\xe9-\xf8\w.\-]+', '_', message[4:].strip().split('\n')[0]).strip('_')
364 print "tag %s" % tag
365 print "from :%s" % markcount
366 print "tagger %s %s %s" % (self.get_author(i), date, self.get_zone_str())
367 print "data %d\n%s" % (len(message), message)
368 if count % self.prognum == 0:
369 self.progress("%d/%d patches" % (count, patchnum))
370 count += 1
371 markcount += 1
372
373 os.chdir(self.cwd)
374
375 if not self.options.export_marks:
376 shutil.rmtree(self.working)
377 self.logsock.close()
378
379 def handle_export_marks(self):
380 if self.options.export_marks:
381 self.progress("writing export marks")
382 sock = open(self.options.export_marks, 'w')
383 sock.write("\n".join(self.export_marks))
384 sock.write("\n")
385 sock.close()
386
387 self.progress("finished")
388
389 def handle(self):
390 self.handle_opts()
391 self.handle_import_marks()
392 self.setup_workdir()
393 self.export_patches()
394 self.handle_export_marks()
395
396if __name__ == "__main__":
397 h = Handler()
398 h.handle()
345399
=== modified file 'exporters/darcs/darcs-fast-export.txt'
--- exporters/darcs/darcs-fast-export.txt 2009-08-10 22:20:43 +0000
+++ exporters/darcs/darcs-fast-export.txt 2009-10-22 10:35:17 +0000
@@ -18,6 +18,10 @@
18repository. It supports incremental conversion as well, via the18repository. It supports incremental conversion as well, via the
19--import-marks / --export-marks switches.19--import-marks / --export-marks switches.
2020
21Optionally the darcsrepo string may be a HTTP repository, in that case
22only the patches are downloaded, not the pristine, speeding up a
23one-time import.
24
21== OPTIONS25== OPTIONS
2226
23-h, --help::27-h, --help::
2428
=== added file 'exporters/darcs/t/lib-httpd.sh'
--- exporters/darcs/t/lib-httpd.sh 1970-01-01 00:00:00 +0000
+++ exporters/darcs/t/lib-httpd.sh 2009-10-22 10:35:18 +0000
@@ -0,0 +1,67 @@
1#!/bin/sh
2#
3# This is based on git's t/lib-httpd.sh, which is
4# Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at>
5#
6
7if test -n "$DFE_TEST_SKIP_HTTPD"
8then
9 echo "skipping test (undef DFE_TEST_SKIP_HTTPD to enable)"
10 exit
11fi
12
13LIB_HTTPD_PATH=${LIB_HTTPD_PATH-'/usr/sbin/httpd'}
14LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'8111'}
15
16HTTPD_ROOT_PATH="$PWD"/httpd
17HTTPD_DOCUMENT_ROOT_PATH=$HTTPD_ROOT_PATH/www
18
19if ! test -x "$LIB_HTTPD_PATH"
20then
21 echo "skipping test, no web server found at '$LIB_HTTPD_PATH'"
22 exit
23fi
24
25HTTPD_VERSION=`$LIB_HTTPD_PATH -v | \
26 sed -n 's/^Server version: Apache\/\([0-9]*\)\..*$/\1/p; q'`
27
28if test -n "$HTTPD_VERSION"
29then
30 if test -z "$LIB_HTTPD_MODULE_PATH"
31 then
32 if ! test $HTTPD_VERSION -ge 2
33 then
34 echo "skipping test, at least Apache version 2 is required"
35 exit
36 fi
37
38 LIB_HTTPD_MODULE_PATH='/usr/lib/apache'
39 fi
40else
41 error "Could not identify web server at '$LIB_HTTPD_PATH'"
42fi
43
44HTTPD_PARA="-d $HTTPD_ROOT_PATH -f $HTTPD_ROOT_PATH/apache.conf"
45
46prepare_httpd() {
47 mkdir -p $HTTPD_DOCUMENT_ROOT_PATH
48
49 ln -s $LIB_HTTPD_MODULE_PATH $HTTPD_ROOT_PATH/modules
50
51 echo "PidFile httpd.pid" > $HTTPD_ROOT_PATH/apache.conf
52 echo "DocumentRoot www" >> $HTTPD_ROOT_PATH/apache.conf
53 echo "ErrorLog error.log" >> $HTTPD_ROOT_PATH/apache.conf
54
55 HTTPD_URL=http://127.0.0.1:$LIB_HTTPD_PORT
56}
57
58start_httpd() {
59 prepare_httpd
60
61 "$LIB_HTTPD_PATH" $HTTPD_PARA \
62 -c "Listen 127.0.0.1:$LIB_HTTPD_PORT" -k start
63}
64
65stop_httpd() {
66 "$LIB_HTTPD_PATH" $HTTPD_PARA -k stop
67}
068
=== added file 'exporters/darcs/t/test2-git-http.sh'
--- exporters/darcs/t/test2-git-http.sh 1970-01-01 00:00:00 +0000
+++ exporters/darcs/t/test2-git-http.sh 2009-10-22 10:35:18 +0000
@@ -0,0 +1,22 @@
1. ./lib.sh
2. ./lib-httpd.sh
3
4rm -rf test2.darcs test2.git httpd
5create_darcs test2 --darcs-2
6mkdir -p $HTTPD_DOCUMENT_ROOT_PATH
7mv -v test2 $HTTPD_DOCUMENT_ROOT_PATH
8ln -s $HTTPD_DOCUMENT_ROOT_PATH/test2 .
9
10mkdir test2.git
11cd test2.git
12git --bare init
13cd ..
14start_httpd
15darcs-fast-export $HTTPD_URL/test2 |(cd test2.git; git fast-import)
16ret=$?
17stop_httpd
18if [ $ret != 0 ]; then
19 exit $ret
20fi
21diff_git test2
22exit $?

Subscribers

People subscribed via source and target branches

to all changes: