Show More
@@ -6,12 +6,24 b'' | |||
|
6 | 6 | # GNU General Public License version 2 or any later version. |
|
7 | 7 | |
|
8 | 8 | import os |
|
9 | from mercurial import util | |
|
9 | from mercurial import util, config | |
|
10 | 10 | from mercurial.node import hex, nullid |
|
11 | 11 | from mercurial.i18n import _ |
|
12 | 12 | |
|
13 | 13 | from common import NoRepo, commit, converter_source, checktool |
|
14 | 14 | |
|
15 | class submodule(object): | |
|
16 | def __init__(self, path, node, url): | |
|
17 | self.path = path | |
|
18 | self.node = node | |
|
19 | self.url = url | |
|
20 | ||
|
21 | def hgsub(self): | |
|
22 | return "%s = [git]%s" % (self.path, self.url) | |
|
23 | ||
|
24 | def hgsubstate(self): | |
|
25 | return "%s %s" % (self.node, self.path) | |
|
26 | ||
|
15 | 27 | class convert_git(converter_source): |
|
16 | 28 | # Windows does not support GIT_DIR= construct while other systems |
|
17 | 29 | # cannot remove environment variable. Just assume none have |
@@ -55,6 +67,7 b' class convert_git(converter_source):' | |||
|
55 | 67 | checktool('git', 'git') |
|
56 | 68 | |
|
57 | 69 | self.path = path |
|
70 | self.submodules = [] | |
|
58 | 71 | |
|
59 | 72 | def getheads(self): |
|
60 | 73 | if not self.rev: |
@@ -76,16 +89,56 b' class convert_git(converter_source):' | |||
|
76 | 89 | return data |
|
77 | 90 | |
|
78 | 91 | def getfile(self, name, rev): |
|
79 | data = self.catfile(rev, "blob") | |
|
80 | mode = self.modecache[(name, rev)] | |
|
92 | if name == '.hgsub': | |
|
93 | data = '\n'.join([m.hgsub() for m in self.submoditer()]) | |
|
94 | mode = '' | |
|
95 | elif name == '.hgsubstate': | |
|
96 | data = '\n'.join([m.hgsubstate() for m in self.submoditer()]) | |
|
97 | mode = '' | |
|
98 | else: | |
|
99 | data = self.catfile(rev, "blob") | |
|
100 | mode = self.modecache[(name, rev)] | |
|
81 | 101 | return data, mode |
|
82 | 102 | |
|
103 | def submoditer(self): | |
|
104 | null = hex(nullid) | |
|
105 | for m in sorted(self.submodules, key=lambda p: p.path): | |
|
106 | if m.node != null: | |
|
107 | yield m | |
|
108 | ||
|
109 | def parsegitmodules(self, content): | |
|
110 | """Parse the formatted .gitmodules file, example file format: | |
|
111 | [submodule "sub"]\n | |
|
112 | \tpath = sub\n | |
|
113 | \turl = git://giturl\n | |
|
114 | """ | |
|
115 | self.submodules = [] | |
|
116 | c = config.config() | |
|
117 | # Each item in .gitmodules starts with \t that cant be parsed | |
|
118 | c.parse('.gitmodules', content.replace('\t','')) | |
|
119 | for sec in c.sections(): | |
|
120 | s = c[sec] | |
|
121 | if 'url' in s and 'path' in s: | |
|
122 | self.submodules.append(submodule(s['path'], '', s['url'])) | |
|
123 | ||
|
124 | def retrievegitmodules(self, version): | |
|
125 | modules, ret = self.gitread("git show %s:%s" % (version, '.gitmodules')) | |
|
126 | if ret: | |
|
127 | raise util.Abort(_('cannot read submodules config file in %s') % version) | |
|
128 | self.parsegitmodules(modules) | |
|
129 | for m in self.submodules: | |
|
130 | node, ret = self.gitread("git rev-parse %s:%s" % (version, m.path)) | |
|
131 | if ret: | |
|
132 | continue | |
|
133 | m.node = node.strip() | |
|
134 | ||
|
83 | 135 | def getchanges(self, version): |
|
84 | 136 | self.modecache = {} |
|
85 | 137 | fh = self.gitopen("git diff-tree -z --root -m -r %s" % version) |
|
86 | 138 | changes = [] |
|
87 | 139 | seen = set() |
|
88 | 140 | entry = None |
|
141 | subexists = False | |
|
89 | 142 | for l in fh.read().split('\x00'): |
|
90 | 143 | if not entry: |
|
91 | 144 | if not l.startswith(':'): |
@@ -97,15 +150,24 b' class convert_git(converter_source):' | |||
|
97 | 150 | seen.add(f) |
|
98 | 151 | entry = entry.split() |
|
99 | 152 | h = entry[3] |
|
100 | if entry[1] == '160000': | |
|
101 | raise util.Abort('git submodules are not supported!') | |
|
102 | 153 | p = (entry[1] == "100755") |
|
103 | 154 | s = (entry[1] == "120000") |
|
104 | self.modecache[(f, h)] = (p and "x") or (s and "l") or "" | |
|
105 | changes.append((f, h)) | |
|
155 | ||
|
156 | if f == '.gitmodules': | |
|
157 | subexists = True | |
|
158 | changes.append(('.hgsub', '')) | |
|
159 | elif entry[1] == '160000' or entry[0] == ':160000': | |
|
160 | subexists = True | |
|
161 | else: | |
|
162 | self.modecache[(f, h)] = (p and "x") or (s and "l") or "" | |
|
163 | changes.append((f, h)) | |
|
106 | 164 | entry = None |
|
107 | 165 | if fh.close(): |
|
108 | 166 | raise util.Abort(_('cannot read changes in %s') % version) |
|
167 | ||
|
168 | if subexists: | |
|
169 | self.retrievegitmodules(version) | |
|
170 | changes.append(('.hgsubstate', '')) | |
|
109 | 171 | return (changes, {}) |
|
110 | 172 | |
|
111 | 173 | def getcommit(self, version): |
@@ -298,3 +298,50 b' damage git repository and convert again' | |||
|
298 | 298 | $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | \ |
|
299 | 299 | > grep 'abort:' | sed 's/abort:.*/abort:/g' |
|
300 | 300 | abort: |
|
301 | ||
|
302 | test sub modules | |
|
303 | ||
|
304 | $ mkdir git-repo5 | |
|
305 | $ cd git-repo5 | |
|
306 | $ git init-db >/dev/null 2>/dev/null | |
|
307 | $ echo 'sub' >> foo | |
|
308 | $ git add foo | |
|
309 | $ commit -a -m 'addfoo' | |
|
310 | $ BASE=${PWD} | |
|
311 | $ cd .. | |
|
312 | $ mkdir git-repo6 | |
|
313 | $ cd git-repo6 | |
|
314 | $ git init-db >/dev/null 2>/dev/null | |
|
315 | $ git submodule add ${BASE} >/dev/null 2>/dev/null | |
|
316 | $ commit -a -m 'addsubmodule' >/dev/null 2>/dev/null | |
|
317 | $ cd .. | |
|
318 | ||
|
319 | convert sub modules | |
|
320 | $ hg convert git-repo6 git-repo6-hg | |
|
321 | initializing destination git-repo6-hg repository | |
|
322 | scanning source... | |
|
323 | sorting... | |
|
324 | converting... | |
|
325 | 0 addsubmodule | |
|
326 | updating bookmarks | |
|
327 | $ hg -R git-repo6-hg log -v | |
|
328 | changeset: 0:* (glob) | |
|
329 | bookmark: master | |
|
330 | tag: tip | |
|
331 | user: nottest <test@example.org> | |
|
332 | date: Mon Jan 01 00:00:23 2007 +0000 | |
|
333 | files: .hgsub .hgsubstate | |
|
334 | description: | |
|
335 | addsubmodule | |
|
336 | ||
|
337 | committer: test <test@example.org> | |
|
338 | ||
|
339 | ||
|
340 | ||
|
341 | $ cd git-repo6-hg | |
|
342 | $ hg up >/dev/null 2>/dev/null | |
|
343 | $ cat .hgsubstate | |
|
344 | * git-repo5 (glob) | |
|
345 | $ cd git-repo5 | |
|
346 | $ cat foo | |
|
347 | sub |
General Comments 0
You need to be logged in to leave comments.
Login now