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])