##// END OF EJS Templates
convert: use git executable only, with subcommands...
Dhruva Krishnamurthy -
r6837:e30c56f3 default
parent child Browse files
Show More
@@ -1,142 +1,142
1 # git support for the convert extension
1 # git support for the convert extension
2
2
3 import os
3 import os
4 from mercurial import util
4 from mercurial import util
5
5
6 from common import NoRepo, commit, converter_source, checktool
6 from common import NoRepo, commit, converter_source, checktool
7
7
8 class convert_git(converter_source):
8 class convert_git(converter_source):
9 # Windows does not support GIT_DIR= construct while other systems
9 # Windows does not support GIT_DIR= construct while other systems
10 # cannot remove environment variable. Just assume none have
10 # cannot remove environment variable. Just assume none have
11 # both issues.
11 # both issues.
12 if hasattr(os, 'unsetenv'):
12 if hasattr(os, 'unsetenv'):
13 def gitcmd(self, s):
13 def gitcmd(self, s):
14 prevgitdir = os.environ.get('GIT_DIR')
14 prevgitdir = os.environ.get('GIT_DIR')
15 os.environ['GIT_DIR'] = self.path
15 os.environ['GIT_DIR'] = self.path
16 try:
16 try:
17 return util.popen(s)
17 return util.popen(s)
18 finally:
18 finally:
19 if prevgitdir is None:
19 if prevgitdir is None:
20 del os.environ['GIT_DIR']
20 del os.environ['GIT_DIR']
21 else:
21 else:
22 os.environ['GIT_DIR'] = prevgitdir
22 os.environ['GIT_DIR'] = prevgitdir
23 else:
23 else:
24 def gitcmd(self, s):
24 def gitcmd(self, s):
25 return util.popen('GIT_DIR=%s %s' % (self.path, s))
25 return util.popen('GIT_DIR=%s %s' % (self.path, s))
26
26
27 def __init__(self, ui, path, rev=None):
27 def __init__(self, ui, path, rev=None):
28 super(convert_git, self).__init__(ui, path, rev=rev)
28 super(convert_git, self).__init__(ui, path, rev=rev)
29
29
30 if os.path.isdir(path + "/.git"):
30 if os.path.isdir(path + "/.git"):
31 path += "/.git"
31 path += "/.git"
32 if not os.path.exists(path + "/objects"):
32 if not os.path.exists(path + "/objects"):
33 raise NoRepo("%s does not look like a Git repo" % path)
33 raise NoRepo("%s does not look like a Git repo" % path)
34
34
35 checktool('git-rev-parse', 'git')
35 checktool('git', 'git')
36
36
37 self.path = path
37 self.path = path
38
38
39 def getheads(self):
39 def getheads(self):
40 if not self.rev:
40 if not self.rev:
41 return self.gitcmd('git-rev-parse --branches').read().splitlines()
41 return self.gitcmd('git rev-parse --branches').read().splitlines()
42 else:
42 else:
43 fh = self.gitcmd("git-rev-parse --verify %s" % self.rev)
43 fh = self.gitcmd("git rev-parse --verify %s" % self.rev)
44 return [fh.read()[:-1]]
44 return [fh.read()[:-1]]
45
45
46 def catfile(self, rev, type):
46 def catfile(self, rev, type):
47 if rev == "0" * 40: raise IOError()
47 if rev == "0" * 40: raise IOError()
48 fh = self.gitcmd("git-cat-file %s %s" % (type, rev))
48 fh = self.gitcmd("git cat-file %s %s" % (type, rev))
49 return fh.read()
49 return fh.read()
50
50
51 def getfile(self, name, rev):
51 def getfile(self, name, rev):
52 return self.catfile(rev, "blob")
52 return self.catfile(rev, "blob")
53
53
54 def getmode(self, name, rev):
54 def getmode(self, name, rev):
55 return self.modecache[(name, rev)]
55 return self.modecache[(name, rev)]
56
56
57 def getchanges(self, version):
57 def getchanges(self, version):
58 self.modecache = {}
58 self.modecache = {}
59 fh = self.gitcmd("git-diff-tree --root -m -r %s" % version)
59 fh = self.gitcmd("git diff-tree --root -m -r %s" % version)
60 changes = []
60 changes = []
61 seen = {}
61 seen = {}
62 for l in fh:
62 for l in fh:
63 if "\t" not in l:
63 if "\t" not in l:
64 continue
64 continue
65 m, f = l[:-1].split("\t")
65 m, f = l[:-1].split("\t")
66 if f in seen:
66 if f in seen:
67 continue
67 continue
68 seen[f] = 1
68 seen[f] = 1
69 m = m.split()
69 m = m.split()
70 h = m[3]
70 h = m[3]
71 p = (m[1] == "100755")
71 p = (m[1] == "100755")
72 s = (m[1] == "120000")
72 s = (m[1] == "120000")
73 self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
73 self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
74 changes.append((f, h))
74 changes.append((f, h))
75 return (changes, {})
75 return (changes, {})
76
76
77 def getcommit(self, version):
77 def getcommit(self, version):
78 c = self.catfile(version, "commit") # read the commit hash
78 c = self.catfile(version, "commit") # read the commit hash
79 end = c.find("\n\n")
79 end = c.find("\n\n")
80 message = c[end+2:]
80 message = c[end+2:]
81 message = self.recode(message)
81 message = self.recode(message)
82 l = c[:end].splitlines()
82 l = c[:end].splitlines()
83 manifest = l[0].split()[1]
83 manifest = l[0].split()[1]
84 parents = []
84 parents = []
85 for e in l[1:]:
85 for e in l[1:]:
86 n, v = e.split(" ", 1)
86 n, v = e.split(" ", 1)
87 if n == "author":
87 if n == "author":
88 p = v.split()
88 p = v.split()
89 tm, tz = p[-2:]
89 tm, tz = p[-2:]
90 author = " ".join(p[:-2])
90 author = " ".join(p[:-2])
91 if author[0] == "<": author = author[1:-1]
91 if author[0] == "<": author = author[1:-1]
92 author = self.recode(author)
92 author = self.recode(author)
93 if n == "committer":
93 if n == "committer":
94 p = v.split()
94 p = v.split()
95 tm, tz = p[-2:]
95 tm, tz = p[-2:]
96 committer = " ".join(p[:-2])
96 committer = " ".join(p[:-2])
97 if committer[0] == "<": committer = committer[1:-1]
97 if committer[0] == "<": committer = committer[1:-1]
98 committer = self.recode(committer)
98 committer = self.recode(committer)
99 message += "\ncommitter: %s\n" % committer
99 message += "\ncommitter: %s\n" % committer
100 if n == "parent": parents.append(v)
100 if n == "parent": parents.append(v)
101
101
102 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
102 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
103 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
103 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
104 date = tm + " " + str(tz)
104 date = tm + " " + str(tz)
105
105
106 c = commit(parents=parents, date=date, author=author, desc=message,
106 c = commit(parents=parents, date=date, author=author, desc=message,
107 rev=version)
107 rev=version)
108 return c
108 return c
109
109
110 def gettags(self):
110 def gettags(self):
111 tags = {}
111 tags = {}
112 fh = self.gitcmd('git-ls-remote --tags "%s"' % self.path)
112 fh = self.gitcmd('git ls-remote --tags "%s"' % self.path)
113 prefix = 'refs/tags/'
113 prefix = 'refs/tags/'
114 for line in fh:
114 for line in fh:
115 line = line.strip()
115 line = line.strip()
116 if not line.endswith("^{}"):
116 if not line.endswith("^{}"):
117 continue
117 continue
118 node, tag = line.split(None, 1)
118 node, tag = line.split(None, 1)
119 if not tag.startswith(prefix):
119 if not tag.startswith(prefix):
120 continue
120 continue
121 tag = tag[len(prefix):-3]
121 tag = tag[len(prefix):-3]
122 tags[tag] = node
122 tags[tag] = node
123
123
124 return tags
124 return tags
125
125
126 def getchangedfiles(self, version, i):
126 def getchangedfiles(self, version, i):
127 changes = []
127 changes = []
128 if i is None:
128 if i is None:
129 fh = self.gitcmd("git-diff-tree --root -m -r %s" % version)
129 fh = self.gitcmd("git diff-tree --root -m -r %s" % version)
130 for l in fh:
130 for l in fh:
131 if "\t" not in l:
131 if "\t" not in l:
132 continue
132 continue
133 m, f = l[:-1].split("\t")
133 m, f = l[:-1].split("\t")
134 changes.append(f)
134 changes.append(f)
135 fh.close()
135 fh.close()
136 else:
136 else:
137 fh = self.gitcmd('git-diff-tree --name-only --root -r %s "%s^%s" --'
137 fh = self.gitcmd('git diff-tree --name-only --root -r %s "%s^%s" --'
138 % (version, version, i+1))
138 % (version, version, i+1))
139 changes = [f.rstrip('\n') for f in fh]
139 changes = [f.rstrip('\n') for f in fh]
140 fh.close()
140 fh.close()
141
141
142 return changes
142 return changes
General Comments 0
You need to be logged in to leave comments. Login now