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