27 os.environ["HGENCODING"] = "utf-8" |
27 os.environ["HGENCODING"] = "utf-8" |
28 from mercurial import hg, ui, util, fancyopts |
28 from mercurial import hg, ui, util, fancyopts |
29 |
29 |
30 class Abort(Exception): pass |
30 class Abort(Exception): pass |
31 class NoRepo(Exception): pass |
31 class NoRepo(Exception): pass |
|
32 |
|
33 class commit: |
|
34 def __init__(self, **parts): |
|
35 for x in "author date desc parents".split(): |
|
36 if not x in parts: |
|
37 abort("commit missing field %s\n" % x) |
|
38 self.__dict__.update(parts) |
32 |
39 |
33 quiet = 0 |
40 quiet = 0 |
34 def status(msg): |
41 def status(msg): |
35 if not quiet: sys.stdout.write(str(msg)) |
42 if not quiet: sys.stdout.write(str(msg)) |
36 |
43 |
56 cvs = os.path.join(path, "CVS") |
63 cvs = os.path.join(path, "CVS") |
57 if not os.path.exists(cvs): |
64 if not os.path.exists(cvs): |
58 raise NoRepo("couldn't open CVS repo %s" % path) |
65 raise NoRepo("couldn't open CVS repo %s" % path) |
59 |
66 |
60 self.changeset = {} |
67 self.changeset = {} |
|
68 self.files = {} |
61 self.tags = {} |
69 self.tags = {} |
62 self.lastbranch = {} |
70 self.lastbranch = {} |
63 self.parent = {} |
71 self.parent = {} |
64 self.socket = None |
72 self.socket = None |
65 self.cvsroot = file(os.path.join(cvs, "Root")).read()[:-1] |
73 self.cvsroot = file(os.path.join(cvs, "Root")).read()[:-1] |
110 else: |
118 else: |
111 log += l |
119 log += l |
112 elif state == 2: |
120 elif state == 2: |
113 if l == "\n": # |
121 if l == "\n": # |
114 state = 0 |
122 state = 0 |
115 self.changeset[id] = (date, author, log, files) |
123 p = [self.parent[id]] |
|
124 if id == "1": |
|
125 p = [] |
|
126 c = commit(author=author, date=date, parents=p, |
|
127 desc=log, branch=branch) |
|
128 self.changeset[id] = c |
|
129 self.files[id] = files |
116 else: |
130 else: |
117 file,rev = l[1:-2].rsplit(':',1) |
131 file,rev = l[1:-2].rsplit(':',1) |
118 rev = rev.split("->")[1] |
132 rev = rev.split("->")[1] |
119 files[file] = rev |
133 files[file] = rev |
120 |
134 |
214 abort("unknown CVS response: %s\n" % l) |
228 abort("unknown CVS response: %s\n" % l) |
215 else: |
229 else: |
216 abort("unknown CVS response: %s\n" % line) |
230 abort("unknown CVS response: %s\n" % line) |
217 |
231 |
218 def getchanges(self, rev): |
232 def getchanges(self, rev): |
219 files = self.changeset[rev][3] |
233 files = self.files[rev] |
220 cl = [ (f, r, 0) for f,r in files.items() ] |
234 cl = [ (f, r, 0) for f,r in files.items() ] |
221 cl.sort() |
235 cl.sort() |
222 return cl |
236 return cl |
223 |
237 |
224 def recode(self, text): |
238 def recode(self, text): |
225 return text.decode(self.encoding, "replace").encode("utf-8") |
239 return text.decode(self.encoding, "replace").encode("utf-8") |
226 |
240 |
227 def getcommit(self, rev): |
241 def getcommit(self, rev): |
228 cs = self.changeset[rev] |
242 return self.changeset[rev] |
229 parents = [self.parent[rev]] |
|
230 if rev == "1": |
|
231 parents = [] |
|
232 return (parents, cs[1], cs[0], cs[2]) |
|
233 |
243 |
234 def gettags(self): |
244 def gettags(self): |
235 return self.tags |
245 return self.tags |
236 |
246 |
237 class convert_git: |
247 class convert_git: |
292 if n == "parent": parents.append(v) |
302 if n == "parent": parents.append(v) |
293 |
303 |
294 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:] |
304 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:] |
295 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm)) |
305 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm)) |
296 date = tm + " " + str(tz) |
306 date = tm + " " + str(tz) |
297 return (parents, author, date, message) |
307 |
|
308 c = commit(parents=parents, date=date, author=author, desc=message) |
|
309 return c |
298 |
310 |
299 def gettags(self): |
311 def gettags(self): |
300 tags = {} |
312 tags = {} |
301 for f in os.listdir(self.path + "/refs/tags"): |
313 for f in os.listdir(self.path + "/refs/tags"): |
302 try: |
314 try: |
349 |
361 |
350 if len(parents) < 2: parents.append("0" * 40) |
362 if len(parents) < 2: parents.append("0" * 40) |
351 if len(parents) < 2: parents.append("0" * 40) |
363 if len(parents) < 2: parents.append("0" * 40) |
352 p2 = parents.pop(0) |
364 p2 = parents.pop(0) |
353 |
365 |
|
366 text = commit.desc |
|
367 extra = {} |
|
368 try: |
|
369 extra["branch"] = commit.branch |
|
370 except AttributeError: |
|
371 pass |
|
372 |
354 while parents: |
373 while parents: |
355 p1 = p2 |
374 p1 = p2 |
356 p2 = parents.pop(0) |
375 p2 = parents.pop(0) |
357 a = self.repo.rawcommit(files, text, author, dest, |
376 a = self.repo.rawcommit(files, text, commit.author, commit.date, |
358 hg.bin(p1), hg.bin(p2)) |
377 hg.bin(p1), hg.bin(p2), extra=extra) |
359 text = "(octopus merge fixup)\n" |
378 text = "(octopus merge fixup)\n" |
360 p2 = hg.hex(self.repo.changelog.tip()) |
379 p2 = hg.hex(self.repo.changelog.tip()) |
361 |
380 |
362 return p2 |
381 return p2 |
363 |
382 |
474 visit.insert(0, c) |
493 visit.insert(0, c) |
475 |
494 |
476 return s |
495 return s |
477 |
496 |
478 def copy(self, rev): |
497 def copy(self, rev): |
479 p, a, d, t = self.commitcache[rev] |
498 c = self.commitcache[rev] |
480 files = self.source.getchanges(rev) |
499 files = self.source.getchanges(rev) |
481 |
500 |
482 for f,v,e in files: |
501 for f,v,e in files: |
483 try: |
502 try: |
484 data = self.source.getfile(f, v) |
503 data = self.source.getfile(f, v) |
485 except IOError, inst: |
504 except IOError, inst: |
486 self.dest.delfile(f) |
505 self.dest.delfile(f) |
487 else: |
506 else: |
488 self.dest.putfile(f, e, data) |
507 self.dest.putfile(f, e, data) |
489 |
508 |
490 r = [self.map[v] for v in p] |
509 r = [self.map[v] for v in c.parents] |
491 f = [f for f,v,e in files] |
510 f = [f for f,v,e in files] |
492 self.map[rev] = self.dest.putcommit(f, r, a, d, t) |
511 self.map[rev] = self.dest.putcommit(f, r, c) |
493 file(self.mapfile, "a").write("%s %s\n" % (rev, self.map[rev])) |
512 file(self.mapfile, "a").write("%s %s\n" % (rev, self.map[rev])) |
494 |
513 |
495 def convert(self): |
514 def convert(self): |
496 status("scanning source...\n") |
515 status("scanning source...\n") |
497 heads = self.source.getheads() |
516 heads = self.source.getheads() |