##// END OF EJS Templates
mdiff: use absolute_import
Gregory Szorc -
r27484:0d7635dc default
parent child Browse files
Show More
@@ -1,375 +1,386
1 1 # mdiff.py - diff and patch routines for mercurial
2 2 #
3 3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 from i18n import _
9 import bdiff, mpatch, util, base85, error
10 import re, struct, zlib
8 from __future__ import absolute_import
9
10 import re
11 import struct
12 import zlib
13
14 from .i18n import _
15 from . import (
16 base85,
17 bdiff,
18 error,
19 mpatch,
20 util,
21 )
11 22
12 23 def splitnewlines(text):
13 24 '''like str.splitlines, but only split on newlines.'''
14 25 lines = [l + '\n' for l in text.split('\n')]
15 26 if lines:
16 27 if lines[-1] == '\n':
17 28 lines.pop()
18 29 else:
19 30 lines[-1] = lines[-1][:-1]
20 31 return lines
21 32
22 33 class diffopts(object):
23 34 '''context is the number of context lines
24 35 text treats all files as text
25 36 showfunc enables diff -p output
26 37 git enables the git extended patch format
27 38 nodates removes dates from diff headers
28 39 nobinary ignores binary files
29 40 noprefix disables the 'a/' and 'b/' prefixes (ignored in plain mode)
30 41 ignorews ignores all whitespace changes in the diff
31 42 ignorewsamount ignores changes in the amount of whitespace
32 43 ignoreblanklines ignores changes whose lines are all blank
33 44 upgrade generates git diffs to avoid data loss
34 45 '''
35 46
36 47 defaults = {
37 48 'context': 3,
38 49 'text': False,
39 50 'showfunc': False,
40 51 'git': False,
41 52 'nodates': False,
42 53 'nobinary': False,
43 54 'noprefix': False,
44 55 'ignorews': False,
45 56 'ignorewsamount': False,
46 57 'ignoreblanklines': False,
47 58 'upgrade': False,
48 59 }
49 60
50 61 __slots__ = defaults.keys()
51 62
52 63 def __init__(self, **opts):
53 64 for k in self.__slots__:
54 65 v = opts.get(k)
55 66 if v is None:
56 67 v = self.defaults[k]
57 68 setattr(self, k, v)
58 69
59 70 try:
60 71 self.context = int(self.context)
61 72 except ValueError:
62 73 raise error.Abort(_('diff context lines count must be '
63 74 'an integer, not %r') % self.context)
64 75
65 76 def copy(self, **kwargs):
66 77 opts = dict((k, getattr(self, k)) for k in self.defaults)
67 78 opts.update(kwargs)
68 79 return diffopts(**opts)
69 80
70 81 defaultopts = diffopts()
71 82
72 83 def wsclean(opts, text, blank=True):
73 84 if opts.ignorews:
74 85 text = bdiff.fixws(text, 1)
75 86 elif opts.ignorewsamount:
76 87 text = bdiff.fixws(text, 0)
77 88 if blank and opts.ignoreblanklines:
78 89 text = re.sub('\n+', '\n', text).strip('\n')
79 90 return text
80 91
81 92 def splitblock(base1, lines1, base2, lines2, opts):
82 93 # The input lines matches except for interwoven blank lines. We
83 94 # transform it into a sequence of matching blocks and blank blocks.
84 95 lines1 = [(wsclean(opts, l) and 1 or 0) for l in lines1]
85 96 lines2 = [(wsclean(opts, l) and 1 or 0) for l in lines2]
86 97 s1, e1 = 0, len(lines1)
87 98 s2, e2 = 0, len(lines2)
88 99 while s1 < e1 or s2 < e2:
89 100 i1, i2, btype = s1, s2, '='
90 101 if (i1 >= e1 or lines1[i1] == 0
91 102 or i2 >= e2 or lines2[i2] == 0):
92 103 # Consume the block of blank lines
93 104 btype = '~'
94 105 while i1 < e1 and lines1[i1] == 0:
95 106 i1 += 1
96 107 while i2 < e2 and lines2[i2] == 0:
97 108 i2 += 1
98 109 else:
99 110 # Consume the matching lines
100 111 while i1 < e1 and lines1[i1] == 1 and lines2[i2] == 1:
101 112 i1 += 1
102 113 i2 += 1
103 114 yield [base1 + s1, base1 + i1, base2 + s2, base2 + i2], btype
104 115 s1 = i1
105 116 s2 = i2
106 117
107 118 def allblocks(text1, text2, opts=None, lines1=None, lines2=None, refine=False):
108 119 """Return (block, type) tuples, where block is an mdiff.blocks
109 120 line entry. type is '=' for blocks matching exactly one another
110 121 (bdiff blocks), '!' for non-matching blocks and '~' for blocks
111 122 matching only after having filtered blank lines. If refine is True,
112 123 then '~' blocks are refined and are only made of blank lines.
113 124 line1 and line2 are text1 and text2 split with splitnewlines() if
114 125 they are already available.
115 126 """
116 127 if opts is None:
117 128 opts = defaultopts
118 129 if opts.ignorews or opts.ignorewsamount:
119 130 text1 = wsclean(opts, text1, False)
120 131 text2 = wsclean(opts, text2, False)
121 132 diff = bdiff.blocks(text1, text2)
122 133 for i, s1 in enumerate(diff):
123 134 # The first match is special.
124 135 # we've either found a match starting at line 0 or a match later
125 136 # in the file. If it starts later, old and new below will both be
126 137 # empty and we'll continue to the next match.
127 138 if i > 0:
128 139 s = diff[i - 1]
129 140 else:
130 141 s = [0, 0, 0, 0]
131 142 s = [s[1], s1[0], s[3], s1[2]]
132 143
133 144 # bdiff sometimes gives huge matches past eof, this check eats them,
134 145 # and deals with the special first match case described above
135 146 if s[0] != s[1] or s[2] != s[3]:
136 147 type = '!'
137 148 if opts.ignoreblanklines:
138 149 if lines1 is None:
139 150 lines1 = splitnewlines(text1)
140 151 if lines2 is None:
141 152 lines2 = splitnewlines(text2)
142 153 old = wsclean(opts, "".join(lines1[s[0]:s[1]]))
143 154 new = wsclean(opts, "".join(lines2[s[2]:s[3]]))
144 155 if old == new:
145 156 type = '~'
146 157 yield s, type
147 158 yield s1, '='
148 159
149 160 def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts):
150 161 def datetag(date, fn=None):
151 162 if not opts.git and not opts.nodates:
152 163 return '\t%s\n' % date
153 164 if fn and ' ' in fn:
154 165 return '\t\n'
155 166 return '\n'
156 167
157 168 if not a and not b:
158 169 return ""
159 170
160 171 if opts.noprefix:
161 172 aprefix = bprefix = ''
162 173 else:
163 174 aprefix = 'a/'
164 175 bprefix = 'b/'
165 176
166 177 epoch = util.datestr((0, 0))
167 178
168 179 fn1 = util.pconvert(fn1)
169 180 fn2 = util.pconvert(fn2)
170 181
171 182 if not opts.text and (util.binary(a) or util.binary(b)):
172 183 if a and b and len(a) == len(b) and a == b:
173 184 return ""
174 185 l = ['Binary file %s has changed\n' % fn1]
175 186 elif not a:
176 187 b = splitnewlines(b)
177 188 if a is None:
178 189 l1 = '--- /dev/null%s' % datetag(epoch)
179 190 else:
180 191 l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1))
181 192 l2 = "+++ %s%s" % (bprefix + fn2, datetag(bd, fn2))
182 193 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
183 194 l = [l1, l2, l3] + ["+" + e for e in b]
184 195 elif not b:
185 196 a = splitnewlines(a)
186 197 l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1))
187 198 if b is None:
188 199 l2 = '+++ /dev/null%s' % datetag(epoch)
189 200 else:
190 201 l2 = "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2))
191 202 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
192 203 l = [l1, l2, l3] + ["-" + e for e in a]
193 204 else:
194 205 al = splitnewlines(a)
195 206 bl = splitnewlines(b)
196 207 l = list(_unidiff(a, b, al, bl, opts=opts))
197 208 if not l:
198 209 return ""
199 210
200 211 l.insert(0, "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)))
201 212 l.insert(1, "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2)))
202 213
203 214 for ln in xrange(len(l)):
204 215 if l[ln][-1] != '\n':
205 216 l[ln] += "\n\ No newline at end of file\n"
206 217
207 218 return "".join(l)
208 219
209 220 # creates a headerless unified diff
210 221 # t1 and t2 are the text to be diffed
211 222 # l1 and l2 are the text broken up into lines
212 223 def _unidiff(t1, t2, l1, l2, opts=defaultopts):
213 224 def contextend(l, len):
214 225 ret = l + opts.context
215 226 if ret > len:
216 227 ret = len
217 228 return ret
218 229
219 230 def contextstart(l):
220 231 ret = l - opts.context
221 232 if ret < 0:
222 233 return 0
223 234 return ret
224 235
225 236 lastfunc = [0, '']
226 237 def yieldhunk(hunk):
227 238 (astart, a2, bstart, b2, delta) = hunk
228 239 aend = contextend(a2, len(l1))
229 240 alen = aend - astart
230 241 blen = b2 - bstart + aend - a2
231 242
232 243 func = ""
233 244 if opts.showfunc:
234 245 lastpos, func = lastfunc
235 246 # walk backwards from the start of the context up to the start of
236 247 # the previous hunk context until we find a line starting with an
237 248 # alphanumeric char.
238 249 for i in xrange(astart - 1, lastpos - 1, -1):
239 250 if l1[i][0].isalnum():
240 251 func = ' ' + l1[i].rstrip()[:40]
241 252 lastfunc[1] = func
242 253 break
243 254 # by recording this hunk's starting point as the next place to
244 255 # start looking for function lines, we avoid reading any line in
245 256 # the file more than once.
246 257 lastfunc[0] = astart
247 258
248 259 # zero-length hunk ranges report their start line as one less
249 260 if alen:
250 261 astart += 1
251 262 if blen:
252 263 bstart += 1
253 264
254 265 yield "@@ -%d,%d +%d,%d @@%s\n" % (astart, alen,
255 266 bstart, blen, func)
256 267 for x in delta:
257 268 yield x
258 269 for x in xrange(a2, aend):
259 270 yield ' ' + l1[x]
260 271
261 272 # bdiff.blocks gives us the matching sequences in the files. The loop
262 273 # below finds the spaces between those matching sequences and translates
263 274 # them into diff output.
264 275 #
265 276 hunk = None
266 277 ignoredlines = 0
267 278 for s, stype in allblocks(t1, t2, opts, l1, l2):
268 279 a1, a2, b1, b2 = s
269 280 if stype != '!':
270 281 if stype == '~':
271 282 # The diff context lines are based on t1 content. When
272 283 # blank lines are ignored, the new lines offsets must
273 284 # be adjusted as if equivalent blocks ('~') had the
274 285 # same sizes on both sides.
275 286 ignoredlines += (b2 - b1) - (a2 - a1)
276 287 continue
277 288 delta = []
278 289 old = l1[a1:a2]
279 290 new = l2[b1:b2]
280 291
281 292 b1 -= ignoredlines
282 293 b2 -= ignoredlines
283 294 astart = contextstart(a1)
284 295 bstart = contextstart(b1)
285 296 prev = None
286 297 if hunk:
287 298 # join with the previous hunk if it falls inside the context
288 299 if astart < hunk[1] + opts.context + 1:
289 300 prev = hunk
290 301 astart = hunk[1]
291 302 bstart = hunk[3]
292 303 else:
293 304 for x in yieldhunk(hunk):
294 305 yield x
295 306 if prev:
296 307 # we've joined the previous hunk, record the new ending points.
297 308 hunk[1] = a2
298 309 hunk[3] = b2
299 310 delta = hunk[4]
300 311 else:
301 312 # create a new hunk
302 313 hunk = [astart, a2, bstart, b2, delta]
303 314
304 315 delta[len(delta):] = [' ' + x for x in l1[astart:a1]]
305 316 delta[len(delta):] = ['-' + x for x in old]
306 317 delta[len(delta):] = ['+' + x for x in new]
307 318
308 319 if hunk:
309 320 for x in yieldhunk(hunk):
310 321 yield x
311 322
312 323 def b85diff(to, tn):
313 324 '''print base85-encoded binary diff'''
314 325 def fmtline(line):
315 326 l = len(line)
316 327 if l <= 26:
317 328 l = chr(ord('A') + l - 1)
318 329 else:
319 330 l = chr(l - 26 + ord('a') - 1)
320 331 return '%c%s\n' % (l, base85.b85encode(line, True))
321 332
322 333 def chunk(text, csize=52):
323 334 l = len(text)
324 335 i = 0
325 336 while i < l:
326 337 yield text[i:i + csize]
327 338 i += csize
328 339
329 340 if to is None:
330 341 to = ''
331 342 if tn is None:
332 343 tn = ''
333 344
334 345 if to == tn:
335 346 return ''
336 347
337 348 # TODO: deltas
338 349 ret = []
339 350 ret.append('GIT binary patch\n')
340 351 ret.append('literal %s\n' % len(tn))
341 352 for l in chunk(zlib.compress(tn)):
342 353 ret.append(fmtline(l))
343 354 ret.append('\n')
344 355
345 356 return ''.join(ret)
346 357
347 358 def patchtext(bin):
348 359 pos = 0
349 360 t = []
350 361 while pos < len(bin):
351 362 p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
352 363 pos += 12
353 364 t.append(bin[pos:pos + l])
354 365 pos += l
355 366 return "".join(t)
356 367
357 368 def patch(a, bin):
358 369 if len(a) == 0:
359 370 # skip over trivial delta header
360 371 return util.buffer(bin, 12)
361 372 return mpatch.patches(a, [bin])
362 373
363 374 # similar to difflib.SequenceMatcher.get_matching_blocks
364 375 def get_matching_blocks(a, b):
365 376 return [(d[0], d[2], d[1] - d[0]) for d in bdiff.blocks(a, b)]
366 377
367 378 def trivialdiffheader(length):
368 379 return struct.pack(">lll", 0, 0, length)
369 380
370 381 def replacediffheader(oldlen, newlen):
371 382 return struct.pack(">lll", 0, oldlen, newlen)
372 383
373 384 patches = mpatch.patches
374 385 patchedsize = mpatch.patchedsize
375 386 textdiff = bdiff.bdiff
@@ -1,202 +1,201
1 1 #require test-repo
2 2
3 3 $ cd "$TESTDIR"/..
4 4
5 5 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs python contrib/check-py3-compat.py
6 6 contrib/casesmash.py not using absolute_import
7 7 contrib/check-code.py not using absolute_import
8 8 contrib/check-code.py requires print_function
9 9 contrib/check-config.py not using absolute_import
10 10 contrib/check-config.py requires print_function
11 11 contrib/debugcmdserver.py not using absolute_import
12 12 contrib/debugcmdserver.py requires print_function
13 13 contrib/debugshell.py not using absolute_import
14 14 contrib/fixpax.py not using absolute_import
15 15 contrib/fixpax.py requires print_function
16 16 contrib/hgclient.py not using absolute_import
17 17 contrib/hgclient.py requires print_function
18 18 contrib/hgfixes/fix_bytes.py not using absolute_import
19 19 contrib/hgfixes/fix_bytesmod.py not using absolute_import
20 20 contrib/hgfixes/fix_leftover_imports.py not using absolute_import
21 21 contrib/import-checker.py not using absolute_import
22 22 contrib/import-checker.py requires print_function
23 23 contrib/memory.py not using absolute_import
24 24 contrib/perf.py not using absolute_import
25 25 contrib/python-hook-examples.py not using absolute_import
26 26 contrib/revsetbenchmarks.py not using absolute_import
27 27 contrib/revsetbenchmarks.py requires print_function
28 28 contrib/showstack.py not using absolute_import
29 29 contrib/synthrepo.py not using absolute_import
30 30 contrib/win32/hgwebdir_wsgi.py not using absolute_import
31 31 doc/check-seclevel.py not using absolute_import
32 32 doc/gendoc.py not using absolute_import
33 33 doc/hgmanpage.py not using absolute_import
34 34 hgext/__init__.py not using absolute_import
35 35 hgext/acl.py not using absolute_import
36 36 hgext/blackbox.py not using absolute_import
37 37 hgext/bugzilla.py not using absolute_import
38 38 hgext/censor.py not using absolute_import
39 39 hgext/children.py not using absolute_import
40 40 hgext/churn.py not using absolute_import
41 41 hgext/clonebundles.py not using absolute_import
42 42 hgext/color.py not using absolute_import
43 43 hgext/convert/__init__.py not using absolute_import
44 44 hgext/convert/bzr.py not using absolute_import
45 45 hgext/convert/common.py not using absolute_import
46 46 hgext/convert/convcmd.py not using absolute_import
47 47 hgext/convert/cvs.py not using absolute_import
48 48 hgext/convert/cvsps.py not using absolute_import
49 49 hgext/convert/darcs.py not using absolute_import
50 50 hgext/convert/filemap.py not using absolute_import
51 51 hgext/convert/git.py not using absolute_import
52 52 hgext/convert/gnuarch.py not using absolute_import
53 53 hgext/convert/hg.py not using absolute_import
54 54 hgext/convert/monotone.py not using absolute_import
55 55 hgext/convert/p4.py not using absolute_import
56 56 hgext/convert/subversion.py not using absolute_import
57 57 hgext/convert/transport.py not using absolute_import
58 58 hgext/eol.py not using absolute_import
59 59 hgext/extdiff.py not using absolute_import
60 60 hgext/factotum.py not using absolute_import
61 61 hgext/fetch.py not using absolute_import
62 62 hgext/gpg.py not using absolute_import
63 63 hgext/graphlog.py not using absolute_import
64 64 hgext/hgcia.py not using absolute_import
65 65 hgext/hgk.py not using absolute_import
66 66 hgext/highlight/__init__.py not using absolute_import
67 67 hgext/highlight/highlight.py not using absolute_import
68 68 hgext/histedit.py not using absolute_import
69 69 hgext/keyword.py not using absolute_import
70 70 hgext/largefiles/__init__.py not using absolute_import
71 71 hgext/largefiles/basestore.py not using absolute_import
72 72 hgext/largefiles/lfcommands.py not using absolute_import
73 73 hgext/largefiles/lfutil.py not using absolute_import
74 74 hgext/largefiles/localstore.py not using absolute_import
75 75 hgext/largefiles/overrides.py not using absolute_import
76 76 hgext/largefiles/proto.py not using absolute_import
77 77 hgext/largefiles/remotestore.py not using absolute_import
78 78 hgext/largefiles/reposetup.py not using absolute_import
79 79 hgext/largefiles/uisetup.py not using absolute_import
80 80 hgext/largefiles/wirestore.py not using absolute_import
81 81 hgext/mq.py not using absolute_import
82 82 hgext/notify.py not using absolute_import
83 83 hgext/pager.py not using absolute_import
84 84 hgext/patchbomb.py not using absolute_import
85 85 hgext/purge.py not using absolute_import
86 86 hgext/rebase.py not using absolute_import
87 87 hgext/record.py not using absolute_import
88 88 hgext/relink.py not using absolute_import
89 89 hgext/schemes.py not using absolute_import
90 90 hgext/share.py not using absolute_import
91 91 hgext/shelve.py not using absolute_import
92 92 hgext/strip.py not using absolute_import
93 93 hgext/transplant.py not using absolute_import
94 94 hgext/win32mbcs.py not using absolute_import
95 95 hgext/win32text.py not using absolute_import
96 96 hgext/zeroconf/Zeroconf.py not using absolute_import
97 97 hgext/zeroconf/Zeroconf.py requires print_function
98 98 hgext/zeroconf/__init__.py not using absolute_import
99 99 i18n/check-translation.py not using absolute_import
100 100 i18n/polib.py not using absolute_import
101 101 mercurial/byterange.py not using absolute_import
102 102 mercurial/cmdutil.py not using absolute_import
103 103 mercurial/commands.py not using absolute_import
104 104 mercurial/context.py not using absolute_import
105 105 mercurial/dirstate.py not using absolute_import
106 106 mercurial/dispatch.py requires print_function
107 107 mercurial/exchange.py not using absolute_import
108 108 mercurial/httpclient/__init__.py not using absolute_import
109 109 mercurial/httpclient/_readers.py not using absolute_import
110 110 mercurial/httpclient/socketutil.py not using absolute_import
111 111 mercurial/httpconnection.py not using absolute_import
112 112 mercurial/keepalive.py not using absolute_import
113 113 mercurial/keepalive.py requires print_function
114 114 mercurial/localrepo.py not using absolute_import
115 115 mercurial/lsprof.py requires print_function
116 116 mercurial/lsprofcalltree.py not using absolute_import
117 117 mercurial/lsprofcalltree.py requires print_function
118 118 mercurial/mail.py requires print_function
119 119 mercurial/manifest.py not using absolute_import
120 mercurial/mdiff.py not using absolute_import
121 120 mercurial/patch.py not using absolute_import
122 121 mercurial/pvec.py not using absolute_import
123 122 mercurial/py3kcompat.py not using absolute_import
124 123 setup.py not using absolute_import
125 124 tests/filterpyflakes.py requires print_function
126 125 tests/generate-working-copy-states.py requires print_function
127 126 tests/get-with-headers.py requires print_function
128 127 tests/heredoctest.py requires print_function
129 128 tests/hypothesishelpers.py not using absolute_import
130 129 tests/hypothesishelpers.py requires print_function
131 130 tests/killdaemons.py not using absolute_import
132 131 tests/md5sum.py not using absolute_import
133 132 tests/mockblackbox.py not using absolute_import
134 133 tests/printenv.py not using absolute_import
135 134 tests/readlink.py not using absolute_import
136 135 tests/readlink.py requires print_function
137 136 tests/revlog-formatv0.py not using absolute_import
138 137 tests/run-tests.py not using absolute_import
139 138 tests/seq.py not using absolute_import
140 139 tests/seq.py requires print_function
141 140 tests/silenttestrunner.py not using absolute_import
142 141 tests/silenttestrunner.py requires print_function
143 142 tests/sitecustomize.py not using absolute_import
144 143 tests/svn-safe-append.py not using absolute_import
145 144 tests/svnxml.py not using absolute_import
146 145 tests/test-ancestor.py requires print_function
147 146 tests/test-atomictempfile.py not using absolute_import
148 147 tests/test-batching.py not using absolute_import
149 148 tests/test-batching.py requires print_function
150 149 tests/test-bdiff.py not using absolute_import
151 150 tests/test-bdiff.py requires print_function
152 151 tests/test-context.py not using absolute_import
153 152 tests/test-context.py requires print_function
154 153 tests/test-demandimport.py not using absolute_import
155 154 tests/test-demandimport.py requires print_function
156 155 tests/test-dispatch.py not using absolute_import
157 156 tests/test-dispatch.py requires print_function
158 157 tests/test-doctest.py not using absolute_import
159 158 tests/test-duplicateoptions.py not using absolute_import
160 159 tests/test-duplicateoptions.py requires print_function
161 160 tests/test-filecache.py not using absolute_import
162 161 tests/test-filecache.py requires print_function
163 162 tests/test-filelog.py not using absolute_import
164 163 tests/test-filelog.py requires print_function
165 164 tests/test-hg-parseurl.py not using absolute_import
166 165 tests/test-hg-parseurl.py requires print_function
167 166 tests/test-hgweb-auth.py not using absolute_import
168 167 tests/test-hgweb-auth.py requires print_function
169 168 tests/test-hgwebdir-paths.py not using absolute_import
170 169 tests/test-hybridencode.py not using absolute_import
171 170 tests/test-hybridencode.py requires print_function
172 171 tests/test-lrucachedict.py not using absolute_import
173 172 tests/test-lrucachedict.py requires print_function
174 173 tests/test-manifest.py not using absolute_import
175 174 tests/test-minirst.py not using absolute_import
176 175 tests/test-minirst.py requires print_function
177 176 tests/test-parseindex2.py not using absolute_import
178 177 tests/test-parseindex2.py requires print_function
179 178 tests/test-pathencode.py not using absolute_import
180 179 tests/test-pathencode.py requires print_function
181 180 tests/test-propertycache.py not using absolute_import
182 181 tests/test-propertycache.py requires print_function
183 182 tests/test-revlog-ancestry.py not using absolute_import
184 183 tests/test-revlog-ancestry.py requires print_function
185 184 tests/test-run-tests.py not using absolute_import
186 185 tests/test-simplemerge.py not using absolute_import
187 186 tests/test-status-inprocess.py not using absolute_import
188 187 tests/test-status-inprocess.py requires print_function
189 188 tests/test-symlink-os-yes-fs-no.py not using absolute_import
190 189 tests/test-trusted.py not using absolute_import
191 190 tests/test-trusted.py requires print_function
192 191 tests/test-ui-color.py not using absolute_import
193 192 tests/test-ui-color.py requires print_function
194 193 tests/test-ui-config.py not using absolute_import
195 194 tests/test-ui-config.py requires print_function
196 195 tests/test-ui-verbosity.py not using absolute_import
197 196 tests/test-ui-verbosity.py requires print_function
198 197 tests/test-url.py not using absolute_import
199 198 tests/test-url.py requires print_function
200 199 tests/test-walkrepo.py requires print_function
201 200 tests/test-wireproto.py requires print_function
202 201 tests/tinyproxy.py requires print_function
General Comments 0
You need to be logged in to leave comments. Login now