annotate mercurial/mdiff.py @ 23294:ec8c73b02e2e

mdiff.diffopts: add a new noprefix option By popular demand, we introduce an option to disable the 'a/' and 'b/' prefixes in diff output. This makes copying and pasting filenames from diff output easier. This option will be implemented and documented in upcoming patches. To ensure that existing scripts that parse output don't break, we will ensure that this prefix is disabled in plain mode. A straight 'hg export | hg import' without HGPLAIN=1 will still be broken though, but there's little that can be done about that.
author Siddharth Agarwal <sid0@fb.com>
date Wed, 12 Nov 2014 23:25:32 -0800
parents b89856abf4e2
children 1f510efcd5f3
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
23293
b89856abf4e2 mdiff.diffopts: add doc comment for nobinary
Siddharth Agarwal <sid0@fb.com>
parents: 21790
diff changeset
28 nobinary ignores binary files
23294
ec8c73b02e2e mdiff.diffopts: add a new noprefix option
Siddharth Agarwal <sid0@fb.com>
parents: 23293
diff changeset
29 noprefix disables the 'a/' and 'b/' prefixes (ignored in plain mode)
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
30 ignorews ignores all whitespace changes in the diff
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
31 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
32 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
33 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
34 '''
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
35
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
36 defaults = {
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
37 'context': 3,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
38 'text': False,
5863
3d1f9dcecdea diff: don't show function name by default
Matt Mackall <mpm@selenic.com>
parents: 5482
diff changeset
39 'showfunc': False,
2907
8b02af865990 Add diff --git option
Brendan Cully <brendan@kublai.com>
parents: 2874
diff changeset
40 '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
41 'nodates': False,
21790
3fbef7ac26f0 diff: add nobinary config to suppress git-style binary diffs
Stephen Lee <sphen.lee@gmail.com>
parents: 20034
diff changeset
42 'nobinary': False,
23294
ec8c73b02e2e mdiff.diffopts: add a new noprefix option
Siddharth Agarwal <sid0@fb.com>
parents: 23293
diff changeset
43 'noprefix': False,
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
44 'ignorews': False,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
45 'ignorewsamount': False,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
46 'ignoreblanklines': False,
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10185
diff changeset
47 'upgrade': False,
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
48 }
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
49
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
50 __slots__ = defaults.keys()
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
51
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
52 def __init__(self, **opts):
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
53 for k in self.__slots__:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
54 v = opts.get(k)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
55 if v is None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
56 v = self.defaults[k]
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
57 setattr(self, k, v)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
58
6467
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
59 try:
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
60 self.context = int(self.context)
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
61 except ValueError:
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
62 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
63 'an integer, not %r') % self.context)
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
64
10185
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
65 def copy(self, **kwargs):
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
66 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
67 opts.update(kwargs)
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
68 return diffopts(**opts)
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
69
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
70 defaultopts = diffopts()
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
71
9827
4fe9ca519637 mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents: 8632
diff changeset
72 def wsclean(opts, text, blank=True):
4878
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
73 if opts.ignorews:
15530
eeac5e179243 mdiff: replace wscleanup() regexps with C loops
Patrick Mezard <pmezard@gmail.com>
parents: 15529
diff changeset
74 text = bdiff.fixws(text, 1)
4878
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
75 elif opts.ignorewsamount:
15530
eeac5e179243 mdiff: replace wscleanup() regexps with C loops
Patrick Mezard <pmezard@gmail.com>
parents: 15529
diff changeset
76 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
77 if blank and opts.ignoreblanklines:
15509
3774e1453ef4 diff: --ignore-blank-lines was too enthusiastic
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
78 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
79 return text
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
80
15528
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
81 def splitblock(base1, lines1, base2, lines2, opts):
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
82 # 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
83 # 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
84 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
85 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
86 s1, e1 = 0, len(lines1)
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
87 s2, e2 = 0, len(lines2)
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
88 while s1 < e1 or s2 < e2:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
89 i1, i2, btype = s1, s2, '='
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
90 if (i1 >= e1 or lines1[i1] == 0
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
91 or i2 >= e2 or lines2[i2] == 0):
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
92 # Consume the block of blank lines
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
93 btype = '~'
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
94 while i1 < e1 and lines1[i1] == 0:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
95 i1 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
96 while i2 < e2 and lines2[i2] == 0:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
97 i2 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
98 else:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
99 # Consume the matching lines
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
100 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
101 i1 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
102 i2 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
103 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
104 s1 = i1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
105 s2 = i2
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
106
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
107 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
108 """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
109 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
110 (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
111 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
112 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
113 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
114 they are already available.
15525
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
115 """
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
116 if opts is None:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
117 opts = defaultopts
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
118 if opts.ignorews or opts.ignorewsamount:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
119 text1 = wsclean(opts, text1, False)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
120 text2 = wsclean(opts, text2, False)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
121 diff = bdiff.blocks(text1, text2)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
122 for i, s1 in enumerate(diff):
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
123 # The first match is special.
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
124 # 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
125 # 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
126 # 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
127 if i > 0:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
128 s = diff[i - 1]
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
129 else:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
130 s = [0, 0, 0, 0]
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
131 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
132
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
133 # 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
134 # 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
135 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
136 type = '!'
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
137 if opts.ignoreblanklines:
15529
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
138 if lines1 is None:
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
139 lines1 = splitnewlines(text1)
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
140 if lines2 is None:
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
141 lines2 = splitnewlines(text2)
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
142 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
143 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
144 if old == new:
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
145 type = '~'
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
146 yield s, type
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
147 yield s1, '='
15525
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
148
17940
c84ef0047a94 diff: unify calls to diffline
Guillermo P?rez <bisho@fb.com>
parents: 17939
diff changeset
149 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
150 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
151 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
152 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
153 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
154 return '\t\n'
826659bd8053 git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4361
diff changeset
155 return '\n'
3026
d838bfac668d Remove dates from git export file lines - they confuse git-apply
Brendan Cully <brendan@kublai.com>
parents: 2907
diff changeset
156
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
157 if not a and not b:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
158 return ""
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
159 epoch = util.datestr((0, 0))
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
160
15437
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
161 fn1 = util.pconvert(fn1)
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
162 fn2 = util.pconvert(fn2)
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
163
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
164 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
165 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
166 return ""
5482
e5eedd74e70f Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents: 5367
diff changeset
167 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
168 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
169 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
170 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
171 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
172 else:
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
173 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
174 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
175 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
176 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
177 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
178 a = splitnewlines(a)
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
179 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
180 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
181 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
182 else:
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
183 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
184 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
185 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
186 else:
2251
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
187 al = splitnewlines(a)
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
188 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
189 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
190 if not l:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
191 return ""
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
192
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
193 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
194 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
195
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
196 for ln in xrange(len(l)):
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
197 if l[ln][-1] != '\n':
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
198 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
199
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
200 return "".join(l)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
201
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
202 # creates a headerless unified diff
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
203 # t1 and t2 are the text to be diffed
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
204 # 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
205 def _unidiff(t1, t2, l1, l2, opts=defaultopts):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
206 def contextend(l, len):
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
207 ret = l + opts.context
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
208 if ret > len:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
209 ret = len
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
210 return ret
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
211
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
212 def contextstart(l):
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
213 ret = l - opts.context
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
214 if ret < 0:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
215 return 0
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
216 return ret
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
217
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
218 lastfunc = [0, '']
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
219 def yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
220 (astart, a2, bstart, b2, delta) = hunk
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
221 aend = contextend(a2, len(l1))
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
222 alen = aend - astart
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
223 blen = b2 - bstart + aend - a2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
224
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
225 func = ""
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
226 if opts.showfunc:
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
227 lastpos, func = lastfunc
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
228 # 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
229 # 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
230 # alphanumeric char.
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
231 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
232 if l1[i][0].isalnum():
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
233 func = ' ' + l1[i].rstrip()[:40]
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
234 lastfunc[1] = func
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
235 break
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
236 # 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
237 # 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
238 # the file more than once.
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
239 lastfunc[0] = astart
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
240
15462
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
241 # 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
242 if alen:
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
243 astart += 1
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
244 if blen:
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
245 bstart += 1
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
246
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
247 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
248 bstart, blen, func)
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
249 for x in delta:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
250 yield x
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
251 for x in xrange(a2, aend):
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
252 yield ' ' + l1[x]
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 # 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
255 # below finds the spaces between those matching sequences and translates
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
256 # them into diff output.
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
257 #
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
258 hunk = None
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
259 ignoredlines = 0
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
260 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
261 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
262 if stype != '!':
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
263 if stype == '~':
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
264 # 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
265 # 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
266 # 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
267 # same sizes on both sides.
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
268 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
269 continue
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
270 delta = []
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
271 old = l1[a1:a2]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
272 new = l2[b1:b2]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
273
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
274 b1 -= ignoredlines
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
275 b2 -= ignoredlines
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
276 astart = contextstart(a1)
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
277 bstart = contextstart(b1)
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
278 prev = None
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
279 if hunk:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
280 # 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
281 if astart < hunk[1] + opts.context + 1:
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
282 prev = hunk
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
283 astart = hunk[1]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
284 bstart = hunk[3]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
285 else:
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
286 for x in yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
287 yield x
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
288 if prev:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
289 # 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
290 hunk[1] = a2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
291 hunk[3] = b2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
292 delta = hunk[4]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
293 else:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
294 # create a new hunk
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
295 hunk = [astart, a2, bstart, b2, delta]
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
296
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
297 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
298 delta[len(delta):] = ['-' + x for x in old]
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
299 delta[len(delta):] = ['+' + x for x in new]
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
300
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
301 if hunk:
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
302 for x in yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
303 yield x
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
304
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
305 def b85diff(to, tn):
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
306 '''print base85-encoded binary diff'''
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
307 def fmtline(line):
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
308 l = len(line)
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
309 if l <= 26:
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
310 l = chr(ord('A') + l - 1)
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
311 else:
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
312 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
313 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
314
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
315 def chunk(text, csize=52):
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
316 l = len(text)
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
317 i = 0
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
318 while i < l:
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
319 yield text[i:i + csize]
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
320 i += csize
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
321
17946
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
322 if to is None:
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
323 to = ''
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
324 if tn is None:
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
325 tn = ''
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
326
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
327 if to == tn:
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
328 return ''
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
329
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
330 # TODO: deltas
17946
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
331 ret = []
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
332 ret.append('GIT binary patch\n')
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
333 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
334 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
335 ret.append(fmtline(l))
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
336 ret.append('\n')
17946
1e13b1184292 diff: move index header generation to patch
Guillermo P?rez <bisho@fb.com>
parents: 17941
diff changeset
337
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
338 return ''.join(ret)
d587925680d9 diff: move b85diff to mdiff module
Guillermo P?rez <bisho at fb.com>
parents: 16362
diff changeset
339
120
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
340 def patchtext(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
341 pos = 0
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
342 t = []
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
343 while pos < len(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
344 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
345 pos += 12
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
346 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
347 pos += l
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
348 return "".join(t)
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
349
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
350 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
351 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
352 # 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
353 return util.buffer(bin, 12)
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
354 return mpatch.patches(a, [bin])
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
355
4361
99c853a1408c add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4108
diff changeset
356 # 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
357 def get_matching_blocks(a, b):
99c853a1408c add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4108
diff changeset
358 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
359
5367
7530334bf301 revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents: 4878
diff changeset
360 def trivialdiffheader(length):
7530334bf301 revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents: 4878
diff changeset
361 return struct.pack(">lll", 0, 0, length)
7530334bf301 revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents: 4878
diff changeset
362
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
363 patches = mpatch.patches
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1723
diff changeset
364 patchedsize = mpatch.patchedsize
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
365 textdiff = bdiff.bdiff