##// END OF EJS Templates
convert: add bookmark support to the hg sink
Edouard Gomez -
r13746:d80b7685 default
parent child Browse files
Show More
@@ -1,376 +1,386 b''
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, 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 os.path.join(self.path, ".hg", "shamap")
74
74
75 def authorfile(self):
75 def authorfile(self):
76 return os.path.join(self.path, ".hg", "authormap")
76 return os.path.join(self.path, ".hg", "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.repository(self.ui, pbranchpath)
115 prepo = hg.repository(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):
218 if not len(updatedbookmark):
219 return
220
221 self.ui.status(_("updating bookmarks\n"))
222 for bookmark in updatedbookmark:
223 self.repo._bookmarks[bookmark] = bin(updatedbookmark[bookmark])
224 bookmarks.write(self.repo)
225
226
217 class mercurial_source(converter_source):
227 class mercurial_source(converter_source):
218 def __init__(self, ui, path, rev=None):
228 def __init__(self, ui, path, rev=None):
219 converter_source.__init__(self, ui, path, rev)
229 converter_source.__init__(self, ui, path, rev)
220 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
230 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
221 self.ignored = set()
231 self.ignored = set()
222 self.saverev = ui.configbool('convert', 'hg.saverev', False)
232 self.saverev = ui.configbool('convert', 'hg.saverev', False)
223 try:
233 try:
224 self.repo = hg.repository(self.ui, path)
234 self.repo = hg.repository(self.ui, path)
225 # 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
226 # repo, but some other bogus compatible-looking url
236 # repo, but some other bogus compatible-looking url
227 if not self.repo.local():
237 if not self.repo.local():
228 raise error.RepoError()
238 raise error.RepoError()
229 except error.RepoError:
239 except error.RepoError:
230 ui.traceback()
240 ui.traceback()
231 raise NoRepo(_("%s is not a local Mercurial repository") % path)
241 raise NoRepo(_("%s is not a local Mercurial repository") % path)
232 self.lastrev = None
242 self.lastrev = None
233 self.lastctx = None
243 self.lastctx = None
234 self._changescache = None
244 self._changescache = None
235 self.convertfp = None
245 self.convertfp = None
236 # Restrict converted revisions to startrev descendants
246 # Restrict converted revisions to startrev descendants
237 startnode = ui.config('convert', 'hg.startrev')
247 startnode = ui.config('convert', 'hg.startrev')
238 if startnode is not None:
248 if startnode is not None:
239 try:
249 try:
240 startnode = self.repo.lookup(startnode)
250 startnode = self.repo.lookup(startnode)
241 except error.RepoError:
251 except error.RepoError:
242 raise util.Abort(_('%s is not a valid start revision')
252 raise util.Abort(_('%s is not a valid start revision')
243 % startnode)
253 % startnode)
244 startrev = self.repo.changelog.rev(startnode)
254 startrev = self.repo.changelog.rev(startnode)
245 children = {startnode: 1}
255 children = {startnode: 1}
246 for rev in self.repo.changelog.descendants(startrev):
256 for rev in self.repo.changelog.descendants(startrev):
247 children[self.repo.changelog.node(rev)] = 1
257 children[self.repo.changelog.node(rev)] = 1
248 self.keep = children.__contains__
258 self.keep = children.__contains__
249 else:
259 else:
250 self.keep = util.always
260 self.keep = util.always
251
261
252 def changectx(self, rev):
262 def changectx(self, rev):
253 if self.lastrev != rev:
263 if self.lastrev != rev:
254 self.lastctx = self.repo[rev]
264 self.lastctx = self.repo[rev]
255 self.lastrev = rev
265 self.lastrev = rev
256 return self.lastctx
266 return self.lastctx
257
267
258 def parents(self, ctx):
268 def parents(self, ctx):
259 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())]
260
270
261 def getheads(self):
271 def getheads(self):
262 if self.rev:
272 if self.rev:
263 heads = [self.repo[self.rev].node()]
273 heads = [self.repo[self.rev].node()]
264 else:
274 else:
265 heads = self.repo.heads()
275 heads = self.repo.heads()
266 return [hex(h) for h in heads if self.keep(h)]
276 return [hex(h) for h in heads if self.keep(h)]
267
277
268 def getfile(self, name, rev):
278 def getfile(self, name, rev):
269 try:
279 try:
270 fctx = self.changectx(rev)[name]
280 fctx = self.changectx(rev)[name]
271 return fctx.data(), fctx.flags()
281 return fctx.data(), fctx.flags()
272 except error.LookupError, err:
282 except error.LookupError, err:
273 raise IOError(err)
283 raise IOError(err)
274
284
275 def getchanges(self, rev):
285 def getchanges(self, rev):
276 ctx = self.changectx(rev)
286 ctx = self.changectx(rev)
277 parents = self.parents(ctx)
287 parents = self.parents(ctx)
278 if not parents:
288 if not parents:
279 files = sorted(ctx.manifest())
289 files = sorted(ctx.manifest())
280 if self.ignoreerrors:
290 if self.ignoreerrors:
281 # calling getcopies() is a simple way to detect missing
291 # calling getcopies() is a simple way to detect missing
282 # revlogs and populate self.ignored
292 # revlogs and populate self.ignored
283 self.getcopies(ctx, parents, files)
293 self.getcopies(ctx, parents, files)
284 return [(f, rev) for f in files if f not in self.ignored], {}
294 return [(f, rev) for f in files if f not in self.ignored], {}
285 if self._changescache and self._changescache[0] == rev:
295 if self._changescache and self._changescache[0] == rev:
286 m, a, r = self._changescache[1]
296 m, a, r = self._changescache[1]
287 else:
297 else:
288 m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
298 m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
289 # getcopies() detects missing revlogs early, run it before
299 # getcopies() detects missing revlogs early, run it before
290 # filtering the changes.
300 # filtering the changes.
291 copies = self.getcopies(ctx, parents, m + a)
301 copies = self.getcopies(ctx, parents, m + a)
292 changes = [(name, rev) for name in m + a + r
302 changes = [(name, rev) for name in m + a + r
293 if name not in self.ignored]
303 if name not in self.ignored]
294 return sorted(changes), copies
304 return sorted(changes), copies
295
305
296 def getcopies(self, ctx, parents, files):
306 def getcopies(self, ctx, parents, files):
297 copies = {}
307 copies = {}
298 for name in files:
308 for name in files:
299 if name in self.ignored:
309 if name in self.ignored:
300 continue
310 continue
301 try:
311 try:
302 copysource, copynode = ctx.filectx(name).renamed()
312 copysource, copynode = ctx.filectx(name).renamed()
303 if copysource in self.ignored or not self.keep(copynode):
313 if copysource in self.ignored or not self.keep(copynode):
304 continue
314 continue
305 # Ignore copy sources not in parent revisions
315 # Ignore copy sources not in parent revisions
306 found = False
316 found = False
307 for p in parents:
317 for p in parents:
308 if copysource in p:
318 if copysource in p:
309 found = True
319 found = True
310 break
320 break
311 if not found:
321 if not found:
312 continue
322 continue
313 copies[name] = copysource
323 copies[name] = copysource
314 except TypeError:
324 except TypeError:
315 pass
325 pass
316 except error.LookupError, e:
326 except error.LookupError, e:
317 if not self.ignoreerrors:
327 if not self.ignoreerrors:
318 raise
328 raise
319 self.ignored.add(name)
329 self.ignored.add(name)
320 self.ui.warn(_('ignoring: %s\n') % e)
330 self.ui.warn(_('ignoring: %s\n') % e)
321 return copies
331 return copies
322
332
323 def getcommit(self, rev):
333 def getcommit(self, rev):
324 ctx = self.changectx(rev)
334 ctx = self.changectx(rev)
325 parents = [p.hex() for p in self.parents(ctx)]
335 parents = [p.hex() for p in self.parents(ctx)]
326 if self.saverev:
336 if self.saverev:
327 crev = rev
337 crev = rev
328 else:
338 else:
329 crev = None
339 crev = None
330 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
340 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
331 desc=ctx.description(), rev=crev, parents=parents,
341 desc=ctx.description(), rev=crev, parents=parents,
332 branch=ctx.branch(), extra=ctx.extra(),
342 branch=ctx.branch(), extra=ctx.extra(),
333 sortkey=ctx.rev())
343 sortkey=ctx.rev())
334
344
335 def gettags(self):
345 def gettags(self):
336 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
346 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
337 return dict([(name, hex(node)) for name, node in tags
347 return dict([(name, hex(node)) for name, node in tags
338 if self.keep(node)])
348 if self.keep(node)])
339
349
340 def getchangedfiles(self, rev, i):
350 def getchangedfiles(self, rev, i):
341 ctx = self.changectx(rev)
351 ctx = self.changectx(rev)
342 parents = self.parents(ctx)
352 parents = self.parents(ctx)
343 if not parents and i is None:
353 if not parents and i is None:
344 i = 0
354 i = 0
345 changes = [], ctx.manifest().keys(), []
355 changes = [], ctx.manifest().keys(), []
346 else:
356 else:
347 i = i or 0
357 i = i or 0
348 changes = self.repo.status(parents[i].node(), ctx.node())[:3]
358 changes = self.repo.status(parents[i].node(), ctx.node())[:3]
349 changes = [[f for f in l if f not in self.ignored] for l in changes]
359 changes = [[f for f in l if f not in self.ignored] for l in changes]
350
360
351 if i == 0:
361 if i == 0:
352 self._changescache = (rev, changes)
362 self._changescache = (rev, changes)
353
363
354 return changes[0] + changes[1] + changes[2]
364 return changes[0] + changes[1] + changes[2]
355
365
356 def converted(self, rev, destrev):
366 def converted(self, rev, destrev):
357 if self.convertfp is None:
367 if self.convertfp is None:
358 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
368 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
359 'a')
369 'a')
360 self.convertfp.write('%s %s\n' % (destrev, rev))
370 self.convertfp.write('%s %s\n' % (destrev, rev))
361 self.convertfp.flush()
371 self.convertfp.flush()
362
372
363 def before(self):
373 def before(self):
364 self.ui.debug('run hg source pre-conversion action\n')
374 self.ui.debug('run hg source pre-conversion action\n')
365
375
366 def after(self):
376 def after(self):
367 self.ui.debug('run hg source post-conversion action\n')
377 self.ui.debug('run hg source post-conversion action\n')
368
378
369 def hasnativeorder(self):
379 def hasnativeorder(self):
370 return True
380 return True
371
381
372 def lookuprev(self, rev):
382 def lookuprev(self, rev):
373 try:
383 try:
374 return hex(self.repo.lookup(rev))
384 return hex(self.repo.lookup(rev))
375 except error.RepoError:
385 except error.RepoError:
376 return None
386 return None
General Comments 0
You need to be logged in to leave comments. Login now