##// END OF EJS Templates
convert: quote "^" to avoid windows using it as an escape char.
Patrick Mezard -
r5404:67d3daa8 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
6 from common import NoRepo, commit, converter_source
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 os.popen(s)
17 return os.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 os.popen('GIT_DIR=%s %s' % (self.path, s))
25 return os.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("couldn't open GIT repo %s" % path)
33 raise NoRepo("couldn't open GIT repo %s" % path)
34 self.path = path
34 self.path = path
35
35
36 def getheads(self):
36 def getheads(self):
37 if not self.rev:
37 if not self.rev:
38 return self.gitcmd('git-rev-parse --branches').read().splitlines()
38 return self.gitcmd('git-rev-parse --branches').read().splitlines()
39 else:
39 else:
40 fh = self.gitcmd("git-rev-parse --verify %s" % self.rev)
40 fh = self.gitcmd("git-rev-parse --verify %s" % self.rev)
41 return [fh.read()[:-1]]
41 return [fh.read()[:-1]]
42
42
43 def catfile(self, rev, type):
43 def catfile(self, rev, type):
44 if rev == "0" * 40: raise IOError()
44 if rev == "0" * 40: raise IOError()
45 fh = self.gitcmd("git-cat-file %s %s 2>%s" % (type, rev,
45 fh = self.gitcmd("git-cat-file %s %s 2>%s" % (type, rev,
46 util.nulldev))
46 util.nulldev))
47 return fh.read()
47 return fh.read()
48
48
49 def getfile(self, name, rev):
49 def getfile(self, name, rev):
50 return self.catfile(rev, "blob")
50 return self.catfile(rev, "blob")
51
51
52 def getmode(self, name, rev):
52 def getmode(self, name, rev):
53 return self.modecache[(name, rev)]
53 return self.modecache[(name, rev)]
54
54
55 def getchanges(self, version):
55 def getchanges(self, version):
56 self.modecache = {}
56 self.modecache = {}
57 fh = self.gitcmd("git-diff-tree --root -m -r %s" % version)
57 fh = self.gitcmd("git-diff-tree --root -m -r %s" % version)
58 changes = []
58 changes = []
59 seen = {}
59 seen = {}
60 for l in fh:
60 for l in fh:
61 if "\t" not in l:
61 if "\t" not in l:
62 continue
62 continue
63 m, f = l[:-1].split("\t")
63 m, f = l[:-1].split("\t")
64 if f in seen:
64 if f in seen:
65 continue
65 continue
66 seen[f] = 1
66 seen[f] = 1
67 m = m.split()
67 m = m.split()
68 h = m[3]
68 h = m[3]
69 p = (m[1] == "100755")
69 p = (m[1] == "100755")
70 s = (m[1] == "120000")
70 s = (m[1] == "120000")
71 self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
71 self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
72 changes.append((f, h))
72 changes.append((f, h))
73 return (changes, {})
73 return (changes, {})
74
74
75 def getcommit(self, version):
75 def getcommit(self, version):
76 c = self.catfile(version, "commit") # read the commit hash
76 c = self.catfile(version, "commit") # read the commit hash
77 end = c.find("\n\n")
77 end = c.find("\n\n")
78 message = c[end+2:]
78 message = c[end+2:]
79 message = self.recode(message)
79 message = self.recode(message)
80 l = c[:end].splitlines()
80 l = c[:end].splitlines()
81 manifest = l[0].split()[1]
81 manifest = l[0].split()[1]
82 parents = []
82 parents = []
83 for e in l[1:]:
83 for e in l[1:]:
84 n, v = e.split(" ", 1)
84 n, v = e.split(" ", 1)
85 if n == "author":
85 if n == "author":
86 p = v.split()
86 p = v.split()
87 tm, tz = p[-2:]
87 tm, tz = p[-2:]
88 author = " ".join(p[:-2])
88 author = " ".join(p[:-2])
89 if author[0] == "<": author = author[1:-1]
89 if author[0] == "<": author = author[1:-1]
90 author = self.recode(author)
90 author = self.recode(author)
91 if n == "committer":
91 if n == "committer":
92 p = v.split()
92 p = v.split()
93 tm, tz = p[-2:]
93 tm, tz = p[-2:]
94 committer = " ".join(p[:-2])
94 committer = " ".join(p[:-2])
95 if committer[0] == "<": committer = committer[1:-1]
95 if committer[0] == "<": committer = committer[1:-1]
96 committer = self.recode(committer)
96 committer = self.recode(committer)
97 message += "\ncommitter: %s\n" % committer
97 message += "\ncommitter: %s\n" % committer
98 if n == "parent": parents.append(v)
98 if n == "parent": parents.append(v)
99
99
100 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
100 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
101 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
101 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
102 date = tm + " " + str(tz)
102 date = tm + " " + str(tz)
103 author = author or "unknown"
103 author = author or "unknown"
104
104
105 c = commit(parents=parents, date=date, author=author, desc=message,
105 c = commit(parents=parents, date=date, author=author, desc=message,
106 rev=version)
106 rev=version)
107 return c
107 return c
108
108
109 def gettags(self):
109 def gettags(self):
110 tags = {}
110 tags = {}
111 fh = self.gitcmd('git-ls-remote --tags "%s" 2>%s' % (self.path,
111 fh = self.gitcmd('git-ls-remote --tags "%s" 2>%s' % (self.path,
112 util.nulldev))
112 util.nulldev))
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