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