Mercurial > hg > mercurial-crew-with-dirclash
comparison hgext/convert/git.py @ 4534:cc9b79216a76
Split convert extension into common and repository type modules
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Sun, 10 Jun 2007 20:08:47 -0700 |
parents | hgext/convert/__init__.py@c3a78a49d7f0 |
children | 06a0e0557edc |
comparison
equal
deleted
inserted
replaced
4533:36abb07c79d4 | 4534:cc9b79216a76 |
---|---|
1 # git support for the convert extension | |
2 | |
3 import os | |
4 | |
5 from common import NoRepo, commit, converter_source | |
6 | |
7 def recode(s): | |
8 try: | |
9 return s.decode("utf-8").encode("utf-8") | |
10 except: | |
11 try: | |
12 return s.decode("latin-1").encode("utf-8") | |
13 except: | |
14 return s.decode("utf-8", "replace").encode("utf-8") | |
15 | |
16 class convert_git(converter_source): | |
17 def __init__(self, ui, path): | |
18 if os.path.isdir(path + "/.git"): | |
19 path += "/.git" | |
20 self.path = path | |
21 self.ui = ui | |
22 if not os.path.exists(path + "/objects"): | |
23 raise NoRepo("couldn't open GIT repo %s" % path) | |
24 | |
25 def getheads(self): | |
26 fh = os.popen("GIT_DIR=%s git-rev-parse --verify HEAD" % self.path) | |
27 return [fh.read()[:-1]] | |
28 | |
29 def catfile(self, rev, type): | |
30 if rev == "0" * 40: raise IOError() | |
31 fh = os.popen("GIT_DIR=%s git-cat-file %s %s 2>/dev/null" | |
32 % (self.path, type, rev)) | |
33 return fh.read() | |
34 | |
35 def getfile(self, name, rev): | |
36 return self.catfile(rev, "blob") | |
37 | |
38 def getmode(self, name, rev): | |
39 return self.modecache[(name, rev)] | |
40 | |
41 def getchanges(self, version): | |
42 self.modecache = {} | |
43 fh = os.popen("GIT_DIR=%s git-diff-tree --root -m -r %s" | |
44 % (self.path, version)) | |
45 changes = [] | |
46 for l in fh: | |
47 if "\t" not in l: continue | |
48 m, f = l[:-1].split("\t") | |
49 m = m.split() | |
50 h = m[3] | |
51 p = (m[1] == "100755") | |
52 s = (m[1] == "120000") | |
53 self.modecache[(f, h)] = (p and "x") or (s and "l") or "" | |
54 changes.append((f, h)) | |
55 return changes | |
56 | |
57 def getcommit(self, version): | |
58 c = self.catfile(version, "commit") # read the commit hash | |
59 end = c.find("\n\n") | |
60 message = c[end+2:] | |
61 message = recode(message) | |
62 l = c[:end].splitlines() | |
63 manifest = l[0].split()[1] | |
64 parents = [] | |
65 for e in l[1:]: | |
66 n, v = e.split(" ", 1) | |
67 if n == "author": | |
68 p = v.split() | |
69 tm, tz = p[-2:] | |
70 author = " ".join(p[:-2]) | |
71 if author[0] == "<": author = author[1:-1] | |
72 author = recode(author) | |
73 if n == "committer": | |
74 p = v.split() | |
75 tm, tz = p[-2:] | |
76 committer = " ".join(p[:-2]) | |
77 if committer[0] == "<": committer = committer[1:-1] | |
78 committer = recode(committer) | |
79 message += "\ncommitter: %s\n" % committer | |
80 if n == "parent": parents.append(v) | |
81 | |
82 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:] | |
83 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm)) | |
84 date = tm + " " + str(tz) | |
85 | |
86 c = commit(parents=parents, date=date, author=author, desc=message) | |
87 return c | |
88 | |
89 def gettags(self): | |
90 tags = {} | |
91 fh = os.popen('git-ls-remote --tags "%s" 2>/dev/null' % self.path) | |
92 prefix = 'refs/tags/' | |
93 for line in fh: | |
94 line = line.strip() | |
95 if not line.endswith("^{}"): | |
96 continue | |
97 node, tag = line.split(None, 1) | |
98 if not tag.startswith(prefix): | |
99 continue | |
100 tag = tag[len(prefix):-3] | |
101 tags[tag] = node | |
102 | |
103 return tags |