##// END OF EJS Templates
convert: hg use absolute_import
timeless -
r28370:c1878afb default
parent child Browse files
Show More
@@ -1,634 +1,651 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 from __future__ import absolute_import
19
20
21 import cStringIO
22 import os
23 import re
24 import time
20
25
21 import os, time, cStringIO
26 from mercurial import (
27 bookmarks,
28 context,
29 error,
30 exchange,
31 hg,
32 lock as lockmod,
33 merge as mergemod,
34 node as nodemod,
35 phases,
36 scmutil,
37 util,
38 )
22 from mercurial.i18n import _
39 from mercurial.i18n import _
23 from mercurial.node import bin, hex, nullid
40 from . import common
24 from mercurial import hg, util, context, bookmarks, error, scmutil, exchange
41 mapfile = common.mapfile
25 from mercurial import phases
42 NoRepo = common.NoRepo
26 from mercurial import lock as lockmod
27 from mercurial import merge as mergemod
28
43
29 from common import NoRepo, commit, converter_source, converter_sink, mapfile
30
31 import re
32 sha1re = re.compile(r'\b[0-9a-f]{12,40}\b')
44 sha1re = re.compile(r'\b[0-9a-f]{12,40}\b')
33
45
34 class mercurial_sink(converter_sink):
46 class mercurial_sink(common.converter_sink):
35 def __init__(self, ui, path):
47 def __init__(self, ui, path):
36 converter_sink.__init__(self, ui, path)
48 common.converter_sink.__init__(self, ui, path)
37 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
49 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
38 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
50 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
39 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
51 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
40 self.lastbranch = None
52 self.lastbranch = None
41 if os.path.isdir(path) and len(os.listdir(path)) > 0:
53 if os.path.isdir(path) and len(os.listdir(path)) > 0:
42 try:
54 try:
43 self.repo = hg.repository(self.ui, path)
55 self.repo = hg.repository(self.ui, path)
44 if not self.repo.local():
56 if not self.repo.local():
45 raise NoRepo(_('%s is not a local Mercurial repository')
57 raise NoRepo(_('%s is not a local Mercurial repository')
46 % path)
58 % path)
47 except error.RepoError as err:
59 except error.RepoError as err:
48 ui.traceback()
60 ui.traceback()
49 raise NoRepo(err.args[0])
61 raise NoRepo(err.args[0])
50 else:
62 else:
51 try:
63 try:
52 ui.status(_('initializing destination %s repository\n') % path)
64 ui.status(_('initializing destination %s repository\n') % path)
53 self.repo = hg.repository(self.ui, path, create=True)
65 self.repo = hg.repository(self.ui, path, create=True)
54 if not self.repo.local():
66 if not self.repo.local():
55 raise NoRepo(_('%s is not a local Mercurial repository')
67 raise NoRepo(_('%s is not a local Mercurial repository')
56 % path)
68 % path)
57 self.created.append(path)
69 self.created.append(path)
58 except error.RepoError:
70 except error.RepoError:
59 ui.traceback()
71 ui.traceback()
60 raise NoRepo(_("could not create hg repository %s as sink")
72 raise NoRepo(_("could not create hg repository %s as sink")
61 % path)
73 % path)
62 self.lock = None
74 self.lock = None
63 self.wlock = None
75 self.wlock = None
64 self.filemapmode = False
76 self.filemapmode = False
65 self.subrevmaps = {}
77 self.subrevmaps = {}
66
78
67 def before(self):
79 def before(self):
68 self.ui.debug('run hg sink pre-conversion action\n')
80 self.ui.debug('run hg sink pre-conversion action\n')
69 self.wlock = self.repo.wlock()
81 self.wlock = self.repo.wlock()
70 self.lock = self.repo.lock()
82 self.lock = self.repo.lock()
71
83
72 def after(self):
84 def after(self):
73 self.ui.debug('run hg sink post-conversion action\n')
85 self.ui.debug('run hg sink post-conversion action\n')
74 if self.lock:
86 if self.lock:
75 self.lock.release()
87 self.lock.release()
76 if self.wlock:
88 if self.wlock:
77 self.wlock.release()
89 self.wlock.release()
78
90
79 def revmapfile(self):
91 def revmapfile(self):
80 return self.repo.join("shamap")
92 return self.repo.join("shamap")
81
93
82 def authorfile(self):
94 def authorfile(self):
83 return self.repo.join("authormap")
95 return self.repo.join("authormap")
84
96
85 def setbranch(self, branch, pbranches):
97 def setbranch(self, branch, pbranches):
86 if not self.clonebranches:
98 if not self.clonebranches:
87 return
99 return
88
100
89 setbranch = (branch != self.lastbranch)
101 setbranch = (branch != self.lastbranch)
90 self.lastbranch = branch
102 self.lastbranch = branch
91 if not branch:
103 if not branch:
92 branch = 'default'
104 branch = 'default'
93 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
105 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
94 if pbranches:
106 if pbranches:
95 pbranch = pbranches[0][1]
107 pbranch = pbranches[0][1]
96 else:
108 else:
97 pbranch = 'default'
109 pbranch = 'default'
98
110
99 branchpath = os.path.join(self.path, branch)
111 branchpath = os.path.join(self.path, branch)
100 if setbranch:
112 if setbranch:
101 self.after()
113 self.after()
102 try:
114 try:
103 self.repo = hg.repository(self.ui, branchpath)
115 self.repo = hg.repository(self.ui, branchpath)
104 except Exception:
116 except Exception:
105 self.repo = hg.repository(self.ui, branchpath, create=True)
117 self.repo = hg.repository(self.ui, branchpath, create=True)
106 self.before()
118 self.before()
107
119
108 # pbranches may bring revisions from other branches (merge parents)
120 # pbranches may bring revisions from other branches (merge parents)
109 # Make sure we have them, or pull them.
121 # Make sure we have them, or pull them.
110 missings = {}
122 missings = {}
111 for b in pbranches:
123 for b in pbranches:
112 try:
124 try:
113 self.repo.lookup(b[0])
125 self.repo.lookup(b[0])
114 except Exception:
126 except Exception:
115 missings.setdefault(b[1], []).append(b[0])
127 missings.setdefault(b[1], []).append(b[0])
116
128
117 if missings:
129 if missings:
118 self.after()
130 self.after()
119 for pbranch, heads in sorted(missings.iteritems()):
131 for pbranch, heads in sorted(missings.iteritems()):
120 pbranchpath = os.path.join(self.path, pbranch)
132 pbranchpath = os.path.join(self.path, pbranch)
121 prepo = hg.peer(self.ui, {}, pbranchpath)
133 prepo = hg.peer(self.ui, {}, pbranchpath)
122 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
134 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
123 exchange.pull(self.repo, prepo,
135 exchange.pull(self.repo, prepo,
124 [prepo.lookup(h) for h in heads])
136 [prepo.lookup(h) for h in heads])
125 self.before()
137 self.before()
126
138
127 def _rewritetags(self, source, revmap, data):
139 def _rewritetags(self, source, revmap, data):
128 fp = cStringIO.StringIO()
140 fp = cStringIO.StringIO()
129 for line in data.splitlines():
141 for line in data.splitlines():
130 s = line.split(' ', 1)
142 s = line.split(' ', 1)
131 if len(s) != 2:
143 if len(s) != 2:
132 continue
144 continue
133 revid = revmap.get(source.lookuprev(s[0]))
145 revid = revmap.get(source.lookuprev(s[0]))
134 if not revid:
146 if not revid:
135 if s[0] == hex(nullid):
147 if s[0] == nodemod.nullhex:
136 revid = s[0]
148 revid = s[0]
137 else:
149 else:
138 continue
150 continue
139 fp.write('%s %s\n' % (revid, s[1]))
151 fp.write('%s %s\n' % (revid, s[1]))
140 return fp.getvalue()
152 return fp.getvalue()
141
153
142 def _rewritesubstate(self, source, data):
154 def _rewritesubstate(self, source, data):
143 fp = cStringIO.StringIO()
155 fp = cStringIO.StringIO()
144 for line in data.splitlines():
156 for line in data.splitlines():
145 s = line.split(' ', 1)
157 s = line.split(' ', 1)
146 if len(s) != 2:
158 if len(s) != 2:
147 continue
159 continue
148
160
149 revid = s[0]
161 revid = s[0]
150 subpath = s[1]
162 subpath = s[1]
151 if revid != hex(nullid):
163 if revid != nodemod.nullhex:
152 revmap = self.subrevmaps.get(subpath)
164 revmap = self.subrevmaps.get(subpath)
153 if revmap is None:
165 if revmap is None:
154 revmap = mapfile(self.ui,
166 revmap = mapfile(self.ui,
155 self.repo.wjoin(subpath, '.hg/shamap'))
167 self.repo.wjoin(subpath, '.hg/shamap'))
156 self.subrevmaps[subpath] = revmap
168 self.subrevmaps[subpath] = revmap
157
169
158 # It is reasonable that one or more of the subrepos don't
170 # It is reasonable that one or more of the subrepos don't
159 # need to be converted, in which case they can be cloned
171 # need to be converted, in which case they can be cloned
160 # into place instead of converted. Therefore, only warn
172 # into place instead of converted. Therefore, only warn
161 # once.
173 # once.
162 msg = _('no ".hgsubstate" updates will be made for "%s"\n')
174 msg = _('no ".hgsubstate" updates will be made for "%s"\n')
163 if len(revmap) == 0:
175 if len(revmap) == 0:
164 sub = self.repo.wvfs.reljoin(subpath, '.hg')
176 sub = self.repo.wvfs.reljoin(subpath, '.hg')
165
177
166 if self.repo.wvfs.exists(sub):
178 if self.repo.wvfs.exists(sub):
167 self.ui.warn(msg % subpath)
179 self.ui.warn(msg % subpath)
168
180
169 newid = revmap.get(revid)
181 newid = revmap.get(revid)
170 if not newid:
182 if not newid:
171 if len(revmap) > 0:
183 if len(revmap) > 0:
172 self.ui.warn(_("%s is missing from %s/.hg/shamap\n") %
184 self.ui.warn(_("%s is missing from %s/.hg/shamap\n") %
173 (revid, subpath))
185 (revid, subpath))
174 else:
186 else:
175 revid = newid
187 revid = newid
176
188
177 fp.write('%s %s\n' % (revid, subpath))
189 fp.write('%s %s\n' % (revid, subpath))
178
190
179 return fp.getvalue()
191 return fp.getvalue()
180
192
181 def _calculatemergedfiles(self, source, p1ctx, p2ctx):
193 def _calculatemergedfiles(self, source, p1ctx, p2ctx):
182 """Calculates the files from p2 that we need to pull in when merging p1
194 """Calculates the files from p2 that we need to pull in when merging p1
183 and p2, given that the merge is coming from the given source.
195 and p2, given that the merge is coming from the given source.
184
196
185 This prevents us from losing files that only exist in the target p2 and
197 This prevents us from losing files that only exist in the target p2 and
186 that don't come from the source repo (like if you're merging multiple
198 that don't come from the source repo (like if you're merging multiple
187 repositories together).
199 repositories together).
188 """
200 """
189 anc = [p1ctx.ancestor(p2ctx)]
201 anc = [p1ctx.ancestor(p2ctx)]
190 # Calculate what files are coming from p2
202 # Calculate what files are coming from p2
191 actions, diverge, rename = mergemod.calculateupdates(
203 actions, diverge, rename = mergemod.calculateupdates(
192 self.repo, p1ctx, p2ctx, anc,
204 self.repo, p1ctx, p2ctx, anc,
193 True, # branchmerge
205 True, # branchmerge
194 True, # force
206 True, # force
195 False, # acceptremote
207 False, # acceptremote
196 False, # followcopies
208 False, # followcopies
197 )
209 )
198
210
199 for file, (action, info, msg) in actions.iteritems():
211 for file, (action, info, msg) in actions.iteritems():
200 if source.targetfilebelongstosource(file):
212 if source.targetfilebelongstosource(file):
201 # If the file belongs to the source repo, ignore the p2
213 # If the file belongs to the source repo, ignore the p2
202 # since it will be covered by the existing fileset.
214 # since it will be covered by the existing fileset.
203 continue
215 continue
204
216
205 # If the file requires actual merging, abort. We don't have enough
217 # If the file requires actual merging, abort. We don't have enough
206 # context to resolve merges correctly.
218 # context to resolve merges correctly.
207 if action in ['m', 'dm', 'cd', 'dc']:
219 if action in ['m', 'dm', 'cd', 'dc']:
208 raise error.Abort(_("unable to convert merge commit "
220 raise error.Abort(_("unable to convert merge commit "
209 "since target parents do not merge cleanly (file "
221 "since target parents do not merge cleanly (file "
210 "%s, parents %s and %s)") % (file, p1ctx,
222 "%s, parents %s and %s)") % (file, p1ctx,
211 p2ctx))
223 p2ctx))
212 elif action == 'k':
224 elif action == 'k':
213 # 'keep' means nothing changed from p1
225 # 'keep' means nothing changed from p1
214 continue
226 continue
215 else:
227 else:
216 # Any other change means we want to take the p2 version
228 # Any other change means we want to take the p2 version
217 yield file
229 yield file
218
230
219 def putcommit(self, files, copies, parents, commit, source, revmap, full,
231 def putcommit(self, files, copies, parents, commit, source, revmap, full,
220 cleanp2):
232 cleanp2):
221 files = dict(files)
233 files = dict(files)
222
234
223 def getfilectx(repo, memctx, f):
235 def getfilectx(repo, memctx, f):
224 if p2ctx and f in p2files and f not in copies:
236 if p2ctx and f in p2files and f not in copies:
225 self.ui.debug('reusing %s from p2\n' % f)
237 self.ui.debug('reusing %s from p2\n' % f)
226 try:
238 try:
227 return p2ctx[f]
239 return p2ctx[f]
228 except error.ManifestLookupError:
240 except error.ManifestLookupError:
229 # If the file doesn't exist in p2, then we're syncing a
241 # If the file doesn't exist in p2, then we're syncing a
230 # delete, so just return None.
242 # delete, so just return None.
231 return None
243 return None
232 try:
244 try:
233 v = files[f]
245 v = files[f]
234 except KeyError:
246 except KeyError:
235 return None
247 return None
236 data, mode = source.getfile(f, v)
248 data, mode = source.getfile(f, v)
237 if data is None:
249 if data is None:
238 return None
250 return None
239 if f == '.hgtags':
251 if f == '.hgtags':
240 data = self._rewritetags(source, revmap, data)
252 data = self._rewritetags(source, revmap, data)
241 if f == '.hgsubstate':
253 if f == '.hgsubstate':
242 data = self._rewritesubstate(source, data)
254 data = self._rewritesubstate(source, data)
243 return context.memfilectx(self.repo, f, data, 'l' in mode,
255 return context.memfilectx(self.repo, f, data, 'l' in mode,
244 'x' in mode, copies.get(f))
256 'x' in mode, copies.get(f))
245
257
246 pl = []
258 pl = []
247 for p in parents:
259 for p in parents:
248 if p not in pl:
260 if p not in pl:
249 pl.append(p)
261 pl.append(p)
250 parents = pl
262 parents = pl
251 nparents = len(parents)
263 nparents = len(parents)
252 if self.filemapmode and nparents == 1:
264 if self.filemapmode and nparents == 1:
253 m1node = self.repo.changelog.read(bin(parents[0]))[0]
265 m1node = self.repo.changelog.read(nodemod.bin(parents[0]))[0]
254 parent = parents[0]
266 parent = parents[0]
255
267
256 if len(parents) < 2:
268 if len(parents) < 2:
257 parents.append(nullid)
269 parents.append(nodemod.nullid)
258 if len(parents) < 2:
270 if len(parents) < 2:
259 parents.append(nullid)
271 parents.append(nodemod.nullid)
260 p2 = parents.pop(0)
272 p2 = parents.pop(0)
261
273
262 text = commit.desc
274 text = commit.desc
263
275
264 sha1s = re.findall(sha1re, text)
276 sha1s = re.findall(sha1re, text)
265 for sha1 in sha1s:
277 for sha1 in sha1s:
266 oldrev = source.lookuprev(sha1)
278 oldrev = source.lookuprev(sha1)
267 newrev = revmap.get(oldrev)
279 newrev = revmap.get(oldrev)
268 if newrev is not None:
280 if newrev is not None:
269 text = text.replace(sha1, newrev[:len(sha1)])
281 text = text.replace(sha1, newrev[:len(sha1)])
270
282
271 extra = commit.extra.copy()
283 extra = commit.extra.copy()
272
284
273 sourcename = self.repo.ui.config('convert', 'hg.sourcename')
285 sourcename = self.repo.ui.config('convert', 'hg.sourcename')
274 if sourcename:
286 if sourcename:
275 extra['convert_source'] = sourcename
287 extra['convert_source'] = sourcename
276
288
277 for label in ('source', 'transplant_source', 'rebase_source',
289 for label in ('source', 'transplant_source', 'rebase_source',
278 'intermediate-source'):
290 'intermediate-source'):
279 node = extra.get(label)
291 node = extra.get(label)
280
292
281 if node is None:
293 if node is None:
282 continue
294 continue
283
295
284 # Only transplant stores its reference in binary
296 # Only transplant stores its reference in binary
285 if label == 'transplant_source':
297 if label == 'transplant_source':
286 node = hex(node)
298 node = nodemod.hex(node)
287
299
288 newrev = revmap.get(node)
300 newrev = revmap.get(node)
289 if newrev is not None:
301 if newrev is not None:
290 if label == 'transplant_source':
302 if label == 'transplant_source':
291 newrev = bin(newrev)
303 newrev = nodemod.bin(newrev)
292
304
293 extra[label] = newrev
305 extra[label] = newrev
294
306
295 if self.branchnames and commit.branch:
307 if self.branchnames and commit.branch:
296 extra['branch'] = commit.branch
308 extra['branch'] = commit.branch
297 if commit.rev and commit.saverev:
309 if commit.rev and commit.saverev:
298 extra['convert_revision'] = commit.rev
310 extra['convert_revision'] = commit.rev
299
311
300 while parents:
312 while parents:
301 p1 = p2
313 p1 = p2
302 p2 = parents.pop(0)
314 p2 = parents.pop(0)
303 p1ctx = self.repo[p1]
315 p1ctx = self.repo[p1]
304 p2ctx = None
316 p2ctx = None
305 if p2 != nullid:
317 if p2 != nodemod.nullid:
306 p2ctx = self.repo[p2]
318 p2ctx = self.repo[p2]
307 fileset = set(files)
319 fileset = set(files)
308 if full:
320 if full:
309 fileset.update(self.repo[p1])
321 fileset.update(self.repo[p1])
310 fileset.update(self.repo[p2])
322 fileset.update(self.repo[p2])
311
323
312 if p2ctx:
324 if p2ctx:
313 p2files = set(cleanp2)
325 p2files = set(cleanp2)
314 for file in self._calculatemergedfiles(source, p1ctx, p2ctx):
326 for file in self._calculatemergedfiles(source, p1ctx, p2ctx):
315 p2files.add(file)
327 p2files.add(file)
316 fileset.add(file)
328 fileset.add(file)
317
329
318 ctx = context.memctx(self.repo, (p1, p2), text, fileset,
330 ctx = context.memctx(self.repo, (p1, p2), text, fileset,
319 getfilectx, commit.author, commit.date, extra)
331 getfilectx, commit.author, commit.date, extra)
320
332
321 # We won't know if the conversion changes the node until after the
333 # We won't know if the conversion changes the node until after the
322 # commit, so copy the source's phase for now.
334 # commit, so copy the source's phase for now.
323 self.repo.ui.setconfig('phases', 'new-commit',
335 self.repo.ui.setconfig('phases', 'new-commit',
324 phases.phasenames[commit.phase], 'convert')
336 phases.phasenames[commit.phase], 'convert')
325
337
326 with self.repo.transaction("convert") as tr:
338 with self.repo.transaction("convert") as tr:
327 node = hex(self.repo.commitctx(ctx))
339 node = nodemod.hex(self.repo.commitctx(ctx))
328
340
329 # If the node value has changed, but the phase is lower than
341 # If the node value has changed, but the phase is lower than
330 # draft, set it back to draft since it hasn't been exposed
342 # draft, set it back to draft since it hasn't been exposed
331 # anywhere.
343 # anywhere.
332 if commit.rev != node:
344 if commit.rev != node:
333 ctx = self.repo[node]
345 ctx = self.repo[node]
334 if ctx.phase() < phases.draft:
346 if ctx.phase() < phases.draft:
335 phases.retractboundary(self.repo, tr, phases.draft,
347 phases.retractboundary(self.repo, tr, phases.draft,
336 [ctx.node()])
348 [ctx.node()])
337
349
338 text = "(octopus merge fixup)\n"
350 text = "(octopus merge fixup)\n"
339 p2 = node
351 p2 = node
340
352
341 if self.filemapmode and nparents == 1:
353 if self.filemapmode and nparents == 1:
342 man = self.repo.manifest
354 man = self.repo.manifest
343 mnode = self.repo.changelog.read(bin(p2))[0]
355 mnode = self.repo.changelog.read(nodemod.bin(p2))[0]
344 closed = 'close' in commit.extra
356 closed = 'close' in commit.extra
345 if not closed and not man.cmp(m1node, man.revision(mnode)):
357 if not closed and not man.cmp(m1node, man.revision(mnode)):
346 self.ui.status(_("filtering out empty revision\n"))
358 self.ui.status(_("filtering out empty revision\n"))
347 self.repo.rollback(force=True)
359 self.repo.rollback(force=True)
348 return parent
360 return parent
349 return p2
361 return p2
350
362
351 def puttags(self, tags):
363 def puttags(self, tags):
352 try:
364 try:
353 parentctx = self.repo[self.tagsbranch]
365 parentctx = self.repo[self.tagsbranch]
354 tagparent = parentctx.node()
366 tagparent = parentctx.node()
355 except error.RepoError:
367 except error.RepoError:
356 parentctx = None
368 parentctx = None
357 tagparent = nullid
369 tagparent = nodemod.nullid
358
370
359 oldlines = set()
371 oldlines = set()
360 for branch, heads in self.repo.branchmap().iteritems():
372 for branch, heads in self.repo.branchmap().iteritems():
361 for h in heads:
373 for h in heads:
362 if '.hgtags' in self.repo[h]:
374 if '.hgtags' in self.repo[h]:
363 oldlines.update(
375 oldlines.update(
364 set(self.repo[h]['.hgtags'].data().splitlines(True)))
376 set(self.repo[h]['.hgtags'].data().splitlines(True)))
365 oldlines = sorted(list(oldlines))
377 oldlines = sorted(list(oldlines))
366
378
367 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
379 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
368 if newlines == oldlines:
380 if newlines == oldlines:
369 return None, None
381 return None, None
370
382
371 # if the old and new tags match, then there is nothing to update
383 # if the old and new tags match, then there is nothing to update
372 oldtags = set()
384 oldtags = set()
373 newtags = set()
385 newtags = set()
374 for line in oldlines:
386 for line in oldlines:
375 s = line.strip().split(' ', 1)
387 s = line.strip().split(' ', 1)
376 if len(s) != 2:
388 if len(s) != 2:
377 continue
389 continue
378 oldtags.add(s[1])
390 oldtags.add(s[1])
379 for line in newlines:
391 for line in newlines:
380 s = line.strip().split(' ', 1)
392 s = line.strip().split(' ', 1)
381 if len(s) != 2:
393 if len(s) != 2:
382 continue
394 continue
383 if s[1] not in oldtags:
395 if s[1] not in oldtags:
384 newtags.add(s[1].strip())
396 newtags.add(s[1].strip())
385
397
386 if not newtags:
398 if not newtags:
387 return None, None
399 return None, None
388
400
389 data = "".join(newlines)
401 data = "".join(newlines)
390 def getfilectx(repo, memctx, f):
402 def getfilectx(repo, memctx, f):
391 return context.memfilectx(repo, f, data, False, False, None)
403 return context.memfilectx(repo, f, data, False, False, None)
392
404
393 self.ui.status(_("updating tags\n"))
405 self.ui.status(_("updating tags\n"))
394 date = "%s 0" % int(time.mktime(time.gmtime()))
406 date = "%s 0" % int(time.mktime(time.gmtime()))
395 extra = {'branch': self.tagsbranch}
407 extra = {'branch': self.tagsbranch}
396 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
408 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
397 [".hgtags"], getfilectx, "convert-repo", date,
409 [".hgtags"], getfilectx, "convert-repo", date,
398 extra)
410 extra)
399 node = self.repo.commitctx(ctx)
411 node = self.repo.commitctx(ctx)
400 return hex(node), hex(tagparent)
412 return nodemod.hex(node), nodemod.hex(tagparent)
401
413
402 def setfilemapmode(self, active):
414 def setfilemapmode(self, active):
403 self.filemapmode = active
415 self.filemapmode = active
404
416
405 def putbookmarks(self, updatedbookmark):
417 def putbookmarks(self, updatedbookmark):
406 if not len(updatedbookmark):
418 if not len(updatedbookmark):
407 return
419 return
408 wlock = lock = tr = None
420 wlock = lock = tr = None
409 try:
421 try:
410 wlock = self.repo.wlock()
422 wlock = self.repo.wlock()
411 lock = self.repo.lock()
423 lock = self.repo.lock()
412 tr = self.repo.transaction('bookmark')
424 tr = self.repo.transaction('bookmark')
413 self.ui.status(_("updating bookmarks\n"))
425 self.ui.status(_("updating bookmarks\n"))
414 destmarks = self.repo._bookmarks
426 destmarks = self.repo._bookmarks
415 for bookmark in updatedbookmark:
427 for bookmark in updatedbookmark:
416 destmarks[bookmark] = bin(updatedbookmark[bookmark])
428 destmarks[bookmark] = nodemod.bin(updatedbookmark[bookmark])
417 destmarks.recordchange(tr)
429 destmarks.recordchange(tr)
418 tr.close()
430 tr.close()
419 finally:
431 finally:
420 lockmod.release(lock, wlock, tr)
432 lockmod.release(lock, wlock, tr)
421
433
422 def hascommitfrommap(self, rev):
434 def hascommitfrommap(self, rev):
423 # the exact semantics of clonebranches is unclear so we can't say no
435 # the exact semantics of clonebranches is unclear so we can't say no
424 return rev in self.repo or self.clonebranches
436 return rev in self.repo or self.clonebranches
425
437
426 def hascommitforsplicemap(self, rev):
438 def hascommitforsplicemap(self, rev):
427 if rev not in self.repo and self.clonebranches:
439 if rev not in self.repo and self.clonebranches:
428 raise error.Abort(_('revision %s not found in destination '
440 raise error.Abort(_('revision %s not found in destination '
429 'repository (lookups with clonebranches=true '
441 'repository (lookups with clonebranches=true '
430 'are not implemented)') % rev)
442 'are not implemented)') % rev)
431 return rev in self.repo
443 return rev in self.repo
432
444
433 class mercurial_source(converter_source):
445 class mercurial_source(common.converter_source):
434 def __init__(self, ui, path, revs=None):
446 def __init__(self, ui, path, revs=None):
435 converter_source.__init__(self, ui, path, revs)
447 common.converter_source.__init__(self, ui, path, revs)
436 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
448 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
437 self.ignored = set()
449 self.ignored = set()
438 self.saverev = ui.configbool('convert', 'hg.saverev', False)
450 self.saverev = ui.configbool('convert', 'hg.saverev', False)
439 try:
451 try:
440 self.repo = hg.repository(self.ui, path)
452 self.repo = hg.repository(self.ui, path)
441 # try to provoke an exception if this isn't really a hg
453 # try to provoke an exception if this isn't really a hg
442 # repo, but some other bogus compatible-looking url
454 # repo, but some other bogus compatible-looking url
443 if not self.repo.local():
455 if not self.repo.local():
444 raise error.RepoError
456 raise error.RepoError
445 except error.RepoError:
457 except error.RepoError:
446 ui.traceback()
458 ui.traceback()
447 raise NoRepo(_("%s is not a local Mercurial repository") % path)
459 raise NoRepo(_("%s is not a local Mercurial repository") % path)
448 self.lastrev = None
460 self.lastrev = None
449 self.lastctx = None
461 self.lastctx = None
450 self._changescache = None, None
462 self._changescache = None, None
451 self.convertfp = None
463 self.convertfp = None
452 # Restrict converted revisions to startrev descendants
464 # Restrict converted revisions to startrev descendants
453 startnode = ui.config('convert', 'hg.startrev')
465 startnode = ui.config('convert', 'hg.startrev')
454 hgrevs = ui.config('convert', 'hg.revs')
466 hgrevs = ui.config('convert', 'hg.revs')
455 if hgrevs is None:
467 if hgrevs is None:
456 if startnode is not None:
468 if startnode is not None:
457 try:
469 try:
458 startnode = self.repo.lookup(startnode)
470 startnode = self.repo.lookup(startnode)
459 except error.RepoError:
471 except error.RepoError:
460 raise error.Abort(_('%s is not a valid start revision')
472 raise error.Abort(_('%s is not a valid start revision')
461 % startnode)
473 % startnode)
462 startrev = self.repo.changelog.rev(startnode)
474 startrev = self.repo.changelog.rev(startnode)
463 children = {startnode: 1}
475 children = {startnode: 1}
464 for r in self.repo.changelog.descendants([startrev]):
476 for r in self.repo.changelog.descendants([startrev]):
465 children[self.repo.changelog.node(r)] = 1
477 children[self.repo.changelog.node(r)] = 1
466 self.keep = children.__contains__
478 self.keep = children.__contains__
467 else:
479 else:
468 self.keep = util.always
480 self.keep = util.always
469 if revs:
481 if revs:
470 self._heads = [self.repo[r].node() for r in revs]
482 self._heads = [self.repo[r].node() for r in revs]
471 else:
483 else:
472 self._heads = self.repo.heads()
484 self._heads = self.repo.heads()
473 else:
485 else:
474 if revs or startnode is not None:
486 if revs or startnode is not None:
475 raise error.Abort(_('hg.revs cannot be combined with '
487 raise error.Abort(_('hg.revs cannot be combined with '
476 'hg.startrev or --rev'))
488 'hg.startrev or --rev'))
477 nodes = set()
489 nodes = set()
478 parents = set()
490 parents = set()
479 for r in scmutil.revrange(self.repo, [hgrevs]):
491 for r in scmutil.revrange(self.repo, [hgrevs]):
480 ctx = self.repo[r]
492 ctx = self.repo[r]
481 nodes.add(ctx.node())
493 nodes.add(ctx.node())
482 parents.update(p.node() for p in ctx.parents())
494 parents.update(p.node() for p in ctx.parents())
483 self.keep = nodes.__contains__
495 self.keep = nodes.__contains__
484 self._heads = nodes - parents
496 self._heads = nodes - parents
485
497
486 def _changectx(self, rev):
498 def _changectx(self, rev):
487 if self.lastrev != rev:
499 if self.lastrev != rev:
488 self.lastctx = self.repo[rev]
500 self.lastctx = self.repo[rev]
489 self.lastrev = rev
501 self.lastrev = rev
490 return self.lastctx
502 return self.lastctx
491
503
492 def _parents(self, ctx):
504 def _parents(self, ctx):
493 return [p for p in ctx.parents() if p and self.keep(p.node())]
505 return [p for p in ctx.parents() if p and self.keep(p.node())]
494
506
495 def getheads(self):
507 def getheads(self):
496 return [hex(h) for h in self._heads if self.keep(h)]
508 return [nodemod.hex(h) for h in self._heads if self.keep(h)]
497
509
498 def getfile(self, name, rev):
510 def getfile(self, name, rev):
499 try:
511 try:
500 fctx = self._changectx(rev)[name]
512 fctx = self._changectx(rev)[name]
501 return fctx.data(), fctx.flags()
513 return fctx.data(), fctx.flags()
502 except error.LookupError:
514 except error.LookupError:
503 return None, None
515 return None, None
504
516
505 def _changedfiles(self, ctx1, ctx2):
517 def _changedfiles(self, ctx1, ctx2):
506 ma, r = [], []
518 ma, r = [], []
507 maappend = ma.append
519 maappend = ma.append
508 rappend = r.append
520 rappend = r.append
509 d = ctx1.manifest().diff(ctx2.manifest())
521 d = ctx1.manifest().diff(ctx2.manifest())
510 for f, ((node1, flag1), (node2, flag2)) in d.iteritems():
522 for f, ((node1, flag1), (node2, flag2)) in d.iteritems():
511 if node2 is None:
523 if node2 is None:
512 rappend(f)
524 rappend(f)
513 else:
525 else:
514 maappend(f)
526 maappend(f)
515 return ma, r
527 return ma, r
516
528
517 def getchanges(self, rev, full):
529 def getchanges(self, rev, full):
518 ctx = self._changectx(rev)
530 ctx = self._changectx(rev)
519 parents = self._parents(ctx)
531 parents = self._parents(ctx)
520 if full or not parents:
532 if full or not parents:
521 files = copyfiles = ctx.manifest()
533 files = copyfiles = ctx.manifest()
522 if parents:
534 if parents:
523 if self._changescache[0] == rev:
535 if self._changescache[0] == rev:
524 ma, r = self._changescache[1]
536 ma, r = self._changescache[1]
525 else:
537 else:
526 ma, r = self._changedfiles(parents[0], ctx)
538 ma, r = self._changedfiles(parents[0], ctx)
527 if not full:
539 if not full:
528 files = ma + r
540 files = ma + r
529 copyfiles = ma
541 copyfiles = ma
530 # _getcopies() is also run for roots and before filtering so missing
542 # _getcopies() is also run for roots and before filtering so missing
531 # revlogs are detected early
543 # revlogs are detected early
532 copies = self._getcopies(ctx, parents, copyfiles)
544 copies = self._getcopies(ctx, parents, copyfiles)
533 cleanp2 = set()
545 cleanp2 = set()
534 if len(parents) == 2:
546 if len(parents) == 2:
535 d = parents[1].manifest().diff(ctx.manifest(), clean=True)
547 d = parents[1].manifest().diff(ctx.manifest(), clean=True)
536 for f, value in d.iteritems():
548 for f, value in d.iteritems():
537 if value is None:
549 if value is None:
538 cleanp2.add(f)
550 cleanp2.add(f)
539 changes = [(f, rev) for f in files if f not in self.ignored]
551 changes = [(f, rev) for f in files if f not in self.ignored]
540 changes.sort()
552 changes.sort()
541 return changes, copies, cleanp2
553 return changes, copies, cleanp2
542
554
543 def _getcopies(self, ctx, parents, files):
555 def _getcopies(self, ctx, parents, files):
544 copies = {}
556 copies = {}
545 for name in files:
557 for name in files:
546 if name in self.ignored:
558 if name in self.ignored:
547 continue
559 continue
548 try:
560 try:
549 copysource, _copynode = ctx.filectx(name).renamed()
561 copysource, _copynode = ctx.filectx(name).renamed()
550 if copysource in self.ignored:
562 if copysource in self.ignored:
551 continue
563 continue
552 # Ignore copy sources not in parent revisions
564 # Ignore copy sources not in parent revisions
553 found = False
565 found = False
554 for p in parents:
566 for p in parents:
555 if copysource in p:
567 if copysource in p:
556 found = True
568 found = True
557 break
569 break
558 if not found:
570 if not found:
559 continue
571 continue
560 copies[name] = copysource
572 copies[name] = copysource
561 except TypeError:
573 except TypeError:
562 pass
574 pass
563 except error.LookupError as e:
575 except error.LookupError as e:
564 if not self.ignoreerrors:
576 if not self.ignoreerrors:
565 raise
577 raise
566 self.ignored.add(name)
578 self.ignored.add(name)
567 self.ui.warn(_('ignoring: %s\n') % e)
579 self.ui.warn(_('ignoring: %s\n') % e)
568 return copies
580 return copies
569
581
570 def getcommit(self, rev):
582 def getcommit(self, rev):
571 ctx = self._changectx(rev)
583 ctx = self._changectx(rev)
572 parents = [p.hex() for p in self._parents(ctx)]
584 parents = [p.hex() for p in self._parents(ctx)]
573 crev = rev
585 crev = rev
574
586
575 return commit(author=ctx.user(),
587 return common.commit(author=ctx.user(),
576 date=util.datestr(ctx.date(), '%Y-%m-%d %H:%M:%S %1%2'),
588 date=util.datestr(ctx.date(),
577 desc=ctx.description(), rev=crev, parents=parents,
589 '%Y-%m-%d %H:%M:%S %1%2'),
578 branch=ctx.branch(), extra=ctx.extra(),
590 desc=ctx.description(),
579 sortkey=ctx.rev(), saverev=self.saverev,
591 rev=crev,
580 phase=ctx.phase())
592 parents=parents,
593 branch=ctx.branch(),
594 extra=ctx.extra(),
595 sortkey=ctx.rev(),
596 saverev=self.saverev,
597 phase=ctx.phase())
581
598
582 def gettags(self):
599 def gettags(self):
583 # This will get written to .hgtags, filter non global tags out.
600 # This will get written to .hgtags, filter non global tags out.
584 tags = [t for t in self.repo.tagslist()
601 tags = [t for t in self.repo.tagslist()
585 if self.repo.tagtype(t[0]) == 'global']
602 if self.repo.tagtype(t[0]) == 'global']
586 return dict([(name, hex(node)) for name, node in tags
603 return dict([(name, nodemod.hex(node)) for name, node in tags
587 if self.keep(node)])
604 if self.keep(node)])
588
605
589 def getchangedfiles(self, rev, i):
606 def getchangedfiles(self, rev, i):
590 ctx = self._changectx(rev)
607 ctx = self._changectx(rev)
591 parents = self._parents(ctx)
608 parents = self._parents(ctx)
592 if not parents and i is None:
609 if not parents and i is None:
593 i = 0
610 i = 0
594 ma, r = ctx.manifest().keys(), []
611 ma, r = ctx.manifest().keys(), []
595 else:
612 else:
596 i = i or 0
613 i = i or 0
597 ma, r = self._changedfiles(parents[i], ctx)
614 ma, r = self._changedfiles(parents[i], ctx)
598 ma, r = [[f for f in l if f not in self.ignored] for l in (ma, r)]
615 ma, r = [[f for f in l if f not in self.ignored] for l in (ma, r)]
599
616
600 if i == 0:
617 if i == 0:
601 self._changescache = (rev, (ma, r))
618 self._changescache = (rev, (ma, r))
602
619
603 return ma + r
620 return ma + r
604
621
605 def converted(self, rev, destrev):
622 def converted(self, rev, destrev):
606 if self.convertfp is None:
623 if self.convertfp is None:
607 self.convertfp = open(self.repo.join('shamap'), 'a')
624 self.convertfp = open(self.repo.join('shamap'), 'a')
608 self.convertfp.write('%s %s\n' % (destrev, rev))
625 self.convertfp.write('%s %s\n' % (destrev, rev))
609 self.convertfp.flush()
626 self.convertfp.flush()
610
627
611 def before(self):
628 def before(self):
612 self.ui.debug('run hg source pre-conversion action\n')
629 self.ui.debug('run hg source pre-conversion action\n')
613
630
614 def after(self):
631 def after(self):
615 self.ui.debug('run hg source post-conversion action\n')
632 self.ui.debug('run hg source post-conversion action\n')
616
633
617 def hasnativeorder(self):
634 def hasnativeorder(self):
618 return True
635 return True
619
636
620 def hasnativeclose(self):
637 def hasnativeclose(self):
621 return True
638 return True
622
639
623 def lookuprev(self, rev):
640 def lookuprev(self, rev):
624 try:
641 try:
625 return hex(self.repo.lookup(rev))
642 return nodemod.hex(self.repo.lookup(rev))
626 except (error.RepoError, error.LookupError):
643 except (error.RepoError, error.LookupError):
627 return None
644 return None
628
645
629 def getbookmarks(self):
646 def getbookmarks(self):
630 return bookmarks.listbookmarks(self.repo)
647 return bookmarks.listbookmarks(self.repo)
631
648
632 def checkrevformat(self, revstr, mapname='splicemap'):
649 def checkrevformat(self, revstr, mapname='splicemap'):
633 """ Mercurial, revision string is a 40 byte hex """
650 """ Mercurial, revision string is a 40 byte hex """
634 self.checkhexformat(revstr, mapname)
651 self.checkhexformat(revstr, mapname)
@@ -1,153 +1,152 b''
1 #require test-repo
1 #require test-repo
2
2
3 $ cd "$TESTDIR"/..
3 $ cd "$TESTDIR"/..
4
4
5 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs python contrib/check-py3-compat.py
5 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs python contrib/check-py3-compat.py
6 contrib/check-code.py not using absolute_import
6 contrib/check-code.py not using absolute_import
7 contrib/check-code.py requires print_function
7 contrib/check-code.py requires print_function
8 contrib/debugshell.py not using absolute_import
8 contrib/debugshell.py not using absolute_import
9 contrib/hgfixes/fix_bytes.py not using absolute_import
9 contrib/hgfixes/fix_bytes.py not using absolute_import
10 contrib/hgfixes/fix_bytesmod.py not using absolute_import
10 contrib/hgfixes/fix_bytesmod.py not using absolute_import
11 contrib/hgfixes/fix_leftover_imports.py not using absolute_import
11 contrib/hgfixes/fix_leftover_imports.py not using absolute_import
12 contrib/import-checker.py not using absolute_import
12 contrib/import-checker.py not using absolute_import
13 contrib/import-checker.py requires print_function
13 contrib/import-checker.py requires print_function
14 contrib/memory.py not using absolute_import
14 contrib/memory.py not using absolute_import
15 contrib/perf.py not using absolute_import
15 contrib/perf.py not using absolute_import
16 contrib/python-hook-examples.py not using absolute_import
16 contrib/python-hook-examples.py not using absolute_import
17 contrib/revsetbenchmarks.py not using absolute_import
17 contrib/revsetbenchmarks.py not using absolute_import
18 contrib/revsetbenchmarks.py requires print_function
18 contrib/revsetbenchmarks.py requires print_function
19 contrib/showstack.py not using absolute_import
19 contrib/showstack.py not using absolute_import
20 contrib/synthrepo.py not using absolute_import
20 contrib/synthrepo.py not using absolute_import
21 contrib/win32/hgwebdir_wsgi.py not using absolute_import
21 contrib/win32/hgwebdir_wsgi.py not using absolute_import
22 doc/check-seclevel.py not using absolute_import
22 doc/check-seclevel.py not using absolute_import
23 doc/gendoc.py not using absolute_import
23 doc/gendoc.py not using absolute_import
24 doc/hgmanpage.py not using absolute_import
24 doc/hgmanpage.py not using absolute_import
25 hgext/__init__.py not using absolute_import
25 hgext/__init__.py not using absolute_import
26 hgext/color.py not using absolute_import
26 hgext/color.py not using absolute_import
27 hgext/convert/__init__.py not using absolute_import
27 hgext/convert/__init__.py not using absolute_import
28 hgext/convert/bzr.py not using absolute_import
28 hgext/convert/bzr.py not using absolute_import
29 hgext/convert/common.py not using absolute_import
29 hgext/convert/common.py not using absolute_import
30 hgext/convert/convcmd.py not using absolute_import
30 hgext/convert/convcmd.py not using absolute_import
31 hgext/convert/cvs.py not using absolute_import
31 hgext/convert/cvs.py not using absolute_import
32 hgext/convert/hg.py not using absolute_import
33 hgext/convert/monotone.py not using absolute_import
32 hgext/convert/monotone.py not using absolute_import
34 hgext/convert/p4.py not using absolute_import
33 hgext/convert/p4.py not using absolute_import
35 hgext/convert/subversion.py not using absolute_import
34 hgext/convert/subversion.py not using absolute_import
36 hgext/convert/transport.py not using absolute_import
35 hgext/convert/transport.py not using absolute_import
37 hgext/eol.py not using absolute_import
36 hgext/eol.py not using absolute_import
38 hgext/extdiff.py not using absolute_import
37 hgext/extdiff.py not using absolute_import
39 hgext/factotum.py not using absolute_import
38 hgext/factotum.py not using absolute_import
40 hgext/fetch.py not using absolute_import
39 hgext/fetch.py not using absolute_import
41 hgext/gpg.py not using absolute_import
40 hgext/gpg.py not using absolute_import
42 hgext/graphlog.py not using absolute_import
41 hgext/graphlog.py not using absolute_import
43 hgext/hgcia.py not using absolute_import
42 hgext/hgcia.py not using absolute_import
44 hgext/hgk.py not using absolute_import
43 hgext/hgk.py not using absolute_import
45 hgext/highlight/__init__.py not using absolute_import
44 hgext/highlight/__init__.py not using absolute_import
46 hgext/highlight/highlight.py not using absolute_import
45 hgext/highlight/highlight.py not using absolute_import
47 hgext/histedit.py not using absolute_import
46 hgext/histedit.py not using absolute_import
48 hgext/largefiles/__init__.py not using absolute_import
47 hgext/largefiles/__init__.py not using absolute_import
49 hgext/largefiles/basestore.py not using absolute_import
48 hgext/largefiles/basestore.py not using absolute_import
50 hgext/largefiles/lfcommands.py not using absolute_import
49 hgext/largefiles/lfcommands.py not using absolute_import
51 hgext/largefiles/lfutil.py not using absolute_import
50 hgext/largefiles/lfutil.py not using absolute_import
52 hgext/largefiles/localstore.py not using absolute_import
51 hgext/largefiles/localstore.py not using absolute_import
53 hgext/largefiles/overrides.py not using absolute_import
52 hgext/largefiles/overrides.py not using absolute_import
54 hgext/largefiles/proto.py not using absolute_import
53 hgext/largefiles/proto.py not using absolute_import
55 hgext/largefiles/remotestore.py not using absolute_import
54 hgext/largefiles/remotestore.py not using absolute_import
56 hgext/largefiles/reposetup.py not using absolute_import
55 hgext/largefiles/reposetup.py not using absolute_import
57 hgext/largefiles/uisetup.py not using absolute_import
56 hgext/largefiles/uisetup.py not using absolute_import
58 hgext/largefiles/wirestore.py not using absolute_import
57 hgext/largefiles/wirestore.py not using absolute_import
59 hgext/mq.py not using absolute_import
58 hgext/mq.py not using absolute_import
60 hgext/notify.py not using absolute_import
59 hgext/notify.py not using absolute_import
61 hgext/patchbomb.py not using absolute_import
60 hgext/patchbomb.py not using absolute_import
62 hgext/purge.py not using absolute_import
61 hgext/purge.py not using absolute_import
63 hgext/rebase.py not using absolute_import
62 hgext/rebase.py not using absolute_import
64 hgext/record.py not using absolute_import
63 hgext/record.py not using absolute_import
65 hgext/relink.py not using absolute_import
64 hgext/relink.py not using absolute_import
66 hgext/schemes.py not using absolute_import
65 hgext/schemes.py not using absolute_import
67 hgext/share.py not using absolute_import
66 hgext/share.py not using absolute_import
68 hgext/shelve.py not using absolute_import
67 hgext/shelve.py not using absolute_import
69 hgext/strip.py not using absolute_import
68 hgext/strip.py not using absolute_import
70 hgext/transplant.py not using absolute_import
69 hgext/transplant.py not using absolute_import
71 hgext/win32mbcs.py not using absolute_import
70 hgext/win32mbcs.py not using absolute_import
72 hgext/win32text.py not using absolute_import
71 hgext/win32text.py not using absolute_import
73 i18n/check-translation.py not using absolute_import
72 i18n/check-translation.py not using absolute_import
74 i18n/polib.py not using absolute_import
73 i18n/polib.py not using absolute_import
75 setup.py not using absolute_import
74 setup.py not using absolute_import
76 tests/filterpyflakes.py requires print_function
75 tests/filterpyflakes.py requires print_function
77 tests/generate-working-copy-states.py requires print_function
76 tests/generate-working-copy-states.py requires print_function
78 tests/get-with-headers.py requires print_function
77 tests/get-with-headers.py requires print_function
79 tests/heredoctest.py requires print_function
78 tests/heredoctest.py requires print_function
80 tests/hypothesishelpers.py not using absolute_import
79 tests/hypothesishelpers.py not using absolute_import
81 tests/hypothesishelpers.py requires print_function
80 tests/hypothesishelpers.py requires print_function
82 tests/killdaemons.py not using absolute_import
81 tests/killdaemons.py not using absolute_import
83 tests/md5sum.py not using absolute_import
82 tests/md5sum.py not using absolute_import
84 tests/mockblackbox.py not using absolute_import
83 tests/mockblackbox.py not using absolute_import
85 tests/printenv.py not using absolute_import
84 tests/printenv.py not using absolute_import
86 tests/readlink.py not using absolute_import
85 tests/readlink.py not using absolute_import
87 tests/readlink.py requires print_function
86 tests/readlink.py requires print_function
88 tests/revlog-formatv0.py not using absolute_import
87 tests/revlog-formatv0.py not using absolute_import
89 tests/run-tests.py not using absolute_import
88 tests/run-tests.py not using absolute_import
90 tests/seq.py not using absolute_import
89 tests/seq.py not using absolute_import
91 tests/seq.py requires print_function
90 tests/seq.py requires print_function
92 tests/silenttestrunner.py not using absolute_import
91 tests/silenttestrunner.py not using absolute_import
93 tests/silenttestrunner.py requires print_function
92 tests/silenttestrunner.py requires print_function
94 tests/sitecustomize.py not using absolute_import
93 tests/sitecustomize.py not using absolute_import
95 tests/svn-safe-append.py not using absolute_import
94 tests/svn-safe-append.py not using absolute_import
96 tests/svnxml.py not using absolute_import
95 tests/svnxml.py not using absolute_import
97 tests/test-ancestor.py requires print_function
96 tests/test-ancestor.py requires print_function
98 tests/test-atomictempfile.py not using absolute_import
97 tests/test-atomictempfile.py not using absolute_import
99 tests/test-batching.py not using absolute_import
98 tests/test-batching.py not using absolute_import
100 tests/test-batching.py requires print_function
99 tests/test-batching.py requires print_function
101 tests/test-bdiff.py not using absolute_import
100 tests/test-bdiff.py not using absolute_import
102 tests/test-bdiff.py requires print_function
101 tests/test-bdiff.py requires print_function
103 tests/test-context.py not using absolute_import
102 tests/test-context.py not using absolute_import
104 tests/test-context.py requires print_function
103 tests/test-context.py requires print_function
105 tests/test-demandimport.py not using absolute_import
104 tests/test-demandimport.py not using absolute_import
106 tests/test-demandimport.py requires print_function
105 tests/test-demandimport.py requires print_function
107 tests/test-dispatch.py not using absolute_import
106 tests/test-dispatch.py not using absolute_import
108 tests/test-dispatch.py requires print_function
107 tests/test-dispatch.py requires print_function
109 tests/test-doctest.py not using absolute_import
108 tests/test-doctest.py not using absolute_import
110 tests/test-duplicateoptions.py not using absolute_import
109 tests/test-duplicateoptions.py not using absolute_import
111 tests/test-duplicateoptions.py requires print_function
110 tests/test-duplicateoptions.py requires print_function
112 tests/test-filecache.py not using absolute_import
111 tests/test-filecache.py not using absolute_import
113 tests/test-filecache.py requires print_function
112 tests/test-filecache.py requires print_function
114 tests/test-filelog.py not using absolute_import
113 tests/test-filelog.py not using absolute_import
115 tests/test-filelog.py requires print_function
114 tests/test-filelog.py requires print_function
116 tests/test-hg-parseurl.py not using absolute_import
115 tests/test-hg-parseurl.py not using absolute_import
117 tests/test-hg-parseurl.py requires print_function
116 tests/test-hg-parseurl.py requires print_function
118 tests/test-hgweb-auth.py not using absolute_import
117 tests/test-hgweb-auth.py not using absolute_import
119 tests/test-hgweb-auth.py requires print_function
118 tests/test-hgweb-auth.py requires print_function
120 tests/test-hgwebdir-paths.py not using absolute_import
119 tests/test-hgwebdir-paths.py not using absolute_import
121 tests/test-hybridencode.py not using absolute_import
120 tests/test-hybridencode.py not using absolute_import
122 tests/test-hybridencode.py requires print_function
121 tests/test-hybridencode.py requires print_function
123 tests/test-lrucachedict.py not using absolute_import
122 tests/test-lrucachedict.py not using absolute_import
124 tests/test-lrucachedict.py requires print_function
123 tests/test-lrucachedict.py requires print_function
125 tests/test-manifest.py not using absolute_import
124 tests/test-manifest.py not using absolute_import
126 tests/test-minirst.py not using absolute_import
125 tests/test-minirst.py not using absolute_import
127 tests/test-minirst.py requires print_function
126 tests/test-minirst.py requires print_function
128 tests/test-parseindex2.py not using absolute_import
127 tests/test-parseindex2.py not using absolute_import
129 tests/test-parseindex2.py requires print_function
128 tests/test-parseindex2.py requires print_function
130 tests/test-pathencode.py not using absolute_import
129 tests/test-pathencode.py not using absolute_import
131 tests/test-pathencode.py requires print_function
130 tests/test-pathencode.py requires print_function
132 tests/test-propertycache.py not using absolute_import
131 tests/test-propertycache.py not using absolute_import
133 tests/test-propertycache.py requires print_function
132 tests/test-propertycache.py requires print_function
134 tests/test-revlog-ancestry.py not using absolute_import
133 tests/test-revlog-ancestry.py not using absolute_import
135 tests/test-revlog-ancestry.py requires print_function
134 tests/test-revlog-ancestry.py requires print_function
136 tests/test-run-tests.py not using absolute_import
135 tests/test-run-tests.py not using absolute_import
137 tests/test-simplemerge.py not using absolute_import
136 tests/test-simplemerge.py not using absolute_import
138 tests/test-status-inprocess.py not using absolute_import
137 tests/test-status-inprocess.py not using absolute_import
139 tests/test-status-inprocess.py requires print_function
138 tests/test-status-inprocess.py requires print_function
140 tests/test-symlink-os-yes-fs-no.py not using absolute_import
139 tests/test-symlink-os-yes-fs-no.py not using absolute_import
141 tests/test-trusted.py not using absolute_import
140 tests/test-trusted.py not using absolute_import
142 tests/test-trusted.py requires print_function
141 tests/test-trusted.py requires print_function
143 tests/test-ui-color.py not using absolute_import
142 tests/test-ui-color.py not using absolute_import
144 tests/test-ui-color.py requires print_function
143 tests/test-ui-color.py requires print_function
145 tests/test-ui-config.py not using absolute_import
144 tests/test-ui-config.py not using absolute_import
146 tests/test-ui-config.py requires print_function
145 tests/test-ui-config.py requires print_function
147 tests/test-ui-verbosity.py not using absolute_import
146 tests/test-ui-verbosity.py not using absolute_import
148 tests/test-ui-verbosity.py requires print_function
147 tests/test-ui-verbosity.py requires print_function
149 tests/test-url.py not using absolute_import
148 tests/test-url.py not using absolute_import
150 tests/test-url.py requires print_function
149 tests/test-url.py requires print_function
151 tests/test-walkrepo.py requires print_function
150 tests/test-walkrepo.py requires print_function
152 tests/test-wireproto.py requires print_function
151 tests/test-wireproto.py requires print_function
153 tests/tinyproxy.py requires print_function
152 tests/tinyproxy.py requires print_function
General Comments 0
You need to be logged in to leave comments. Login now