##// END OF EJS Templates
convert: use repo.join instead of referencing ".hg" directly
Martin Geisler -
r15069:650d81a3 default
parent child Browse files
Show More
@@ -1,388 +1,387
1 # hg.py - hg backend for convert extension
1 # hg.py - hg backend for convert extension
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 # Notes for hg->hg conversion:
8 # Notes for hg->hg conversion:
9 #
9 #
10 # * Old versions of Mercurial didn't trim the whitespace from the ends
10 # * Old versions of Mercurial didn't trim the whitespace from the ends
11 # of commit messages, but new versions do. Changesets created by
11 # of commit messages, but new versions do. Changesets created by
12 # those older versions, then converted, may thus have different
12 # those older versions, then converted, may thus have different
13 # hashes for changesets that are otherwise identical.
13 # hashes for changesets that are otherwise identical.
14 #
14 #
15 # * Using "--config convert.hg.saverev=true" will make the source
15 # * Using "--config convert.hg.saverev=true" will make the source
16 # identifier to be stored in the converted revision. This will cause
16 # identifier to be stored in the converted revision. This will cause
17 # the converted revision to have a different identity than the
17 # the converted revision to have a different identity than the
18 # source.
18 # source.
19
19
20
20
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
24 from mercurial import hg, util, context, bookmarks, error
25
25
26 from common import NoRepo, commit, converter_source, converter_sink
26 from common import NoRepo, commit, converter_source, converter_sink
27
27
28 class mercurial_sink(converter_sink):
28 class mercurial_sink(converter_sink):
29 def __init__(self, ui, path):
29 def __init__(self, ui, path):
30 converter_sink.__init__(self, ui, path)
30 converter_sink.__init__(self, ui, path)
31 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
31 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
32 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
32 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
33 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
33 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
34 self.lastbranch = None
34 self.lastbranch = None
35 if os.path.isdir(path) and len(os.listdir(path)) > 0:
35 if os.path.isdir(path) and len(os.listdir(path)) > 0:
36 try:
36 try:
37 self.repo = hg.repository(self.ui, path)
37 self.repo = hg.repository(self.ui, path)
38 if not self.repo.local():
38 if not self.repo.local():
39 raise NoRepo(_('%s is not a local Mercurial repository')
39 raise NoRepo(_('%s is not a local Mercurial repository')
40 % path)
40 % path)
41 except error.RepoError, err:
41 except error.RepoError, err:
42 ui.traceback()
42 ui.traceback()
43 raise NoRepo(err.args[0])
43 raise NoRepo(err.args[0])
44 else:
44 else:
45 try:
45 try:
46 ui.status(_('initializing destination %s repository\n') % path)
46 ui.status(_('initializing destination %s repository\n') % path)
47 self.repo = hg.repository(self.ui, path, create=True)
47 self.repo = hg.repository(self.ui, path, create=True)
48 if not self.repo.local():
48 if not self.repo.local():
49 raise NoRepo(_('%s is not a local Mercurial repository')
49 raise NoRepo(_('%s is not a local Mercurial repository')
50 % path)
50 % path)
51 self.created.append(path)
51 self.created.append(path)
52 except error.RepoError:
52 except error.RepoError:
53 ui.traceback()
53 ui.traceback()
54 raise NoRepo(_("could not create hg repository %s as sink")
54 raise NoRepo(_("could not create hg repository %s as sink")
55 % path)
55 % path)
56 self.lock = None
56 self.lock = None
57 self.wlock = None
57 self.wlock = None
58 self.filemapmode = False
58 self.filemapmode = False
59
59
60 def before(self):
60 def before(self):
61 self.ui.debug('run hg sink pre-conversion action\n')
61 self.ui.debug('run hg sink pre-conversion action\n')
62 self.wlock = self.repo.wlock()
62 self.wlock = self.repo.wlock()
63 self.lock = self.repo.lock()
63 self.lock = self.repo.lock()
64
64
65 def after(self):
65 def after(self):
66 self.ui.debug('run hg sink post-conversion action\n')
66 self.ui.debug('run hg sink post-conversion action\n')
67 if self.lock:
67 if self.lock:
68 self.lock.release()
68 self.lock.release()
69 if self.wlock:
69 if self.wlock:
70 self.wlock.release()
70 self.wlock.release()
71
71
72 def revmapfile(self):
72 def revmapfile(self):
73 return os.path.join(self.path, ".hg", "shamap")
73 return self.repo.join("shamap")
74
74
75 def authorfile(self):
75 def authorfile(self):
76 return os.path.join(self.path, ".hg", "authormap")
76 return self.repo.join("authormap")
77
77
78 def getheads(self):
78 def getheads(self):
79 h = self.repo.changelog.heads()
79 h = self.repo.changelog.heads()
80 return [hex(x) for x in h]
80 return [hex(x) for x in h]
81
81
82 def setbranch(self, branch, pbranches):
82 def setbranch(self, branch, pbranches):
83 if not self.clonebranches:
83 if not self.clonebranches:
84 return
84 return
85
85
86 setbranch = (branch != self.lastbranch)
86 setbranch = (branch != self.lastbranch)
87 self.lastbranch = branch
87 self.lastbranch = branch
88 if not branch:
88 if not branch:
89 branch = 'default'
89 branch = 'default'
90 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
90 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
91 pbranch = pbranches and pbranches[0][1] or 'default'
91 pbranch = pbranches and pbranches[0][1] or 'default'
92
92
93 branchpath = os.path.join(self.path, branch)
93 branchpath = os.path.join(self.path, branch)
94 if setbranch:
94 if setbranch:
95 self.after()
95 self.after()
96 try:
96 try:
97 self.repo = hg.repository(self.ui, branchpath)
97 self.repo = hg.repository(self.ui, branchpath)
98 except:
98 except:
99 self.repo = hg.repository(self.ui, branchpath, create=True)
99 self.repo = hg.repository(self.ui, branchpath, create=True)
100 self.before()
100 self.before()
101
101
102 # pbranches may bring revisions from other branches (merge parents)
102 # pbranches may bring revisions from other branches (merge parents)
103 # Make sure we have them, or pull them.
103 # Make sure we have them, or pull them.
104 missings = {}
104 missings = {}
105 for b in pbranches:
105 for b in pbranches:
106 try:
106 try:
107 self.repo.lookup(b[0])
107 self.repo.lookup(b[0])
108 except:
108 except:
109 missings.setdefault(b[1], []).append(b[0])
109 missings.setdefault(b[1], []).append(b[0])
110
110
111 if missings:
111 if missings:
112 self.after()
112 self.after()
113 for pbranch, heads in missings.iteritems():
113 for pbranch, heads in missings.iteritems():
114 pbranchpath = os.path.join(self.path, pbranch)
114 pbranchpath = os.path.join(self.path, pbranch)
115 prepo = hg.peer(self.ui, {}, pbranchpath)
115 prepo = hg.peer(self.ui, {}, pbranchpath)
116 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
116 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
117 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
117 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
118 self.before()
118 self.before()
119
119
120 def _rewritetags(self, source, revmap, data):
120 def _rewritetags(self, source, revmap, data):
121 fp = cStringIO.StringIO()
121 fp = cStringIO.StringIO()
122 for line in data.splitlines():
122 for line in data.splitlines():
123 s = line.split(' ', 1)
123 s = line.split(' ', 1)
124 if len(s) != 2:
124 if len(s) != 2:
125 continue
125 continue
126 revid = revmap.get(source.lookuprev(s[0]))
126 revid = revmap.get(source.lookuprev(s[0]))
127 if not revid:
127 if not revid:
128 continue
128 continue
129 fp.write('%s %s\n' % (revid, s[1]))
129 fp.write('%s %s\n' % (revid, s[1]))
130 return fp.getvalue()
130 return fp.getvalue()
131
131
132 def putcommit(self, files, copies, parents, commit, source, revmap):
132 def putcommit(self, files, copies, parents, commit, source, revmap):
133
133
134 files = dict(files)
134 files = dict(files)
135 def getfilectx(repo, memctx, f):
135 def getfilectx(repo, memctx, f):
136 v = files[f]
136 v = files[f]
137 data, mode = source.getfile(f, v)
137 data, mode = source.getfile(f, v)
138 if f == '.hgtags':
138 if f == '.hgtags':
139 data = self._rewritetags(source, revmap, data)
139 data = self._rewritetags(source, revmap, data)
140 return context.memfilectx(f, data, 'l' in mode, 'x' in mode,
140 return context.memfilectx(f, data, 'l' in mode, 'x' in mode,
141 copies.get(f))
141 copies.get(f))
142
142
143 pl = []
143 pl = []
144 for p in parents:
144 for p in parents:
145 if p not in pl:
145 if p not in pl:
146 pl.append(p)
146 pl.append(p)
147 parents = pl
147 parents = pl
148 nparents = len(parents)
148 nparents = len(parents)
149 if self.filemapmode and nparents == 1:
149 if self.filemapmode and nparents == 1:
150 m1node = self.repo.changelog.read(bin(parents[0]))[0]
150 m1node = self.repo.changelog.read(bin(parents[0]))[0]
151 parent = parents[0]
151 parent = parents[0]
152
152
153 if len(parents) < 2:
153 if len(parents) < 2:
154 parents.append(nullid)
154 parents.append(nullid)
155 if len(parents) < 2:
155 if len(parents) < 2:
156 parents.append(nullid)
156 parents.append(nullid)
157 p2 = parents.pop(0)
157 p2 = parents.pop(0)
158
158
159 text = commit.desc
159 text = commit.desc
160 extra = commit.extra.copy()
160 extra = commit.extra.copy()
161 if self.branchnames and commit.branch:
161 if self.branchnames and commit.branch:
162 extra['branch'] = commit.branch
162 extra['branch'] = commit.branch
163 if commit.rev:
163 if commit.rev:
164 extra['convert_revision'] = commit.rev
164 extra['convert_revision'] = commit.rev
165
165
166 while parents:
166 while parents:
167 p1 = p2
167 p1 = p2
168 p2 = parents.pop(0)
168 p2 = parents.pop(0)
169 ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
169 ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
170 getfilectx, commit.author, commit.date, extra)
170 getfilectx, commit.author, commit.date, extra)
171 self.repo.commitctx(ctx)
171 self.repo.commitctx(ctx)
172 text = "(octopus merge fixup)\n"
172 text = "(octopus merge fixup)\n"
173 p2 = hex(self.repo.changelog.tip())
173 p2 = hex(self.repo.changelog.tip())
174
174
175 if self.filemapmode and nparents == 1:
175 if self.filemapmode and nparents == 1:
176 man = self.repo.manifest
176 man = self.repo.manifest
177 mnode = self.repo.changelog.read(bin(p2))[0]
177 mnode = self.repo.changelog.read(bin(p2))[0]
178 closed = 'close' in commit.extra
178 closed = 'close' in commit.extra
179 if not closed and not man.cmp(m1node, man.revision(mnode)):
179 if not closed and not man.cmp(m1node, man.revision(mnode)):
180 self.ui.status(_("filtering out empty revision\n"))
180 self.ui.status(_("filtering out empty revision\n"))
181 self.repo.rollback()
181 self.repo.rollback()
182 return parent
182 return parent
183 return p2
183 return p2
184
184
185 def puttags(self, tags):
185 def puttags(self, tags):
186 try:
186 try:
187 parentctx = self.repo[self.tagsbranch]
187 parentctx = self.repo[self.tagsbranch]
188 tagparent = parentctx.node()
188 tagparent = parentctx.node()
189 except error.RepoError:
189 except error.RepoError:
190 parentctx = None
190 parentctx = None
191 tagparent = nullid
191 tagparent = nullid
192
192
193 try:
193 try:
194 oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
194 oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
195 except:
195 except:
196 oldlines = []
196 oldlines = []
197
197
198 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
198 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
199 if newlines == oldlines:
199 if newlines == oldlines:
200 return None, None
200 return None, None
201 data = "".join(newlines)
201 data = "".join(newlines)
202 def getfilectx(repo, memctx, f):
202 def getfilectx(repo, memctx, f):
203 return context.memfilectx(f, data, False, False, None)
203 return context.memfilectx(f, data, False, False, None)
204
204
205 self.ui.status(_("updating tags\n"))
205 self.ui.status(_("updating tags\n"))
206 date = "%s 0" % int(time.mktime(time.gmtime()))
206 date = "%s 0" % int(time.mktime(time.gmtime()))
207 extra = {'branch': self.tagsbranch}
207 extra = {'branch': self.tagsbranch}
208 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
208 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
209 [".hgtags"], getfilectx, "convert-repo", date,
209 [".hgtags"], getfilectx, "convert-repo", date,
210 extra)
210 extra)
211 self.repo.commitctx(ctx)
211 self.repo.commitctx(ctx)
212 return hex(self.repo.changelog.tip()), hex(tagparent)
212 return hex(self.repo.changelog.tip()), hex(tagparent)
213
213
214 def setfilemapmode(self, active):
214 def setfilemapmode(self, active):
215 self.filemapmode = active
215 self.filemapmode = active
216
216
217 def putbookmarks(self, updatedbookmark):
217 def putbookmarks(self, updatedbookmark):
218 if not len(updatedbookmark):
218 if not len(updatedbookmark):
219 return
219 return
220
220
221 self.ui.status(_("updating bookmarks\n"))
221 self.ui.status(_("updating bookmarks\n"))
222 for bookmark in updatedbookmark:
222 for bookmark in updatedbookmark:
223 self.repo._bookmarks[bookmark] = bin(updatedbookmark[bookmark])
223 self.repo._bookmarks[bookmark] = bin(updatedbookmark[bookmark])
224 bookmarks.write(self.repo)
224 bookmarks.write(self.repo)
225
225
226
226
227 class mercurial_source(converter_source):
227 class mercurial_source(converter_source):
228 def __init__(self, ui, path, rev=None):
228 def __init__(self, ui, path, rev=None):
229 converter_source.__init__(self, ui, path, rev)
229 converter_source.__init__(self, ui, path, rev)
230 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
230 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
231 self.ignored = set()
231 self.ignored = set()
232 self.saverev = ui.configbool('convert', 'hg.saverev', False)
232 self.saverev = ui.configbool('convert', 'hg.saverev', False)
233 try:
233 try:
234 self.repo = hg.repository(self.ui, path)
234 self.repo = hg.repository(self.ui, path)
235 # try to provoke an exception if this isn't really a hg
235 # try to provoke an exception if this isn't really a hg
236 # repo, but some other bogus compatible-looking url
236 # repo, but some other bogus compatible-looking url
237 if not self.repo.local():
237 if not self.repo.local():
238 raise error.RepoError()
238 raise error.RepoError()
239 except error.RepoError:
239 except error.RepoError:
240 ui.traceback()
240 ui.traceback()
241 raise NoRepo(_("%s is not a local Mercurial repository") % path)
241 raise NoRepo(_("%s is not a local Mercurial repository") % path)
242 self.lastrev = None
242 self.lastrev = None
243 self.lastctx = None
243 self.lastctx = None
244 self._changescache = None
244 self._changescache = None
245 self.convertfp = None
245 self.convertfp = None
246 # Restrict converted revisions to startrev descendants
246 # Restrict converted revisions to startrev descendants
247 startnode = ui.config('convert', 'hg.startrev')
247 startnode = ui.config('convert', 'hg.startrev')
248 if startnode is not None:
248 if startnode is not None:
249 try:
249 try:
250 startnode = self.repo.lookup(startnode)
250 startnode = self.repo.lookup(startnode)
251 except error.RepoError:
251 except error.RepoError:
252 raise util.Abort(_('%s is not a valid start revision')
252 raise util.Abort(_('%s is not a valid start revision')
253 % startnode)
253 % startnode)
254 startrev = self.repo.changelog.rev(startnode)
254 startrev = self.repo.changelog.rev(startnode)
255 children = {startnode: 1}
255 children = {startnode: 1}
256 for rev in self.repo.changelog.descendants(startrev):
256 for rev in self.repo.changelog.descendants(startrev):
257 children[self.repo.changelog.node(rev)] = 1
257 children[self.repo.changelog.node(rev)] = 1
258 self.keep = children.__contains__
258 self.keep = children.__contains__
259 else:
259 else:
260 self.keep = util.always
260 self.keep = util.always
261
261
262 def changectx(self, rev):
262 def changectx(self, rev):
263 if self.lastrev != rev:
263 if self.lastrev != rev:
264 self.lastctx = self.repo[rev]
264 self.lastctx = self.repo[rev]
265 self.lastrev = rev
265 self.lastrev = rev
266 return self.lastctx
266 return self.lastctx
267
267
268 def parents(self, ctx):
268 def parents(self, ctx):
269 return [p for p in ctx.parents() if p and self.keep(p.node())]
269 return [p for p in ctx.parents() if p and self.keep(p.node())]
270
270
271 def getheads(self):
271 def getheads(self):
272 if self.rev:
272 if self.rev:
273 heads = [self.repo[self.rev].node()]
273 heads = [self.repo[self.rev].node()]
274 else:
274 else:
275 heads = self.repo.heads()
275 heads = self.repo.heads()
276 return [hex(h) for h in heads if self.keep(h)]
276 return [hex(h) for h in heads if self.keep(h)]
277
277
278 def getfile(self, name, rev):
278 def getfile(self, name, rev):
279 try:
279 try:
280 fctx = self.changectx(rev)[name]
280 fctx = self.changectx(rev)[name]
281 return fctx.data(), fctx.flags()
281 return fctx.data(), fctx.flags()
282 except error.LookupError, err:
282 except error.LookupError, err:
283 raise IOError(err)
283 raise IOError(err)
284
284
285 def getchanges(self, rev):
285 def getchanges(self, rev):
286 ctx = self.changectx(rev)
286 ctx = self.changectx(rev)
287 parents = self.parents(ctx)
287 parents = self.parents(ctx)
288 if not parents:
288 if not parents:
289 files = sorted(ctx.manifest())
289 files = sorted(ctx.manifest())
290 # getcopies() is not needed for roots, but it is a simple way to
290 # getcopies() is not needed for roots, but it is a simple way to
291 # detect missing revlogs and abort on errors or populate self.ignored
291 # detect missing revlogs and abort on errors or populate self.ignored
292 self.getcopies(ctx, parents, files)
292 self.getcopies(ctx, parents, files)
293 return [(f, rev) for f in files if f not in self.ignored], {}
293 return [(f, rev) for f in files if f not in self.ignored], {}
294 if self._changescache and self._changescache[0] == rev:
294 if self._changescache and self._changescache[0] == rev:
295 m, a, r = self._changescache[1]
295 m, a, r = self._changescache[1]
296 else:
296 else:
297 m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
297 m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
298 # getcopies() detects missing revlogs early, run it before
298 # getcopies() detects missing revlogs early, run it before
299 # filtering the changes.
299 # filtering the changes.
300 copies = self.getcopies(ctx, parents, m + a)
300 copies = self.getcopies(ctx, parents, m + a)
301 changes = [(name, rev) for name in m + a + r
301 changes = [(name, rev) for name in m + a + r
302 if name not in self.ignored]
302 if name not in self.ignored]
303 return sorted(changes), copies
303 return sorted(changes), copies
304
304
305 def getcopies(self, ctx, parents, files):
305 def getcopies(self, ctx, parents, files):
306 copies = {}
306 copies = {}
307 for name in files:
307 for name in files:
308 if name in self.ignored:
308 if name in self.ignored:
309 continue
309 continue
310 try:
310 try:
311 copysource, copynode = ctx.filectx(name).renamed()
311 copysource, copynode = ctx.filectx(name).renamed()
312 if copysource in self.ignored or not self.keep(copynode):
312 if copysource in self.ignored or not self.keep(copynode):
313 continue
313 continue
314 # Ignore copy sources not in parent revisions
314 # Ignore copy sources not in parent revisions
315 found = False
315 found = False
316 for p in parents:
316 for p in parents:
317 if copysource in p:
317 if copysource in p:
318 found = True
318 found = True
319 break
319 break
320 if not found:
320 if not found:
321 continue
321 continue
322 copies[name] = copysource
322 copies[name] = copysource
323 except TypeError:
323 except TypeError:
324 pass
324 pass
325 except error.LookupError, e:
325 except error.LookupError, e:
326 if not self.ignoreerrors:
326 if not self.ignoreerrors:
327 raise
327 raise
328 self.ignored.add(name)
328 self.ignored.add(name)
329 self.ui.warn(_('ignoring: %s\n') % e)
329 self.ui.warn(_('ignoring: %s\n') % e)
330 return copies
330 return copies
331
331
332 def getcommit(self, rev):
332 def getcommit(self, rev):
333 ctx = self.changectx(rev)
333 ctx = self.changectx(rev)
334 parents = [p.hex() for p in self.parents(ctx)]
334 parents = [p.hex() for p in self.parents(ctx)]
335 if self.saverev:
335 if self.saverev:
336 crev = rev
336 crev = rev
337 else:
337 else:
338 crev = None
338 crev = None
339 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
339 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
340 desc=ctx.description(), rev=crev, parents=parents,
340 desc=ctx.description(), rev=crev, parents=parents,
341 branch=ctx.branch(), extra=ctx.extra(),
341 branch=ctx.branch(), extra=ctx.extra(),
342 sortkey=ctx.rev())
342 sortkey=ctx.rev())
343
343
344 def gettags(self):
344 def gettags(self):
345 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
345 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
346 return dict([(name, hex(node)) for name, node in tags
346 return dict([(name, hex(node)) for name, node in tags
347 if self.keep(node)])
347 if self.keep(node)])
348
348
349 def getchangedfiles(self, rev, i):
349 def getchangedfiles(self, rev, i):
350 ctx = self.changectx(rev)
350 ctx = self.changectx(rev)
351 parents = self.parents(ctx)
351 parents = self.parents(ctx)
352 if not parents and i is None:
352 if not parents and i is None:
353 i = 0
353 i = 0
354 changes = [], ctx.manifest().keys(), []
354 changes = [], ctx.manifest().keys(), []
355 else:
355 else:
356 i = i or 0
356 i = i or 0
357 changes = self.repo.status(parents[i].node(), ctx.node())[:3]
357 changes = self.repo.status(parents[i].node(), ctx.node())[:3]
358 changes = [[f for f in l if f not in self.ignored] for l in changes]
358 changes = [[f for f in l if f not in self.ignored] for l in changes]
359
359
360 if i == 0:
360 if i == 0:
361 self._changescache = (rev, changes)
361 self._changescache = (rev, changes)
362
362
363 return changes[0] + changes[1] + changes[2]
363 return changes[0] + changes[1] + changes[2]
364
364
365 def converted(self, rev, destrev):
365 def converted(self, rev, destrev):
366 if self.convertfp is None:
366 if self.convertfp is None:
367 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
367 self.convertfp = open(self.repo.join('shamap'), 'a')
368 'a')
369 self.convertfp.write('%s %s\n' % (destrev, rev))
368 self.convertfp.write('%s %s\n' % (destrev, rev))
370 self.convertfp.flush()
369 self.convertfp.flush()
371
370
372 def before(self):
371 def before(self):
373 self.ui.debug('run hg source pre-conversion action\n')
372 self.ui.debug('run hg source pre-conversion action\n')
374
373
375 def after(self):
374 def after(self):
376 self.ui.debug('run hg source post-conversion action\n')
375 self.ui.debug('run hg source post-conversion action\n')
377
376
378 def hasnativeorder(self):
377 def hasnativeorder(self):
379 return True
378 return True
380
379
381 def lookuprev(self, rev):
380 def lookuprev(self, rev):
382 try:
381 try:
383 return hex(self.repo.lookup(rev))
382 return hex(self.repo.lookup(rev))
384 except error.RepoError:
383 except error.RepoError:
385 return None
384 return None
386
385
387 def getbookmarks(self):
386 def getbookmarks(self):
388 return bookmarks.listbookmarks(self.repo)
387 return bookmarks.listbookmarks(self.repo)
@@ -1,58 +1,58
1
1
2 $ cat >> $HGRCPATH <<EOF
2 $ cat >> $HGRCPATH <<EOF
3 > [extensions]
3 > [extensions]
4 > convert=
4 > convert=
5 > EOF
5 > EOF
6
6
7 Prepare orig repo
7 Prepare orig repo
8
8
9 $ hg init orig
9 $ hg init orig
10 $ cd orig
10 $ cd orig
11 $ echo foo > foo
11 $ echo foo > foo
12 $ HGUSER='user name' hg ci -qAm 'foo'
12 $ HGUSER='user name' hg ci -qAm 'foo'
13 $ cd ..
13 $ cd ..
14
14
15 Explicit --authors
15 Explicit --authors
16
16
17 $ cat > authormap.txt <<EOF
17 $ cat > authormap.txt <<EOF
18 > user name = Long User Name
18 > user name = Long User Name
19 >
19 >
20 > # comment
20 > # comment
21 > this line is ignored
21 > this line is ignored
22 > EOF
22 > EOF
23 $ hg convert --authors authormap.txt orig new
23 $ hg convert --authors authormap.txt orig new
24 initializing destination new repository
24 initializing destination new repository
25 Ignoring bad line in author map file authormap.txt: this line is ignored
25 Ignoring bad line in author map file authormap.txt: this line is ignored
26 scanning source...
26 scanning source...
27 sorting...
27 sorting...
28 converting...
28 converting...
29 0 foo
29 0 foo
30 Writing author map file new/.hg/authormap
30 Writing author map file $TESTTMP/new/.hg/authormap
31 $ cat new/.hg/authormap
31 $ cat new/.hg/authormap
32 user name=Long User Name
32 user name=Long User Name
33 $ hg -Rnew log
33 $ hg -Rnew log
34 changeset: 0:d89716e88087
34 changeset: 0:d89716e88087
35 tag: tip
35 tag: tip
36 user: Long User Name
36 user: Long User Name
37 date: Thu Jan 01 00:00:00 1970 +0000
37 date: Thu Jan 01 00:00:00 1970 +0000
38 summary: foo
38 summary: foo
39
39
40 $ rm -rf new
40 $ rm -rf new
41
41
42 Implicit .hg/authormap
42 Implicit .hg/authormap
43
43
44 $ hg init new
44 $ hg init new
45 $ mv authormap.txt new/.hg/authormap
45 $ mv authormap.txt new/.hg/authormap
46 $ hg convert orig new
46 $ hg convert orig new
47 Ignoring bad line in author map file new/.hg/authormap: this line is ignored
47 Ignoring bad line in author map file $TESTTMP/new/.hg/authormap: this line is ignored
48 scanning source...
48 scanning source...
49 sorting...
49 sorting...
50 converting...
50 converting...
51 0 foo
51 0 foo
52 $ hg -Rnew log
52 $ hg -Rnew log
53 changeset: 0:d89716e88087
53 changeset: 0:d89716e88087
54 tag: tip
54 tag: tip
55 user: Long User Name
55 user: Long User Name
56 date: Thu Jan 01 00:00:00 1970 +0000
56 date: Thu Jan 01 00:00:00 1970 +0000
57 summary: foo
57 summary: foo
58
58
General Comments 0
You need to be logged in to leave comments. Login now