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