21 import os, time, cStringIO |
21 import os, time, cStringIO |
22 from mercurial.i18n import _ |
22 from mercurial.i18n import _ |
23 from mercurial.node import bin, hex, nullid |
23 from mercurial.node import bin, hex, nullid |
24 from mercurial import hg, util, context, bookmarks, error, scmutil, exchange |
24 from mercurial import hg, util, context, bookmarks, error, scmutil, exchange |
25 |
25 |
26 from common import NoRepo, commit, converter_source, converter_sink |
26 from common import NoRepo, commit, converter_source, converter_sink, mapfile |
27 |
27 |
28 import re |
28 import re |
29 sha1re = re.compile(r'\b[0-9a-f]{12,40}\b') |
29 sha1re = re.compile(r'\b[0-9a-f]{12,40}\b') |
30 |
30 |
31 class mercurial_sink(converter_sink): |
31 class mercurial_sink(converter_sink): |
57 raise NoRepo(_("could not create hg repository %s as sink") |
57 raise NoRepo(_("could not create hg repository %s as sink") |
58 % path) |
58 % path) |
59 self.lock = None |
59 self.lock = None |
60 self.wlock = None |
60 self.wlock = None |
61 self.filemapmode = False |
61 self.filemapmode = False |
|
62 self.subrevmaps = {} |
62 |
63 |
63 def before(self): |
64 def before(self): |
64 self.ui.debug('run hg sink pre-conversion action\n') |
65 self.ui.debug('run hg sink pre-conversion action\n') |
65 self.wlock = self.repo.wlock() |
66 self.wlock = self.repo.wlock() |
66 self.lock = self.repo.lock() |
67 self.lock = self.repo.lock() |
133 else: |
134 else: |
134 continue |
135 continue |
135 fp.write('%s %s\n' % (revid, s[1])) |
136 fp.write('%s %s\n' % (revid, s[1])) |
136 return fp.getvalue() |
137 return fp.getvalue() |
137 |
138 |
|
139 def _rewritesubstate(self, source, data): |
|
140 fp = cStringIO.StringIO() |
|
141 for line in data.splitlines(): |
|
142 s = line.split(' ', 1) |
|
143 if len(s) != 2: |
|
144 continue |
|
145 |
|
146 revid = s[0] |
|
147 subpath = s[1] |
|
148 if revid != hex(nullid): |
|
149 revmap = self.subrevmaps.get(subpath) |
|
150 if revmap is None: |
|
151 revmap = mapfile(self.ui, |
|
152 self.repo.wjoin(subpath, '.hg/shamap')) |
|
153 self.subrevmaps[subpath] = revmap |
|
154 |
|
155 # It is reasonable that one or more of the subrepos don't |
|
156 # need to be converted, in which case they can be cloned |
|
157 # into place instead of converted. Therefore, only warn |
|
158 # once. |
|
159 msg = _('no ".hgsubstate" updates will be made for "%s"\n') |
|
160 if len(revmap) == 0: |
|
161 sub = self.repo.wvfs.reljoin(subpath, '.hg') |
|
162 |
|
163 if self.repo.wvfs.exists(sub): |
|
164 self.ui.warn(msg % subpath) |
|
165 |
|
166 newid = revmap.get(revid) |
|
167 if not newid: |
|
168 if len(revmap) > 0: |
|
169 self.ui.warn(_("%s is missing from %s/.hg/shamap\n") % |
|
170 (revid, subpath)) |
|
171 else: |
|
172 revid = newid |
|
173 |
|
174 fp.write('%s %s\n' % (revid, subpath)) |
|
175 |
|
176 return fp.getvalue() |
|
177 |
138 def putcommit(self, files, copies, parents, commit, source, revmap, full, |
178 def putcommit(self, files, copies, parents, commit, source, revmap, full, |
139 cleanp2): |
179 cleanp2): |
140 files = dict(files) |
180 files = dict(files) |
141 |
181 |
142 def getfilectx(repo, memctx, f): |
182 def getfilectx(repo, memctx, f): |
150 data, mode = source.getfile(f, v) |
190 data, mode = source.getfile(f, v) |
151 if data is None: |
191 if data is None: |
152 return None |
192 return None |
153 if f == '.hgtags': |
193 if f == '.hgtags': |
154 data = self._rewritetags(source, revmap, data) |
194 data = self._rewritetags(source, revmap, data) |
|
195 if f == '.hgsubstate': |
|
196 data = self._rewritesubstate(source, data) |
155 return context.memfilectx(self.repo, f, data, 'l' in mode, |
197 return context.memfilectx(self.repo, f, data, 'l' in mode, |
156 'x' in mode, copies.get(f)) |
198 'x' in mode, copies.get(f)) |
157 |
199 |
158 pl = [] |
200 pl = [] |
159 for p in parents: |
201 for p in parents: |