Mercurial > public > mercurial-scm > hg
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) |