##// END OF EJS Templates
Merge with crew-stable
Patrick Mezard -
r9546:4333b974 merge default
parent child Browse files
Show More
@@ -1,363 +1,370
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, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
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, 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 repo') % path)
39 raise NoRepo(_('%s is not a local Mercurial repo') % path)
40 except error.RepoError, err:
40 except error.RepoError, err:
41 ui.traceback()
41 ui.traceback()
42 raise NoRepo(err.args[0])
42 raise NoRepo(err.args[0])
43 else:
43 else:
44 try:
44 try:
45 ui.status(_('initializing destination %s repository\n') % path)
45 ui.status(_('initializing destination %s repository\n') % path)
46 self.repo = hg.repository(self.ui, path, create=True)
46 self.repo = hg.repository(self.ui, path, create=True)
47 if not self.repo.local():
47 if not self.repo.local():
48 raise NoRepo(_('%s is not a local Mercurial repo') % path)
48 raise NoRepo(_('%s is not a local Mercurial repo') % path)
49 self.created.append(path)
49 self.created.append(path)
50 except error.RepoError:
50 except error.RepoError:
51 ui.traceback()
51 ui.traceback()
52 raise NoRepo("could not create hg repo %s as sink" % path)
52 raise NoRepo("could not create hg repo %s as sink" % path)
53 self.lock = None
53 self.lock = None
54 self.wlock = None
54 self.wlock = None
55 self.filemapmode = False
55 self.filemapmode = False
56
56
57 def before(self):
57 def before(self):
58 self.ui.debug('run hg sink pre-conversion action\n')
58 self.ui.debug('run hg sink pre-conversion action\n')
59 self.wlock = self.repo.wlock()
59 self.wlock = self.repo.wlock()
60 self.lock = self.repo.lock()
60 self.lock = self.repo.lock()
61
61
62 def after(self):
62 def after(self):
63 self.ui.debug('run hg sink post-conversion action\n')
63 self.ui.debug('run hg sink post-conversion action\n')
64 self.lock.release()
64 self.lock.release()
65 self.wlock.release()
65 self.wlock.release()
66
66
67 def revmapfile(self):
67 def revmapfile(self):
68 return os.path.join(self.path, ".hg", "shamap")
68 return os.path.join(self.path, ".hg", "shamap")
69
69
70 def authorfile(self):
70 def authorfile(self):
71 return os.path.join(self.path, ".hg", "authormap")
71 return os.path.join(self.path, ".hg", "authormap")
72
72
73 def getheads(self):
73 def getheads(self):
74 h = self.repo.changelog.heads()
74 h = self.repo.changelog.heads()
75 return [ hex(x) for x in h ]
75 return [ hex(x) for x in h ]
76
76
77 def setbranch(self, branch, pbranches):
77 def setbranch(self, branch, pbranches):
78 if not self.clonebranches:
78 if not self.clonebranches:
79 return
79 return
80
80
81 setbranch = (branch != self.lastbranch)
81 setbranch = (branch != self.lastbranch)
82 self.lastbranch = branch
82 self.lastbranch = branch
83 if not branch:
83 if not branch:
84 branch = 'default'
84 branch = 'default'
85 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
85 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
86 pbranch = pbranches and pbranches[0][1] or 'default'
86 pbranch = pbranches and pbranches[0][1] or 'default'
87
87
88 branchpath = os.path.join(self.path, branch)
88 branchpath = os.path.join(self.path, branch)
89 if setbranch:
89 if setbranch:
90 self.after()
90 self.after()
91 try:
91 try:
92 self.repo = hg.repository(self.ui, branchpath)
92 self.repo = hg.repository(self.ui, branchpath)
93 except:
93 except:
94 self.repo = hg.repository(self.ui, branchpath, create=True)
94 self.repo = hg.repository(self.ui, branchpath, create=True)
95 self.before()
95 self.before()
96
96
97 # pbranches may bring revisions from other branches (merge parents)
97 # pbranches may bring revisions from other branches (merge parents)
98 # Make sure we have them, or pull them.
98 # Make sure we have them, or pull them.
99 missings = {}
99 missings = {}
100 for b in pbranches:
100 for b in pbranches:
101 try:
101 try:
102 self.repo.lookup(b[0])
102 self.repo.lookup(b[0])
103 except:
103 except:
104 missings.setdefault(b[1], []).append(b[0])
104 missings.setdefault(b[1], []).append(b[0])
105
105
106 if missings:
106 if missings:
107 self.after()
107 self.after()
108 for pbranch, heads in missings.iteritems():
108 for pbranch, heads in missings.iteritems():
109 pbranchpath = os.path.join(self.path, pbranch)
109 pbranchpath = os.path.join(self.path, pbranch)
110 prepo = hg.repository(self.ui, pbranchpath)
110 prepo = hg.repository(self.ui, pbranchpath)
111 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
111 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
112 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
112 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
113 self.before()
113 self.before()
114
114
115 def _rewritetags(self, source, revmap, data):
115 def _rewritetags(self, source, revmap, data):
116 fp = cStringIO.StringIO()
116 fp = cStringIO.StringIO()
117 for line in data.splitlines():
117 for line in data.splitlines():
118 s = line.split(' ', 1)
118 s = line.split(' ', 1)
119 if len(s) != 2:
119 if len(s) != 2:
120 continue
120 continue
121 revid = revmap.get(source.lookuprev(s[0]))
121 revid = revmap.get(source.lookuprev(s[0]))
122 if not revid:
122 if not revid:
123 continue
123 continue
124 fp.write('%s %s\n' % (revid, s[1]))
124 fp.write('%s %s\n' % (revid, s[1]))
125 return fp.getvalue()
125 return fp.getvalue()
126
126
127 def putcommit(self, files, copies, parents, commit, source, revmap):
127 def putcommit(self, files, copies, parents, commit, source, revmap):
128
128
129 files = dict(files)
129 files = dict(files)
130 def getfilectx(repo, memctx, f):
130 def getfilectx(repo, memctx, f):
131 v = files[f]
131 v = files[f]
132 data = source.getfile(f, v)
132 data = source.getfile(f, v)
133 e = source.getmode(f, v)
133 e = source.getmode(f, v)
134 if f == '.hgtags':
134 if f == '.hgtags':
135 data = self._rewritetags(source, revmap, data)
135 data = self._rewritetags(source, revmap, data)
136 return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f))
136 return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f))
137
137
138 pl = []
138 pl = []
139 for p in parents:
139 for p in parents:
140 if p not in pl:
140 if p not in pl:
141 pl.append(p)
141 pl.append(p)
142 parents = pl
142 parents = pl
143 nparents = len(parents)
143 nparents = len(parents)
144 if self.filemapmode and nparents == 1:
144 if self.filemapmode and nparents == 1:
145 m1node = self.repo.changelog.read(bin(parents[0]))[0]
145 m1node = self.repo.changelog.read(bin(parents[0]))[0]
146 parent = parents[0]
146 parent = parents[0]
147
147
148 if len(parents) < 2: parents.append(nullid)
148 if len(parents) < 2: parents.append(nullid)
149 if len(parents) < 2: parents.append(nullid)
149 if len(parents) < 2: parents.append(nullid)
150 p2 = parents.pop(0)
150 p2 = parents.pop(0)
151
151
152 text = commit.desc
152 text = commit.desc
153 extra = commit.extra.copy()
153 extra = commit.extra.copy()
154 if self.branchnames and commit.branch:
154 if self.branchnames and commit.branch:
155 extra['branch'] = commit.branch
155 extra['branch'] = commit.branch
156 if commit.rev:
156 if commit.rev:
157 extra['convert_revision'] = commit.rev
157 extra['convert_revision'] = commit.rev
158
158
159 while parents:
159 while parents:
160 p1 = p2
160 p1 = p2
161 p2 = parents.pop(0)
161 p2 = parents.pop(0)
162 ctx = context.memctx(self.repo, (p1, p2), text, files.keys(), getfilectx,
162 ctx = context.memctx(self.repo, (p1, p2), text, files.keys(), getfilectx,
163 commit.author, commit.date, extra)
163 commit.author, commit.date, extra)
164 self.repo.commitctx(ctx)
164 self.repo.commitctx(ctx)
165 text = "(octopus merge fixup)\n"
165 text = "(octopus merge fixup)\n"
166 p2 = hex(self.repo.changelog.tip())
166 p2 = hex(self.repo.changelog.tip())
167
167
168 if self.filemapmode and nparents == 1:
168 if self.filemapmode and nparents == 1:
169 man = self.repo.manifest
169 man = self.repo.manifest
170 mnode = self.repo.changelog.read(bin(p2))[0]
170 mnode = self.repo.changelog.read(bin(p2))[0]
171 if not man.cmp(m1node, man.revision(mnode)):
171 if not man.cmp(m1node, man.revision(mnode)):
172 self.ui.status(_("filtering out empty revision\n"))
172 self.ui.status(_("filtering out empty revision\n"))
173 self.repo.rollback()
173 self.repo.rollback()
174 return parent
174 return parent
175 return p2
175 return p2
176
176
177 def puttags(self, tags):
177 def puttags(self, tags):
178 try:
178 try:
179 parentctx = self.repo[self.tagsbranch]
179 parentctx = self.repo[self.tagsbranch]
180 tagparent = parentctx.node()
180 tagparent = parentctx.node()
181 except error.RepoError:
181 except error.RepoError:
182 parentctx = None
182 parentctx = None
183 tagparent = nullid
183 tagparent = nullid
184
184
185 try:
185 try:
186 oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
186 oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
187 except:
187 except:
188 oldlines = []
188 oldlines = []
189
189
190 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
190 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
191 if newlines == oldlines:
191 if newlines == oldlines:
192 return None, None
192 return None, None
193 data = "".join(newlines)
193 data = "".join(newlines)
194 def getfilectx(repo, memctx, f):
194 def getfilectx(repo, memctx, f):
195 return context.memfilectx(f, data, False, False, None)
195 return context.memfilectx(f, data, False, False, None)
196
196
197 self.ui.status(_("updating tags\n"))
197 self.ui.status(_("updating tags\n"))
198 date = "%s 0" % int(time.mktime(time.gmtime()))
198 date = "%s 0" % int(time.mktime(time.gmtime()))
199 extra = {'branch': self.tagsbranch}
199 extra = {'branch': self.tagsbranch}
200 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
200 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
201 [".hgtags"], getfilectx, "convert-repo", date,
201 [".hgtags"], getfilectx, "convert-repo", date,
202 extra)
202 extra)
203 self.repo.commitctx(ctx)
203 self.repo.commitctx(ctx)
204 return hex(self.repo.changelog.tip()), hex(tagparent)
204 return hex(self.repo.changelog.tip()), hex(tagparent)
205
205
206 def setfilemapmode(self, active):
206 def setfilemapmode(self, active):
207 self.filemapmode = active
207 self.filemapmode = active
208
208
209 class mercurial_source(converter_source):
209 class mercurial_source(converter_source):
210 def __init__(self, ui, path, rev=None):
210 def __init__(self, ui, path, rev=None):
211 converter_source.__init__(self, ui, path, rev)
211 converter_source.__init__(self, ui, path, rev)
212 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
212 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
213 self.ignored = set()
213 self.ignored = set()
214 self.saverev = ui.configbool('convert', 'hg.saverev', False)
214 self.saverev = ui.configbool('convert', 'hg.saverev', False)
215 try:
215 try:
216 self.repo = hg.repository(self.ui, path)
216 self.repo = hg.repository(self.ui, path)
217 # try to provoke an exception if this isn't really a hg
217 # try to provoke an exception if this isn't really a hg
218 # repo, but some other bogus compatible-looking url
218 # repo, but some other bogus compatible-looking url
219 if not self.repo.local():
219 if not self.repo.local():
220 raise error.RepoError()
220 raise error.RepoError()
221 except error.RepoError:
221 except error.RepoError:
222 ui.traceback()
222 ui.traceback()
223 raise NoRepo("%s is not a local Mercurial repo" % path)
223 raise NoRepo("%s is not a local Mercurial repo" % path)
224 self.lastrev = None
224 self.lastrev = None
225 self.lastctx = None
225 self.lastctx = None
226 self._changescache = None
226 self._changescache = None
227 self.convertfp = None
227 self.convertfp = None
228 # Restrict converted revisions to startrev descendants
228 # Restrict converted revisions to startrev descendants
229 startnode = ui.config('convert', 'hg.startrev')
229 startnode = ui.config('convert', 'hg.startrev')
230 if startnode is not None:
230 if startnode is not None:
231 try:
231 try:
232 startnode = self.repo.lookup(startnode)
232 startnode = self.repo.lookup(startnode)
233 except error.RepoError:
233 except error.RepoError:
234 raise util.Abort(_('%s is not a valid start revision')
234 raise util.Abort(_('%s is not a valid start revision')
235 % startnode)
235 % startnode)
236 startrev = self.repo.changelog.rev(startnode)
236 startrev = self.repo.changelog.rev(startnode)
237 children = {startnode: 1}
237 children = {startnode: 1}
238 for rev in self.repo.changelog.descendants(startrev):
238 for rev in self.repo.changelog.descendants(startrev):
239 children[self.repo.changelog.node(rev)] = 1
239 children[self.repo.changelog.node(rev)] = 1
240 self.keep = children.__contains__
240 self.keep = children.__contains__
241 else:
241 else:
242 self.keep = util.always
242 self.keep = util.always
243
243
244 def changectx(self, rev):
244 def changectx(self, rev):
245 if self.lastrev != rev:
245 if self.lastrev != rev:
246 self.lastctx = self.repo[rev]
246 self.lastctx = self.repo[rev]
247 self.lastrev = rev
247 self.lastrev = rev
248 return self.lastctx
248 return self.lastctx
249
249
250 def parents(self, ctx):
250 def parents(self, ctx):
251 return [p.node() for p in ctx.parents()
251 return [p for p in ctx.parents() if p and self.keep(p.node())]
252 if p and self.keep(p.node())]
253
252
254 def getheads(self):
253 def getheads(self):
255 if self.rev:
254 if self.rev:
256 heads = [self.repo[self.rev].node()]
255 heads = [self.repo[self.rev].node()]
257 else:
256 else:
258 heads = self.repo.heads()
257 heads = self.repo.heads()
259 return [hex(h) for h in heads if self.keep(h)]
258 return [hex(h) for h in heads if self.keep(h)]
260
259
261 def getfile(self, name, rev):
260 def getfile(self, name, rev):
262 try:
261 try:
263 return self.changectx(rev)[name].data()
262 return self.changectx(rev)[name].data()
264 except error.LookupError, err:
263 except error.LookupError, err:
265 raise IOError(err)
264 raise IOError(err)
266
265
267 def getmode(self, name, rev):
266 def getmode(self, name, rev):
268 return self.changectx(rev).manifest().flags(name)
267 return self.changectx(rev).manifest().flags(name)
269
268
270 def getchanges(self, rev):
269 def getchanges(self, rev):
271 ctx = self.changectx(rev)
270 ctx = self.changectx(rev)
272 parents = self.parents(ctx)
271 parents = self.parents(ctx)
273 if not parents:
272 if not parents:
274 files = sorted(ctx.manifest())
273 files = sorted(ctx.manifest())
275 if self.ignoreerrors:
274 if self.ignoreerrors:
276 # calling getcopies() is a simple way to detect missing
275 # calling getcopies() is a simple way to detect missing
277 # revlogs and populate self.ignored
276 # revlogs and populate self.ignored
278 self.getcopies(ctx, files)
277 self.getcopies(ctx, parents, files)
279 return [(f, rev) for f in files if f not in self.ignored], {}
278 return [(f, rev) for f in files if f not in self.ignored], {}
280 if self._changescache and self._changescache[0] == rev:
279 if self._changescache and self._changescache[0] == rev:
281 m, a, r = self._changescache[1]
280 m, a, r = self._changescache[1]
282 else:
281 else:
283 m, a, r = self.repo.status(parents[0], ctx.node())[:3]
282 m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
284 # getcopies() detects missing revlogs early, run it before
283 # getcopies() detects missing revlogs early, run it before
285 # filtering the changes.
284 # filtering the changes.
286 copies = self.getcopies(ctx, m + a)
285 copies = self.getcopies(ctx, parents, m + a)
287 changes = [(name, rev) for name in m + a + r
286 changes = [(name, rev) for name in m + a + r
288 if name not in self.ignored]
287 if name not in self.ignored]
289 return sorted(changes), copies
288 return sorted(changes), copies
290
289
291 def getcopies(self, ctx, files):
290 def getcopies(self, ctx, parents, files):
292 copies = {}
291 copies = {}
293 for name in files:
292 for name in files:
294 if name in self.ignored:
293 if name in self.ignored:
295 continue
294 continue
296 try:
295 try:
297 copysource, copynode = ctx.filectx(name).renamed()
296 copysource, copynode = ctx.filectx(name).renamed()
298 if copysource in self.ignored or not self.keep(copynode):
297 if copysource in self.ignored or not self.keep(copynode):
299 continue
298 continue
299 # Ignore copy sources not in parent revisions
300 found = False
301 for p in parents:
302 if copysource in p:
303 found = True
304 break
305 if not found:
306 continue
300 copies[name] = copysource
307 copies[name] = copysource
301 except TypeError:
308 except TypeError:
302 pass
309 pass
303 except error.LookupError, e:
310 except error.LookupError, e:
304 if not self.ignoreerrors:
311 if not self.ignoreerrors:
305 raise
312 raise
306 self.ignored.add(name)
313 self.ignored.add(name)
307 self.ui.warn(_('ignoring: %s\n') % e)
314 self.ui.warn(_('ignoring: %s\n') % e)
308 return copies
315 return copies
309
316
310 def getcommit(self, rev):
317 def getcommit(self, rev):
311 ctx = self.changectx(rev)
318 ctx = self.changectx(rev)
312 parents = [hex(p) for p in self.parents(ctx)]
319 parents = [p.hex() for p in self.parents(ctx)]
313 if self.saverev:
320 if self.saverev:
314 crev = rev
321 crev = rev
315 else:
322 else:
316 crev = None
323 crev = None
317 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
324 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
318 desc=ctx.description(), rev=crev, parents=parents,
325 desc=ctx.description(), rev=crev, parents=parents,
319 branch=ctx.branch(), extra=ctx.extra(),
326 branch=ctx.branch(), extra=ctx.extra(),
320 sortkey=ctx.rev())
327 sortkey=ctx.rev())
321
328
322 def gettags(self):
329 def gettags(self):
323 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
330 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
324 return dict([(name, hex(node)) for name, node in tags
331 return dict([(name, hex(node)) for name, node in tags
325 if self.keep(node)])
332 if self.keep(node)])
326
333
327 def getchangedfiles(self, rev, i):
334 def getchangedfiles(self, rev, i):
328 ctx = self.changectx(rev)
335 ctx = self.changectx(rev)
329 parents = self.parents(ctx)
336 parents = self.parents(ctx)
330 if not parents and i is None:
337 if not parents and i is None:
331 i = 0
338 i = 0
332 changes = [], ctx.manifest().keys(), []
339 changes = [], ctx.manifest().keys(), []
333 else:
340 else:
334 i = i or 0
341 i = i or 0
335 changes = self.repo.status(parents[i], ctx.node())[:3]
342 changes = self.repo.status(parents[i].node(), ctx.node())[:3]
336 changes = [[f for f in l if f not in self.ignored] for l in changes]
343 changes = [[f for f in l if f not in self.ignored] for l in changes]
337
344
338 if i == 0:
345 if i == 0:
339 self._changescache = (rev, changes)
346 self._changescache = (rev, changes)
340
347
341 return changes[0] + changes[1] + changes[2]
348 return changes[0] + changes[1] + changes[2]
342
349
343 def converted(self, rev, destrev):
350 def converted(self, rev, destrev):
344 if self.convertfp is None:
351 if self.convertfp is None:
345 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
352 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
346 'a')
353 'a')
347 self.convertfp.write('%s %s\n' % (destrev, rev))
354 self.convertfp.write('%s %s\n' % (destrev, rev))
348 self.convertfp.flush()
355 self.convertfp.flush()
349
356
350 def before(self):
357 def before(self):
351 self.ui.debug('run hg source pre-conversion action\n')
358 self.ui.debug('run hg source pre-conversion action\n')
352
359
353 def after(self):
360 def after(self):
354 self.ui.debug('run hg source post-conversion action\n')
361 self.ui.debug('run hg source post-conversion action\n')
355
362
356 def hasnativeorder(self):
363 def hasnativeorder(self):
357 return True
364 return True
358
365
359 def lookuprev(self, rev):
366 def lookuprev(self, rev):
360 try:
367 try:
361 return hex(self.repo.lookup(rev))
368 return hex(self.repo.lookup(rev))
362 except error.RepoError:
369 except error.RepoError:
363 return None
370 return None
General Comments 0
You need to be logged in to leave comments. Login now