annotate mercurial/mdiff.py @ 21661:2f52a16f2bee

pushkey: add an ``encode`` function This function is just a shorthand for ``encoding.fromlocal``. It will help hiding the encoding business from other code exchanging pushkey data over the wire.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 29 May 2014 15:22:58 -0700
parents 1e5b38a919dd
children 3fbef7ac26f0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
239
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
1 # mdiff.py - diff and patch routines for mercurial
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
2 #
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2580
diff changeset
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
239
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7436
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10185
diff changeset
6 # GNU General Public License version 2 or any later version.
239
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
7
6467
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
8 from i18n import _
20034
1e5b38a919dd cleanup: move stdlib imports to their own import statement
Augie Fackler <raf@durin42.com>
parents: 17946
diff changeset
9 import bdiff, mpatch, util, base85
1e5b38a919dd cleanup: move stdlib imports to their own import statement
Augie Fackler <raf@durin42.com>
parents: 17946
diff changeset
10 import re, struct, zlib
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
11
2251
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
12 def splitnewlines(text):
2248
b914f0557832 fix diffs containing embedded "\r".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2078
diff changeset
13 '''like str.splitlines, but only split on newlines.'''
2251
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
14 lines = [l + '\n' for l in text.split('\n')]
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
15 if lines:
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
16 if lines[-1] == '\n':
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
17 lines.pop()
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
18 else:
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
19 lines[-1] = lines[-1][:-1]
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
20 return lines
2248
b914f0557832 fix diffs containing embedded "\r".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2078
diff changeset
21
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
22 class diffopts(object):
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
23 '''context is the number of context lines
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
24 text treats all files as text
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
25 showfunc enables diff -p output
2907
8b02af865990 Add diff --git option
Brendan Cully <brendan@kublai.com>
parents: 2874
diff changeset
26 git enables the git extended patch format
3199
096f1c73cdc3 Add -D/--nodates options to hg diff/export that removes dates from diff headers
Stephen Darnell <stephen@darnell.plus.com>
parents: 3026
diff changeset
27 nodates removes dates from diff headers
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
28 ignorews ignores all whitespace changes in the diff
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
29 ignorewsamount ignores changes in the amount of whitespace
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10185
diff changeset
30 ignoreblanklines ignores changes whose lines are all blank
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10185
diff changeset
31 upgrade generates git diffs to avoid data loss
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10185
diff changeset
32 '''
396
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
33
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
34 defaults = {
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
35 'context': 3,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
36 'text': False,
5863
3d1f9dcecdea diff: don't show function name by default
Matt Mackall <mpm@selenic.com>
parents: 5482
diff changeset
37 'showfunc': False,
2907
8b02af865990 Add diff --git option
Brendan Cully <brendan@kublai.com>
parents: 2874
diff changeset
38 'git': False,
3199
096f1c73cdc3 Add -D/--nodates options to hg diff/export that removes dates from diff headers
Stephen Darnell <stephen@darnell.plus.com>
parents: 3026
diff changeset
39 'nodates': False,
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
40 'ignorews': False,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
41 'ignorewsamount': False,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
42 'ignoreblanklines': False,
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10185
diff changeset
43 'upgrade': False,
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
44 }
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
45
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
46 __slots__ = defaults.keys()
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
47
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
48 def __init__(self, **opts):
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
49 for k in self.__slots__:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
50 v = opts.get(k)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
51 if v is None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
52 v = self.defaults[k]
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
53 setattr(self, k, v)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
54
6467
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
55 try:
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
56 self.context = int(self.context)
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
57 except ValueError:
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
58 raise util.Abort(_('diff context lines count must be '
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
59 'an integer, not %r') % self.context)
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
60
10185
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
61 def copy(self, **kwargs):
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
62 opts = dict((k, getattr(self, k)) for k in self.defaults)
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
63 opts.update(kwargs)
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
64 return diffopts(**opts)
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
65
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
66 defaultopts = diffopts()
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
67
9827
4fe9ca519637 mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents: 8632
diff changeset
68 def wsclean(opts, text, blank=True):
4878
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
69 if opts.ignorews:
15530
eeac5e179243 mdiff: replace wscleanup() regexps with C loops
Patrick Mezard <pmezard@gmail.com>
parents: 15529
diff changeset
70 text = bdiff.fixws(text, 1)
4878
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
71 elif opts.ignorewsamount:
15530
eeac5e179243 mdiff: replace wscleanup() regexps with C loops
Patrick Mezard <pmezard@gmail.com>
parents: 15529
diff changeset
72 text = bdiff.fixws(text, 0)
9827
4fe9ca519637 mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents: 8632
diff changeset
73 if blank and opts.ignoreblanklines:
15509
3774e1453ef4 diff: --ignore-blank-lines was too enthusiastic
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
74 text = re.sub('\n+', '\n', text).strip('\n')
4878
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
75 return text
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
76
15528
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
77 def splitblock(base1, lines1, base2, lines2, opts):
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
78 # The input lines matches except for interwoven blank lines. We
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
79 # transform it into a sequence of matching blocks and blank blocks.
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
80 lines1 = [(wsclean(opts, l) and 1 or 0) for l in lines1]
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
81 lines2 = [(wsclean(opts, l) and 1 or 0) for l in lines2]
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
82 s1, e1 = 0, len(lines1)
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
83 s2, e2 = 0, len(lines2)
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
84 while s1 < e1 or s2 < e2:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
85 i1, i2, btype = s1, s2, '='
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
86 if (i1 >= e1 or lines1[i1] == 0
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
87 or i2 >= e2 or lines2[i2] == 0):
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
88 # Consume the block of blank lines
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
89 btype = '~'
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
90 while i1 < e1 and lines1[i1] == 0:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
91 i1 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
92 while i2 < e2 and lines2[i2] == 0:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
93 i2 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
94 else:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
95 # Consume the matching lines
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
96 while i1 < e1 and lines1[i1] == 1 and lines2[i2] == 1:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
97 i1 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
98 i2 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
99 yield [base1 + s1, base1 + i1, base2 + s2, base2 + i2], btype
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
100 s1 = i1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
101 s2 = i2
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
102
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
103 def allblocks(text1, text2, opts=None, lines1=None, lines2=None, refine=False):
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
104 """Return (block, type) tuples, where block is an mdiff.blocks
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
105 line entry. type is '=' for blocks matching exactly one another
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
106 (bdiff blocks), '!' for non-matching blocks and '~' for blocks
15528
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
107 matching only after having filtered blank lines. If refine is True,
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
108 then '~' blocks are refined and are only made of blank lines.
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
109 line1 and line2 are text1 and text2 split with splitnewlines() if
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
110 they are already available.
15525
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
111 """
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
112 if opts is None:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
113 opts = defaultopts
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
114 if opts.ignorews or opts.ignorewsamount:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
115 text1 = wsclean(opts, text1, False)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
116 text2 = wsclean(opts, text2, False)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
117 diff = bdiff.blocks(text1, text2)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
118 for i, s1 in enumerate(diff):
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
119 # The first match is special.
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
120 # we've either found a match starting at line 0 or a match later
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
121 # in the file. If it starts later, old and new below will both be
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
122 # empty and we'll continue to the next match.
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
123 if i > 0:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
124 s = diff[i - 1]
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
125 else:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
126 s = [0, 0, 0, 0]
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
127 s = [s[1], s1[0], s[3], s1[2]]
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
128
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
129 # bdiff sometimes gives huge matches past eof, this check eats them,
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
130 # and deals with the special first match case described above
15529
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
131 if s[0] != s[1] or s[2] != s[3]:
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
132 type = '!'
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
133 if opts.ignoreblanklines:
15529
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
134 if lines1 is None:
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
135 lines1 = splitnewlines(text1)
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
136 if lines2 is None:
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
137 lines2 = splitnewlines(text2)
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
138 old = wsclean(opts, "".join(lines1[s[0]:s[1]]))
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
139 new = wsclean(opts, "".join(lines2[s[2]:s[3]]))
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
140 if old == new:
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
141 type = '~'
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
142 yield s, type
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
143 yield s1, '='
15525
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
144
17940
c84ef0047a94 diff: unify calls to diffline
Guillermo Pérez <bisho@fb.com>
parents: 17939
diff changeset
145 def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts):
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
146 def datetag(date, fn=None):
4679
826659bd8053 git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4361
diff changeset
147 if not opts.git and not opts.nodates:
826659bd8053 git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4361
diff changeset
148 return '\t%s\n' % date
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
149 if fn and ' ' in fn:
4679
826659bd8053 git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4361
diff changeset
150 return '\t\n'
826659bd8053 git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4361
diff changeset
151 return '\n'
3026
d838bfac668d Remove dates from git export file lines - they confuse git-apply
Brendan Cully <brendan@kublai.com>
parents: 2907
diff changeset
152
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
153 if not a and not b:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
154 return ""
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
155 epoch = util.datestr((0, 0))
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
156
15437
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
157 fn1 = util.pconvert(fn1)
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
158 fn2 = util.pconvert(fn2)
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
159
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
160 if not opts.text and (util.binary(a) or util.binary(b)):
6871
13fe85fe396b mdiff: compare content of binary files directly
Martin Geisler <mg@daimi.au.dk>
parents: 6470
diff changeset
161 if a and b and len(a) == len(b) and a == b:
4103
544838cc1158 Don't lie that "binary file has changed"
tailgunner@smtp.ru
parents: 3199
diff changeset
162 return ""
5482
e5eedd74e70f Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents: 5367
diff changeset
163 l = ['Binary file %s has changed\n' % fn1]
1723
fde8fb2cbede Fix diff against an empty file (issue124) and add a test for this.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1637
diff changeset
164 elif not a:
2251
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
165 b = splitnewlines(b)
1723
fde8fb2cbede Fix diff against an empty file (issue124) and add a test for this.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1637
diff changeset
166 if a is None:
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
167 l1 = '--- /dev/null%s' % datetag(epoch)
1723
fde8fb2cbede Fix diff against an empty file (issue124) and add a test for this.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1637
diff changeset
168 else:
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
169 l1 = "--- %s%s" % ("a/" + fn1, datetag(ad, fn1))
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
170 l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd, fn2))
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
171 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
172 l = [l1, l2, l3] + ["+" + e for e in b]
1723
fde8fb2cbede Fix diff against an empty file (issue124) and add a test for this.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1637
diff changeset
173 elif not b:
2251
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
174 a = splitnewlines(a)
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
175 l1 = "--- %s%s" % ("a/" + fn1, datetag(ad, fn1))
1723
fde8fb2cbede Fix diff against an empty file (issue124) and add a test for this.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1637
diff changeset
176 if b is None:
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
177 l2 = '+++ /dev/null%s' % datetag(epoch)
1723
fde8fb2cbede Fix diff against an empty file (issue124) and add a test for this.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1637
diff changeset
178 else:
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
179 l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd, fn2))
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
180 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
181 l = [l1, l2, l3] + ["-" + e for e in a]
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
182 else:
2251
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
183 al = splitnewlines(a)
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
184 bl = splitnewlines(b)
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
185 l = list(_unidiff(a, b, al, bl, opts=opts))
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
186 if not l:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
187 return ""
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
188
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
189 l.insert(0, "--- a/%s%s" % (fn1, datetag(ad, fn1)))
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
190 l.insert(1, "+++ b/%s%s" % (fn2, datetag(bd, fn2)))
170
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
191
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
192 for ln in xrange(len(l)):
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
193 if l[ln][-1] != '\n':
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
194 l[ln] += "\n\ No newline at end of file\n"
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
195
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
196 return "".join(l)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
197
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
198 # creates a headerless unified diff
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
199 # t1 and t2 are the text to be diffed
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
200 # l1 and l2 are the text broken up into lines
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
201 def _unidiff(t1, t2, l1, l2, opts=defaultopts):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
202 def contextend(l, len):
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
203 ret = l + opts.context
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
204 if ret > len:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
205 ret = len
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
206 return ret
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
207
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
208 def contextstart(l):
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
209 ret = l - opts.context
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
210 if ret < 0:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
211 return 0
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
212 return ret
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
213
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
214 lastfunc = [0, '']
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
215 def yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
216 (astart, a2, bstart, b2, delta) = hunk
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
217 aend = contextend(a2, len(l1))
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
218 alen = aend - astart
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
219 blen = b2 - bstart + aend - a2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
220
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
221 func = ""
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
222 if opts.showfunc:
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
223 lastpos, func = lastfunc
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
224 # walk backwards from the start of the context up to the start of
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
225 # the previous hunk context until we find a line starting with an
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
226 # alphanumeric char.
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
227 for i in xrange(astart - 1, lastpos - 1, -1):
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
228 if l1[i][0].isalnum():
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
229 func = ' ' + l1[i].rstrip()[:40]
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
230 lastfunc[1] = func
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
231 break
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
232 # by recording this hunk's starting point as the next place to
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
233 # start looking for function lines, we avoid reading any line in
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
234 # the file more than once.
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
235 lastfunc[0] = astart
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
236
15462
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
237 # zero-length hunk ranges report their start line as one less
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
238 if alen:
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
239 astart += 1
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
240 if blen:
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
241 bstart += 1
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
242
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
243 yield "@@ -%d,%d +%d,%d @@%s\n" % (astart, alen,
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
244 bstart, blen, func)
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
245 for x in delta:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
246 yield x
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
247 for x in xrange(a2, aend):
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
248 yield ' ' + l1[x]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
249
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
250 # bdiff.blocks gives us the matching sequences in the files. The loop
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
251 # below finds the spaces between those matching sequences and translates
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
252 # them into diff output.
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
253 #
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
254 hunk = None
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
255 ignoredlines = 0
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
256 for s, stype in allblocks(t1, t2, opts, l1, l2):
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
257 a1, a2, b1, b2 = s
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
258 if stype != '!':
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
259 if stype == '~':
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
260 # The diff context lines are based on t1 content. When
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
261 # blank lines are ignored, the new lines offsets must
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
262 # be adjusted as if equivalent blocks ('~') had the
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
263 # same sizes on both sides.
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
264 ignoredlines += (b2 - b1) - (a2 - a1)
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
265 continue
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
266 delta = []
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
267 old = l1[a1:a2]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
268 new = l2[b1:b2]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
269
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
270 b1 -= ignoredlines
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
271 b2 -= ignoredlines
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
272 astart = contextstart(a1)
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
273 bstart = contextstart(b1)
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
274 prev = None
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
275 if hunk:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
276 # join with the previous hunk if it falls inside the context
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
277 if astart < hunk[1] + opts.context + 1:
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
278 prev = hunk
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
279 astart = hunk[1]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
280 bstart = hunk[3]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
281 else:
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
282 for x in yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
283 yield x
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
284 if prev:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
285 # we've joined the previous hunk, record the new ending points.
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
286 hunk[1] = a2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
287 hunk[3] = b2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
288 delta = hunk[4]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
289 else:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
290 # create a new hunk
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
291 hunk = [astart, a2, bstart, b2, delta]
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
292
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
293 delta[len(delta):] = [' ' + x for x in l1[astart:a1]]
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
294 delta[len(delta):] = ['-' + x for x in old]
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
295 delta[len(delta):] = ['+' + x for x in new]
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
296
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
297 if hunk:
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
298 for x in yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
299 yield x
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
300
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
301 def b85diff(to, tn):
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
302 '''print base85-encoded binary diff'''
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
303 def fmtline(line):
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
304 l = len(line)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
305 if l <= 26:
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
306 l = chr(ord('A') + l - 1)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
307 else:
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
308 l = chr(l - 26 + ord('a') - 1)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
309 return '%c%s\n' % (l, base85.b85encode(line, True))
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
310
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
311 def chunk(text, csize=52):
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
312 l = len(text)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
313 i = 0
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
314 while i < l:
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
315 yield text[i:i + csize]
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
316 i += csize
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
317
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
318 if to is None:
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
319 to = ''
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
320 if tn is None:
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
321 tn = ''
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
322
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
323 if to == tn:
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
324 return ''
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
325
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
326 # TODO: deltas
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
327 ret = []
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
328 ret.append('GIT binary patch\n')
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
329 ret.append('literal %s\n' % len(tn))
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
330 for l in chunk(zlib.compress(tn)):
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
331 ret.append(fmtline(l))
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
332 ret.append('\n')
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
333
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
334 return ''.join(ret)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
335
120
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
336 def patchtext(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
337 pos = 0
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
338 t = []
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
339 while pos < len(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
340 p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
341 pos += 12
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
342 t.append(bin[pos:pos + l])
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
343 pos += l
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
344 return "".join(t)
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
345
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
346 def patch(a, bin):
12025
2315a95ee887 mdiff.patch(): add a special case for when the base text is empty
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10614
diff changeset
347 if len(a) == 0:
2315a95ee887 mdiff.patch(): add a special case for when the base text is empty
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10614
diff changeset
348 # skip over trivial delta header
15657
d976b1ef6760 util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents: 15530
diff changeset
349 return util.buffer(bin, 12)
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
350 return mpatch.patches(a, [bin])
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
351
4361
99c853a1408c add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4108
diff changeset
352 # similar to difflib.SequenceMatcher.get_matching_blocks
99c853a1408c add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4108
diff changeset
353 def get_matching_blocks(a, b):
99c853a1408c add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4108
diff changeset
354 return [(d[0], d[2], d[1] - d[0]) for d in bdiff.blocks(a, b)]
99c853a1408c add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4108
diff changeset
355
5367
7530334bf301 revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents: 4878
diff changeset
356 def trivialdiffheader(length):
7530334bf301 revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents: 4878
diff changeset
357 return struct.pack(">lll", 0, 0, length)
7530334bf301 revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents: 4878
diff changeset
358
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
359 patches = mpatch.patches
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1723
diff changeset
360 patchedsize = mpatch.patchedsize
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
361 textdiff = bdiff.bdiff