comparison hgext/convert/__init__.py @ 4532:c3a78a49d7f0

Some small cleanups for convert extension: - repo doesn't need to be imported - util.Abort doesn't need \n - space after comma - long lines - spacing
author Thomas Arendsen Hein <thomas@intevation.de>
date Sat, 09 Jun 2007 13:17:58 +0200
parents d634b61e9cec
children cc9b79216a76
comparison
equal deleted inserted replaced
4531:b51a8138292a 4532:c3a78a49d7f0
4 # 4 #
5 # This software may be used and distributed according to the terms 5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference. 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 import sys, os, zlib, sha, time, re, locale, socket 8 import sys, os, zlib, sha, time, re, locale, socket
9 from mercurial import hg, ui, util, commands, repo 9 from mercurial import hg, ui, util, commands
10 10
11 commands.norepo += " convert" 11 commands.norepo += " convert"
12 12
13 class NoRepo(Exception): pass 13 class NoRepo(Exception): pass
14 14
15 class commit(object): 15 class commit(object):
16 def __init__(self, **parts): 16 def __init__(self, **parts):
17 for x in "author date desc parents".split(): 17 for x in "author date desc parents".split():
18 if not x in parts: 18 if not x in parts:
19 raise util.Abort("commit missing field %s\n" % x) 19 raise util.Abort("commit missing field %s" % x)
20 self.__dict__.update(parts) 20 self.__dict__.update(parts)
21 21
22 def recode(s): 22 def recode(s):
23 try: 23 try:
24 return s.decode("utf-8").encode("utf-8") 24 return s.decode("utf-8").encode("utf-8")
146 elif l.startswith("Date"): 146 elif l.startswith("Date"):
147 date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"]) 147 date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"])
148 date = util.datestr(date) 148 date = util.datestr(date)
149 elif l.startswith("Branch"): 149 elif l.startswith("Branch"):
150 branch = l[8:-1] 150 branch = l[8:-1]
151 self.parent[id] = self.lastbranch.get(branch,'bad') 151 self.parent[id] = self.lastbranch.get(branch, 'bad')
152 self.lastbranch[branch] = id 152 self.lastbranch[branch] = id
153 elif l.startswith("Ancestor branch"): 153 elif l.startswith("Ancestor branch"):
154 ancestor = l[17:-1] 154 ancestor = l[17:-1]
155 self.parent[id] = self.lastbranch[ancestor] 155 self.parent[id] = self.lastbranch[ancestor]
156 elif l.startswith("Author"): 156 elif l.startswith("Author"):
202 202
203 self.ui.status("connecting to %s\n" % root) 203 self.ui.status("connecting to %s\n" % root)
204 204
205 if root.startswith(":pserver:"): 205 if root.startswith(":pserver:"):
206 root = root[9:] 206 root = root[9:]
207 m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?(.*)', root) 207 m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?(.*)',
208 root)
208 if m: 209 if m:
209 conntype = "pserver" 210 conntype = "pserver"
210 user, passw, serv, port, root = m.groups() 211 user, passw, serv, port, root = m.groups()
211 if not user: 212 if not user:
212 user = "anonymous" 213 user = "anonymous"
230 break 231 break
231 pf.close() 232 pf.close()
232 233
233 sck = socket.socket() 234 sck = socket.socket()
234 sck.connect((serv, port)) 235 sck.connect((serv, port))
235 sck.send("\n".join(["BEGIN AUTH REQUEST", root, user, passw, "END AUTH REQUEST", ""])) 236 sck.send("\n".join(["BEGIN AUTH REQUEST", root, user, passw,
237 "END AUTH REQUEST", ""]))
236 if sck.recv(128) != "I LOVE YOU\n": 238 if sck.recv(128) != "I LOVE YOU\n":
237 raise NoRepo("CVS pserver authentication failed") 239 raise NoRepo("CVS pserver authentication failed")
238 240
239 self.writep = self.readp = sck.makefile('r+') 241 self.writep = self.readp = sck.makefile('r+')
240 242
271 " Merged Removed\n") 273 " Merged Removed\n")
272 self.writep.write("valid-requests\n") 274 self.writep.write("valid-requests\n")
273 self.writep.flush() 275 self.writep.flush()
274 r = self.readp.readline() 276 r = self.readp.readline()
275 if not r.startswith("Valid-requests"): 277 if not r.startswith("Valid-requests"):
276 raise util.Abort("server sucks\n") 278 raise util.Abort("server sucks")
277 if "UseUnchanged" in r: 279 if "UseUnchanged" in r:
278 self.writep.write("UseUnchanged\n") 280 self.writep.write("UseUnchanged\n")
279 self.writep.flush() 281 self.writep.flush()
280 r = self.readp.readline() 282 r = self.readp.readline()
281 283
316 self.ui.warn("cvs server: %s\n" % line[2:]) 318 self.ui.warn("cvs server: %s\n" % line[2:])
317 elif line.startswith("Remove"): 319 elif line.startswith("Remove"):
318 l = self.readp.readline() 320 l = self.readp.readline()
319 l = self.readp.readline() 321 l = self.readp.readline()
320 if l != "ok\n": 322 if l != "ok\n":
321 raise util.Abort("unknown CVS response: %s\n" % l) 323 raise util.Abort("unknown CVS response: %s" % l)
322 else: 324 else:
323 raise util.Abort("unknown CVS response: %s\n" % line) 325 raise util.Abort("unknown CVS response: %s" % line)
324 326
325 def getfile(self, file, rev): 327 def getfile(self, file, rev):
326 data, mode = self._getfile(file, rev) 328 data, mode = self._getfile(file, rev)
327 self.modecache[(file, rev)] = mode 329 self.modecache[(file, rev)] = mode
328 return data 330 return data
359 fh = os.popen("GIT_DIR=%s git-rev-parse --verify HEAD" % self.path) 361 fh = os.popen("GIT_DIR=%s git-rev-parse --verify HEAD" % self.path)
360 return [fh.read()[:-1]] 362 return [fh.read()[:-1]]
361 363
362 def catfile(self, rev, type): 364 def catfile(self, rev, type):
363 if rev == "0" * 40: raise IOError() 365 if rev == "0" * 40: raise IOError()
364 fh = os.popen("GIT_DIR=%s git-cat-file %s %s 2>/dev/null" % (self.path, type, rev)) 366 fh = os.popen("GIT_DIR=%s git-cat-file %s %s 2>/dev/null"
367 % (self.path, type, rev))
365 return fh.read() 368 return fh.read()
366 369
367 def getfile(self, name, rev): 370 def getfile(self, name, rev):
368 return self.catfile(rev, "blob") 371 return self.catfile(rev, "blob")
369 372
370 def getmode(self, name, rev): 373 def getmode(self, name, rev):
371 return self.modecache[(name, rev)] 374 return self.modecache[(name, rev)]
372 375
373 def getchanges(self, version): 376 def getchanges(self, version):
374 self.modecache = {} 377 self.modecache = {}
375 fh = os.popen("GIT_DIR=%s git-diff-tree --root -m -r %s" % (self.path, version)) 378 fh = os.popen("GIT_DIR=%s git-diff-tree --root -m -r %s"
379 % (self.path, version))
376 changes = [] 380 changes = []
377 for l in fh: 381 for l in fh:
378 if "\t" not in l: continue 382 if "\t" not in l: continue
379 m, f = l[:-1].split("\t") 383 m, f = l[:-1].split("\t")
380 m = m.split() 384 m = m.split()
392 message = recode(message) 396 message = recode(message)
393 l = c[:end].splitlines() 397 l = c[:end].splitlines()
394 manifest = l[0].split()[1] 398 manifest = l[0].split()[1]
395 parents = [] 399 parents = []
396 for e in l[1:]: 400 for e in l[1:]:
397 n,v = e.split(" ", 1) 401 n, v = e.split(" ", 1)
398 if n == "author": 402 if n == "author":
399 p = v.split() 403 p = v.split()
400 tm, tz = p[-2:] 404 tm, tz = p[-2:]
401 author = " ".join(p[:-2]) 405 author = " ".join(p[:-2])
402 if author[0] == "<": author = author[1:-1] 406 if author[0] == "<": author = author[1:-1]
520 524
521 converters = [convert_cvs, convert_git, convert_mercurial] 525 converters = [convert_cvs, convert_git, convert_mercurial]
522 526
523 def converter(ui, path): 527 def converter(ui, path):
524 if not os.path.isdir(path): 528 if not os.path.isdir(path):
525 raise util.Abort("%s: not a directory\n" % path) 529 raise util.Abort("%s: not a directory" % path)
526 for c in converters: 530 for c in converters:
527 try: 531 try:
528 return c(ui, path) 532 return c(ui, path)
529 except NoRepo: 533 except NoRepo:
530 pass 534 pass
531 raise util.Abort("%s: unknown repository type\n" % path) 535 raise util.Abort("%s: unknown repository type" % path)
532 536
533 class convert(object): 537 class convert(object):
534 def __init__(self, ui, source, dest, mapfile, opts): 538 def __init__(self, ui, source, dest, mapfile, opts):
535 539
536 self.source = source 540 self.source = source
608 612
609 if self.opts.get('datesort'): 613 if self.opts.get('datesort'):
610 depth = {} 614 depth = {}
611 for n in s: 615 for n in s:
612 depth[n] = 0 616 depth[n] = 0
613 pl = [p for p in self.commitcache[n].parents if p not in self.map] 617 pl = [p for p in self.commitcache[n].parents
618 if p not in self.map]
614 if pl: 619 if pl:
615 depth[n] = max([depth[p] for p in pl]) + 1 620 depth[n] = max([depth[p] for p in pl]) + 1
616 621
617 s = [(depth[n], self.commitcache[n].date, n) for n in s] 622 s = [(depth[n], self.commitcache[n].date, n) for n in s]
618 s.sort() 623 s.sort()
622 627
623 def copy(self, rev): 628 def copy(self, rev):
624 c = self.commitcache[rev] 629 c = self.commitcache[rev]
625 files = self.source.getchanges(rev) 630 files = self.source.getchanges(rev)
626 631
627 for f,v in files: 632 for f, v in files:
628 try: 633 try:
629 data = self.source.getfile(f, v) 634 data = self.source.getfile(f, v)
630 except IOError, inst: 635 except IOError, inst:
631 self.dest.delfile(f) 636 self.dest.delfile(f)
632 else: 637 else:
633 e = self.source.getmode(f, v) 638 e = self.source.getmode(f, v)
634 self.dest.putfile(f, e, data) 639 self.dest.putfile(f, e, data)
635 640
636 r = [self.map[v] for v in c.parents] 641 r = [self.map[v] for v in c.parents]
637 f = [f for f,v in files] 642 f = [f for f, v in files]
638 self.map[rev] = self.dest.putcommit(f, r, c) 643 self.map[rev] = self.dest.putcommit(f, r, c)
639 file(self.mapfile, "a").write("%s %s\n" % (rev, self.map[rev])) 644 file(self.mapfile, "a").write("%s %s\n" % (rev, self.map[rev]))
640 645
641 def convert(self): 646 def convert(self):
642 self.ui.status("scanning source...\n") 647 self.ui.status("scanning source...\n")
694 be run repeatedly to copy new commits. 699 be run repeatedly to copy new commits.
695 ''' 700 '''
696 701
697 srcc = converter(ui, src) 702 srcc = converter(ui, src)
698 if not hasattr(srcc, "getcommit"): 703 if not hasattr(srcc, "getcommit"):
699 raise util.Abort("%s: can't read from this repo type\n" % src) 704 raise util.Abort("%s: can't read from this repo type" % src)
700 705
701 if not dest: 706 if not dest:
702 dest = src + "-hg" 707 dest = src + "-hg"
703 ui.status("assuming destination %s\n" % dest) 708 ui.status("assuming destination %s\n" % dest)
704 709
706 if os.path.isdir(dest): 711 if os.path.isdir(dest):
707 if len(os.listdir(dest)) > 0: 712 if len(os.listdir(dest)) > 0:
708 try: 713 try:
709 hg.repository(ui, dest) 714 hg.repository(ui, dest)
710 ui.status("destination %s is a Mercurial repository\n" % dest) 715 ui.status("destination %s is a Mercurial repository\n" % dest)
711 except repo.RepoError: 716 except hg.RepoError:
712 raise util.Abort( 717 raise util.Abort(
713 """destination directory %s is not empty. 718 "destination directory %s is not empty.\n"
714 Please specify an empty directory to be initialized or an already initialized 719 "Please specify an empty directory to be initialized\n"
715 mercurial repository 720 "or an already initialized mercurial repository"
716 """ % dest) 721 % dest)
717 else: 722 else:
718 ui.status("initializing destination %s repository\n" % dest) 723 ui.status("initializing destination %s repository\n" % dest)
719 hg.repository(ui, dest, create=True) 724 hg.repository(ui, dest, create=True)
720 elif os.path.exists(dest): 725 elif os.path.exists(dest):
721 raise util.Abort("destination %s exists and is not a directory\n" % dest) 726 raise util.Abort("destination %s exists and is not a directory" % dest)
722 else: 727 else:
723 ui.status("initializing destination %s repository\n" % dest) 728 ui.status("initializing destination %s repository\n" % dest)
724 hg.repository(ui, dest, create=True) 729 hg.repository(ui, dest, create=True)
725 730
726 destc = converter(ui, dest) 731 destc = converter(ui, dest)
727 if not hasattr(destc, "putcommit"): 732 if not hasattr(destc, "putcommit"):
728 raise util.Abort("%s: can't write to this repo type\n" % src) 733 raise util.Abort("%s: can't write to this repo type" % src)
729 734
730 if not mapfile: 735 if not mapfile:
731 try: 736 try:
732 mapfile = destc.mapfile() 737 mapfile = destc.mapfile()
733 except: 738 except:
735 740
736 c = convert(ui, srcc, destc, mapfile, opts) 741 c = convert(ui, srcc, destc, mapfile, opts)
737 c.convert() 742 c.convert()
738 743
739 cmdtable = { 744 cmdtable = {
740 "convert": (_convert, 745 "convert":
741 [('', 'datesort', None, 'try to sort changesets by date')], 746 (_convert,
742 'hg convert [OPTIONS] <src> [dst [map]]'), 747 [('', 'datesort', None, 'try to sort changesets by date')],
748 'hg convert [OPTION]... SOURCE [DEST [MAPFILE]]'),
743 } 749 }