comparison contrib/convert-repo @ 3955:9af4b853ed4d

convert-repo: add CVS branch support
author Matt Mackall <mpm@selenic.com>
date Fri, 22 Dec 2006 17:59:34 -0600
parents fad134931327
children 558f52943cd2
comparison
equal deleted inserted replaced
3954:fad134931327 3955:9af4b853ed4d
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:
336 os.unlink(self.repo.wjoin(f)) 348 os.unlink(self.repo.wjoin(f))
337 #self.repo.remove([f]) 349 #self.repo.remove([f])
338 except: 350 except:
339 pass 351 pass
340 352
341 def putcommit(self, files, parents, author, dest, text): 353 def putcommit(self, files, parents, commit):
342 seen = {} 354 seen = {}
343 pl = [] 355 pl = []
344 for p in parents: 356 for p in parents:
345 if p not in seen: 357 if p not in seen:
346 pl.append(p) 358 pl.append(p)
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
423 while visit: 442 while visit:
424 n = visit.pop(0) 443 n = visit.pop(0)
425 if n in known or n in self.map: continue 444 if n in known or n in self.map: continue
426 known[n] = 1 445 known[n] = 1
427 self.commitcache[n] = self.source.getcommit(n) 446 self.commitcache[n] = self.source.getcommit(n)
428 cp = self.commitcache[n][0] 447 cp = self.commitcache[n].parents
429 for p in cp: 448 for p in cp:
430 parents.setdefault(n, []).append(p) 449 parents.setdefault(n, []).append(p)
431 visit.append(p) 450 visit.append(p)
432 451
433 return parents 452 return parents
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()
503 c = None 522 c = None
504 523
505 status("converting...\n") 524 status("converting...\n")
506 for c in t: 525 for c in t:
507 num -= 1 526 num -= 1
508 desc = self.commitcache[c][3] 527 desc = self.commitcache[c].desc
509 if "\n" in desc: 528 if "\n" in desc:
510 desc = desc.splitlines()[0] 529 desc = desc.splitlines()[0]
511 status("%d %s\n" % (num, desc)) 530 status("%d %s\n" % (num, desc))
512 self.copy(c) 531 self.copy(c)
513 532