Mercurial > hg
comparison mercurial/mdiff.py @ 17939:d587925680d9
diff: move b85diff to mdiff module
b85diff generates a binary diff, so we move this code to mdiff module
along with unidiff for text diffs. All diffing mechanisms will be in the
same place.
In an upcoming patch we will remove the responsibility to print the
index header from b85diff and move it back to patch, since it's
a patch metadata header, not part of the diff generation.
author | Guillermo Pérez <bisho at fb.com> |
---|---|
date | Tue, 06 Nov 2012 14:04:05 -0800 |
parents | 16b75661828e |
children | c84ef0047a94 |
comparison
equal
deleted
inserted
replaced
17935:9c888b945b65 | 17939:d587925680d9 |
---|---|
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 from i18n import _ | 8 from i18n import _ |
9 import bdiff, mpatch, util | 9 import bdiff, mpatch, util |
10 import re, struct | 10 import re, struct, base85, zlib |
11 from node import hex, nullid | |
11 | 12 |
12 def splitnewlines(text): | 13 def splitnewlines(text): |
13 '''like str.splitlines, but only split on newlines.''' | 14 '''like str.splitlines, but only split on newlines.''' |
14 lines = [l + '\n' for l in text.split('\n')] | 15 lines = [l + '\n' for l in text.split('\n')] |
15 if lines: | 16 if lines: |
312 | 313 |
313 if hunk: | 314 if hunk: |
314 for x in yieldhunk(hunk): | 315 for x in yieldhunk(hunk): |
315 yield x | 316 yield x |
316 | 317 |
318 def b85diff(to, tn): | |
319 '''print base85-encoded binary diff''' | |
320 def gitindex(text): | |
321 if not text: | |
322 return hex(nullid) | |
323 l = len(text) | |
324 s = util.sha1('blob %d\0' % l) | |
325 s.update(text) | |
326 return s.hexdigest() | |
327 | |
328 def fmtline(line): | |
329 l = len(line) | |
330 if l <= 26: | |
331 l = chr(ord('A') + l - 1) | |
332 else: | |
333 l = chr(l - 26 + ord('a') - 1) | |
334 return '%c%s\n' % (l, base85.b85encode(line, True)) | |
335 | |
336 def chunk(text, csize=52): | |
337 l = len(text) | |
338 i = 0 | |
339 while i < l: | |
340 yield text[i:i + csize] | |
341 i += csize | |
342 | |
343 tohash = gitindex(to) | |
344 tnhash = gitindex(tn) | |
345 if tohash == tnhash: | |
346 return "" | |
347 | |
348 # TODO: deltas | |
349 ret = ['index %s..%s\nGIT binary patch\nliteral %s\n' % | |
350 (tohash, tnhash, len(tn))] | |
351 for l in chunk(zlib.compress(tn)): | |
352 ret.append(fmtline(l)) | |
353 ret.append('\n') | |
354 return ''.join(ret) | |
355 | |
317 def patchtext(bin): | 356 def patchtext(bin): |
318 pos = 0 | 357 pos = 0 |
319 t = [] | 358 t = [] |
320 while pos < len(bin): | 359 while pos < len(bin): |
321 p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12]) | 360 p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12]) |