comparison mercurial/patch.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 e51d4aedace9
children c84ef0047a94
comparison
equal deleted inserted replaced
17935:9c888b945b65 17939:d587925680d9
8 8
9 import cStringIO, email.Parser, os, errno, re 9 import cStringIO, email.Parser, os, errno, re
10 import tempfile, zlib, shutil 10 import tempfile, zlib, shutil
11 11
12 from i18n import _ 12 from i18n import _
13 from node import hex, nullid, short 13 from node import hex, short
14 import base85, mdiff, scmutil, util, diffhelpers, copies, encoding, error 14 import base85, mdiff, scmutil, util, diffhelpers, copies, encoding, error
15 import context 15 import context
16 16
17 gitre = re.compile('diff --git a/(.*) b/(.*)') 17 gitre = re.compile('diff --git a/(.*) b/(.*)')
18 18
1511 elif state not in ('hunk', 'git'): 1511 elif state not in ('hunk', 'git'):
1512 raise util.Abort(_('unsupported parser state: %s') % state) 1512 raise util.Abort(_('unsupported parser state: %s') % state)
1513 return changed 1513 return changed
1514 finally: 1514 finally:
1515 fp.close() 1515 fp.close()
1516
1517 def b85diff(to, tn):
1518 '''print base85-encoded binary diff'''
1519 def gitindex(text):
1520 if not text:
1521 return hex(nullid)
1522 l = len(text)
1523 s = util.sha1('blob %d\0' % l)
1524 s.update(text)
1525 return s.hexdigest()
1526
1527 def fmtline(line):
1528 l = len(line)
1529 if l <= 26:
1530 l = chr(ord('A') + l - 1)
1531 else:
1532 l = chr(l - 26 + ord('a') - 1)
1533 return '%c%s\n' % (l, base85.b85encode(line, True))
1534
1535 def chunk(text, csize=52):
1536 l = len(text)
1537 i = 0
1538 while i < l:
1539 yield text[i:i + csize]
1540 i += csize
1541
1542 tohash = gitindex(to)
1543 tnhash = gitindex(tn)
1544 if tohash == tnhash:
1545 return ""
1546
1547 # TODO: deltas
1548 ret = ['index %s..%s\nGIT binary patch\nliteral %s\n' %
1549 (tohash, tnhash, len(tn))]
1550 for l in chunk(zlib.compress(tn)):
1551 ret.append(fmtline(l))
1552 ret.append('\n')
1553 return ''.join(ret)
1554 1516
1555 class GitDiffRequired(Exception): 1517 class GitDiffRequired(Exception):
1556 pass 1518 pass
1557 1519
1558 def diffopts(ui, opts=None, untrusted=False, section='diff'): 1520 def diffopts(ui, opts=None, untrusted=False, section='diff'):
1787 if opts.git: 1749 if opts.git:
1788 header.insert(0, mdiff.diffline(revs, join(a), join(b), opts)) 1750 header.insert(0, mdiff.diffline(revs, join(a), join(b), opts))
1789 1751
1790 if dodiff: 1752 if dodiff:
1791 if dodiff == 'binary': 1753 if dodiff == 'binary':
1792 text = b85diff(to, tn) 1754 text = mdiff.b85diff(to, tn)
1793 else: 1755 else:
1794 text = mdiff.unidiff(to, date1, 1756 text = mdiff.unidiff(to, date1,
1795 # ctx2 date may be dynamic 1757 # ctx2 date may be dynamic
1796 tn, util.datestr(ctx2.date()), 1758 tn, util.datestr(ctx2.date()),
1797 join(a), join(b), revs, opts=opts) 1759 join(a), join(b), revs, opts=opts)