annotate mercurial/mdiff.py @ 33537:709dde1c5dd5

cachevfs: migration the tags fnode cache to 'cachevfs' This will help sharing the cache between shares.
author Boris Feld <boris.feld@octobus.net>
date Sat, 15 Jul 2017 23:30:25 +0200
parents 1b6946f87c50
children da07367d683b
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
27484
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
8 from __future__ import absolute_import
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
9
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
10 import re
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
11 import struct
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
12 import zlib
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
13
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
14 from .i18n import _
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
15 from . import (
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
16 error,
32369
3b88a7fa97d8 bdiff: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32202
diff changeset
17 policy,
31631
a7acda2de4b8 diff: use pycompat.{byteskwargs, strkwargs} to switch opts b/w bytes and str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31273
diff changeset
18 pycompat,
27484
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
19 util,
0d7635dca691 mdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
20 )
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
21
32369
3b88a7fa97d8 bdiff: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32202
diff changeset
22 bdiff = policy.importmod(r'bdiff')
32371
151cc3b3d799 mpatch: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32369
diff changeset
23 mpatch = policy.importmod(r'mpatch')
32369
3b88a7fa97d8 bdiff: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32202
diff changeset
24
32202
ded48ad55146 bdiff: proxy through mdiff module
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
25 blocks = bdiff.blocks
ded48ad55146 bdiff: proxy through mdiff module
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
26 fixws = bdiff.fixws
32200
2d84947cd85d mdiff: move re-exports to top
Yuya Nishihara <yuya@tcha.org>
parents: 31808
diff changeset
27 patches = mpatch.patches
2d84947cd85d mdiff: move re-exports to top
Yuya Nishihara <yuya@tcha.org>
parents: 31808
diff changeset
28 patchedsize = mpatch.patchedsize
2d84947cd85d mdiff: move re-exports to top
Yuya Nishihara <yuya@tcha.org>
parents: 31808
diff changeset
29 textdiff = bdiff.bdiff
2d84947cd85d mdiff: move re-exports to top
Yuya Nishihara <yuya@tcha.org>
parents: 31808
diff changeset
30
2251
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
31 def splitnewlines(text):
2248
b914f0557832 fix diffs containing embedded "\r".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2078
diff changeset
32 '''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
33 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
34 if lines:
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
35 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
36 lines.pop()
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
37 else:
35fb62a3a673 fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2248
diff changeset
38 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
39 return lines
2248
b914f0557832 fix diffs containing embedded "\r".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2078
diff changeset
40
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
41 class diffopts(object):
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
42 '''context is the number of context lines
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
43 text treats all files as text
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
44 showfunc enables diff -p output
2907
8b02af865990 Add diff --git option
Brendan Cully <brendan@kublai.com>
parents: 2874
diff changeset
45 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
46 nodates removes dates from diff headers
23293
b89856abf4e2 mdiff.diffopts: add doc comment for nobinary
Siddharth Agarwal <sid0@fb.com>
parents: 21790
diff changeset
47 nobinary ignores binary files
23294
ec8c73b02e2e mdiff.diffopts: add a new noprefix option
Siddharth Agarwal <sid0@fb.com>
parents: 23293
diff changeset
48 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
49 ignorews ignores all whitespace changes in the diff
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
50 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
51 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
52 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
53 '''
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
54
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
55 defaults = {
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
56 'context': 3,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
57 'text': False,
5863
3d1f9dcecdea diff: don't show function name by default
Matt Mackall <mpm@selenic.com>
parents: 5482
diff changeset
58 'showfunc': False,
2907
8b02af865990 Add diff --git option
Brendan Cully <brendan@kublai.com>
parents: 2874
diff changeset
59 '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
60 'nodates': False,
21790
3fbef7ac26f0 diff: add nobinary config to suppress git-style binary diffs
Stephen Lee <sphen.lee@gmail.com>
parents: 20034
diff changeset
61 'nobinary': False,
23294
ec8c73b02e2e mdiff.diffopts: add a new noprefix option
Siddharth Agarwal <sid0@fb.com>
parents: 23293
diff changeset
62 'noprefix': False,
30788
d1901c4c8ec0 patch: add config knob for displaying the index header
Sean Farley <sean@farley.io>
parents: 30717
diff changeset
63 'index': 0,
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
64 'ignorews': False,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
65 'ignorewsamount': False,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
66 'ignoreblanklines': False,
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10185
diff changeset
67 'upgrade': False,
30806
e2796f193f06 patch: add similarity config knob in experimental section
Sean Farley <sean@farley.io>
parents: 30788
diff changeset
68 'showsimilarity': False,
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
69 }
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
70
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
71 def __init__(self, **opts):
31631
a7acda2de4b8 diff: use pycompat.{byteskwargs, strkwargs} to switch opts b/w bytes and str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31273
diff changeset
72 opts = pycompat.byteskwargs(opts)
29416
30789efb1e5e mdiff: remove use of __slots__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27711
diff changeset
73 for k in self.defaults.keys():
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
74 v = opts.get(k)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
75 if v is None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
76 v = self.defaults[k]
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
77 setattr(self, k, v)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
78
6467
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
79 try:
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
80 self.context = int(self.context)
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
81 except ValueError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24119
diff changeset
82 raise error.Abort(_('diff context lines count must be '
6467
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
83 'an integer, not %r') % self.context)
65029a3aafc2 Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents: 5863
diff changeset
84
10185
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
85 def copy(self, **kwargs):
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
86 opts = dict((k, getattr(self, k)) for k in self.defaults)
33102
1b6946f87c50 py3: use pycompat.strkwargs() to convert kwargs keys to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32371
diff changeset
87 opts = pycompat.strkwargs(opts)
10185
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
88 opts.update(kwargs)
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
89 return diffopts(**opts)
7637fe4f525d mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents: 9827
diff changeset
90
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
91 defaultopts = diffopts()
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
92
9827
4fe9ca519637 mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents: 8632
diff changeset
93 def wsclean(opts, text, blank=True):
4878
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
94 if opts.ignorews:
15530
eeac5e179243 mdiff: replace wscleanup() regexps with C loops
Patrick Mezard <pmezard@gmail.com>
parents: 15529
diff changeset
95 text = bdiff.fixws(text, 1)
4878
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
96 elif opts.ignorewsamount:
15530
eeac5e179243 mdiff: replace wscleanup() regexps with C loops
Patrick Mezard <pmezard@gmail.com>
parents: 15529
diff changeset
97 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
98 if blank and opts.ignoreblanklines:
15509
3774e1453ef4 diff: --ignore-blank-lines was too enthusiastic
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
99 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
100 return text
372d93f03d3a diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents: 4679
diff changeset
101
15528
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
102 def splitblock(base1, lines1, base2, lines2, opts):
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
103 # 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
104 # 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
105 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
106 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
107 s1, e1 = 0, len(lines1)
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
108 s2, e2 = 0, len(lines2)
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
109 while s1 < e1 or s2 < e2:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
110 i1, i2, btype = s1, s2, '='
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
111 if (i1 >= e1 or lines1[i1] == 0
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
112 or i2 >= e2 or lines2[i2] == 0):
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
113 # Consume the block of blank lines
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
114 btype = '~'
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
115 while i1 < e1 and lines1[i1] == 0:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
116 i1 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
117 while i2 < e2 and lines2[i2] == 0:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
118 i2 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
119 else:
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
120 # Consume the matching lines
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
121 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
122 i1 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
123 i2 += 1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
124 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
125 s1 = i1
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
126 s2 = i2
a84698badf0b annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents: 15526
diff changeset
127
31808
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
128 def hunkinrange(hunk, linerange):
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
129 """Return True if `hunk` defined as (start, length) is in `linerange`
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
130 defined as (lowerbound, upperbound).
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
131
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
132 >>> hunkinrange((5, 10), (2, 7))
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
133 True
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
134 >>> hunkinrange((5, 10), (6, 12))
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
135 True
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
136 >>> hunkinrange((5, 10), (13, 17))
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
137 True
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
138 >>> hunkinrange((5, 10), (3, 17))
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
139 True
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
140 >>> hunkinrange((5, 10), (1, 3))
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
141 False
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
142 >>> hunkinrange((5, 10), (18, 20))
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
143 False
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
144 >>> hunkinrange((5, 10), (1, 5))
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
145 False
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
146 >>> hunkinrange((5, 10), (15, 27))
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
147 False
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
148 """
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
149 start, length = hunk
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
150 lowerbound, upperbound = linerange
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
151 return lowerbound < start + length and start < upperbound
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
152
30717
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
153 def blocksinrange(blocks, rangeb):
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
154 """filter `blocks` like (a1, a2, b1, b2) from items outside line range
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
155 `rangeb` from ``(b1, b2)`` point of view.
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
156
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
157 Return `filteredblocks, rangea` where:
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
158
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
159 * `filteredblocks` is list of ``block = (a1, a2, b1, b2), stype`` items of
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
160 `blocks` that are inside `rangeb` from ``(b1, b2)`` point of view; a
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
161 block ``(b1, b2)`` being inside `rangeb` if
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
162 ``rangeb[0] < b2 and b1 < rangeb[1]``;
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
163 * `rangea` is the line range w.r.t. to ``(a1, a2)`` parts of `blocks`.
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
164 """
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
165 lbb, ubb = rangeb
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
166 lba, uba = None, None
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
167 filteredblocks = []
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
168 for block in blocks:
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
169 (a1, a2, b1, b2), stype = block
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
170 if lbb >= b1 and ubb <= b2 and stype == '=':
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
171 # rangeb is within a single "=" hunk, restrict back linerange1
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
172 # by offsetting rangeb
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
173 lba = lbb - b1 + a1
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
174 uba = ubb - b1 + a1
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
175 else:
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
176 if b1 <= lbb < b2:
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
177 if stype == '=':
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
178 lba = a2 - (b2 - lbb)
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
179 else:
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
180 lba = a1
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
181 if b1 < ubb <= b2:
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
182 if stype == '=':
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
183 uba = a1 + (ubb - b1)
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
184 else:
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
185 uba = a2
31808
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31715
diff changeset
186 if hunkinrange((b1, (b2 - b1)), rangeb):
30717
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
187 filteredblocks.append(block)
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
188 if lba is None or uba is None or uba < lba:
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
189 raise error.Abort(_('line range exceeds file size'))
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
190 return filteredblocks, (lba, uba)
3eeb8e138e5c mdiff: add a "blocksinrange" function to filter diff blocks by line range
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30023
diff changeset
191
30023
ff17dff99295 mdiff: remove unused parameter 'refine' from allblocks()
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 29416
diff changeset
192 def allblocks(text1, text2, opts=None, lines1=None, lines2=None):
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
193 """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
194 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
195 (bdiff blocks), '!' for non-matching blocks and '~' for blocks
30023
ff17dff99295 mdiff: remove unused parameter 'refine' from allblocks()
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 29416
diff changeset
196 matching only after having filtered blank lines.
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
197 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
198 they are already available.
15525
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
199 """
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
200 if opts is None:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
201 opts = defaultopts
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
202 if opts.ignorews or opts.ignorewsamount:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
203 text1 = wsclean(opts, text1, False)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
204 text2 = wsclean(opts, text2, False)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
205 diff = bdiff.blocks(text1, text2)
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
206 for i, s1 in enumerate(diff):
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
207 # The first match is special.
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
208 # 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
209 # 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
210 # 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
211 if i > 0:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
212 s = diff[i - 1]
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
213 else:
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
214 s = [0, 0, 0, 0]
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
215 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
216
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
217 # 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
218 # 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
219 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
220 type = '!'
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
221 if opts.ignoreblanklines:
15529
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
222 if lines1 is None:
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
223 lines1 = splitnewlines(text1)
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
224 if lines2 is None:
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
225 lines2 = splitnewlines(text2)
b35cf47286a6 mdiff: split lines in allblocks() only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15528
diff changeset
226 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
227 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
228 if old == new:
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
229 type = '~'
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
230 yield s, type
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
231 yield s1, '='
15525
935bf2e7dbc5 mdiff: extract blocks whitespace normalization in diffblocks()
Patrick Mezard <pmezard@gmail.com>
parents: 15513
diff changeset
232
17940
c84ef0047a94 diff: unify calls to diffline
Guillermo Pérez <bisho@fb.com>
parents: 17939
diff changeset
233 def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts):
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
234 """Return a unified diff as a (headers, hunks) tuple.
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
235
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
236 If the diff is not null, `headers` is a list with unified diff header
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
237 lines "--- <original>" and "+++ <new>" and `hunks` is a generator yielding
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
238 (hunkrange, hunklines) coming from _unidiff().
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
239 Otherwise, `headers` and `hunks` are empty.
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
240 """
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
241 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
242 if not opts.git and not opts.nodates:
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
243 return '\t%s' % date
16362
16b75661828e mdiff: fix diff header generation for files with spaces (issue3357)
Patrick Mezard <patrick@mezard.eu>
parents: 16089
diff changeset
244 if fn and ' ' in fn:
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
245 return '\t'
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
246 return ''
3026
d838bfac668d Remove dates from git export file lines - they confuse git-apply
Brendan Cully <brendan@kublai.com>
parents: 2907
diff changeset
247
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
248 sentinel = [], ()
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
249 if not a and not b:
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
250 return sentinel
23299
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
251
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
252 if opts.noprefix:
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
253 aprefix = bprefix = ''
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
254 else:
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
255 aprefix = 'a/'
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
256 bprefix = 'b/'
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
257
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
258 epoch = util.datestr((0, 0))
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
259
15437
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
260 fn1 = util.pconvert(fn1)
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
261 fn2 = util.pconvert(fn2)
8f08b635cdce diff: always use / in paths in diff
Mads Kiilerich <mads@kiilerich.com>
parents: 15141
diff changeset
262
31272
e41946f39724 mdiff: extract a checknonewline inner function in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31271
diff changeset
263 def checknonewline(lines):
e41946f39724 mdiff: extract a checknonewline inner function in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31271
diff changeset
264 for text in lines:
31715
6c80f985a13c diff: slice over bytes to make sure conditions work normally
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31631
diff changeset
265 if text[-1:] != '\n':
31272
e41946f39724 mdiff: extract a checknonewline inner function in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31271
diff changeset
266 text += "\n\ No newline at end of file\n"
e41946f39724 mdiff: extract a checknonewline inner function in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31271
diff changeset
267 yield text
e41946f39724 mdiff: extract a checknonewline inner function in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31271
diff changeset
268
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
269 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
270 if a and b and len(a) == len(b) and a == b:
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
271 return sentinel
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
272 headerlines = []
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
273 hunks = (None, ['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
274 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
275 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
276 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
277 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
278 else:
23299
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
279 l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1))
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
280 l2 = "+++ %s%s" % (bprefix + fn2, datetag(bd, fn2))
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
281 headerlines = [l1, l2]
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
282 size = len(b)
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
283 hunkrange = (0, 0, 1, size)
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
284 hunklines = ["@@ -0,0 +1,%d @@\n" % size] + ["+" + e for e in b]
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
285 hunks = (hunkrange, checknonewline(hunklines)),
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
286 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
287 a = splitnewlines(a)
23299
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
288 l1 = "--- %s%s%s" % (aprefix, 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
289 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
290 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
291 else:
23299
1f510efcd5f3 mdiff.unidiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23294
diff changeset
292 l2 = "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2))
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
293 headerlines = [l1, l2]
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
294 size = len(a)
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
295 hunkrange = (1, size, 0, 0)
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
296 hunklines = ["@@ -1,%d +0,0 @@\n" % size] + ["-" + e for e in a]
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
297 hunks = (hunkrange, checknonewline(hunklines)),
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
298 else:
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
299 diffhunks = _unidiff(a, b, opts=opts)
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
300 try:
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
301 hunkrange, hunklines = next(diffhunks)
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
302 except StopIteration:
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
303 return sentinel
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
304
31271
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
305 headerlines = [
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
306 "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)),
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
307 "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2)),
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31269
diff changeset
308 ]
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
309 def rewindhunks():
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
310 yield hunkrange, checknonewline(hunklines)
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
311 for hr, hl in diffhunks:
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
312 yield hr, checknonewline(hl)
170
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
313
31273
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
314 hunks = rewindhunks()
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
315
92714858dd3e mdiff: let unidiff return (diffheader, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31272
diff changeset
316 return headerlines, hunks
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
317
31267
881ed6a4cf87 mdiff: compute newlines-splitted texts within _unidiff
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30806
diff changeset
318 def _unidiff(t1, t2, opts=defaultopts):
31269
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
319 """Yield hunks of a headerless unified diff from t1 and t2 texts.
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
320
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
321 Each hunk consists of a (hunkrange, hunklines) tuple where `hunkrange` is a
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
322 tuple (s1, l1, s2, l2) representing the range information of the hunk to
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
323 form the '@@ -s1,l1 +s2,l2 @@' header and `hunklines` is a list of lines
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
324 of the hunk combining said header followed by line additions and
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
325 deletions.
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
326 """
31267
881ed6a4cf87 mdiff: compute newlines-splitted texts within _unidiff
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30806
diff changeset
327 l1 = splitnewlines(t1)
881ed6a4cf87 mdiff: compute newlines-splitted texts within _unidiff
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30806
diff changeset
328 l2 = splitnewlines(t2)
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
329 def contextend(l, len):
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
330 ret = l + opts.context
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
331 if ret > len:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
332 ret = len
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
333 return ret
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
334
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
335 def contextstart(l):
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
336 ret = l - opts.context
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
337 if ret < 0:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
338 return 0
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
339 return ret
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
340
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
341 lastfunc = [0, '']
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
342 def yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
343 (astart, a2, bstart, b2, delta) = hunk
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
344 aend = contextend(a2, len(l1))
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
345 alen = aend - astart
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
346 blen = b2 - bstart + aend - a2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
347
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
348 func = ""
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2859
diff changeset
349 if opts.showfunc:
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
350 lastpos, func = lastfunc
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
351 # 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
352 # 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
353 # alphanumeric char.
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
354 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
355 if l1[i][0].isalnum():
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
356 func = ' ' + l1[i].rstrip()[:40]
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
357 lastfunc[1] = func
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
358 break
15141
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
359 # 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
360 # 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
361 # the file more than once.
16dc9a32ca04 mdiff: speed up showfunc for large diffs
Brodie Rao <brodie@bitheap.org>
parents: 12751
diff changeset
362 lastfunc[0] = astart
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
363
15462
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
364 # 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
365 if alen:
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
366 astart += 1
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
367 if blen:
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
368 bstart += 1
2b1ec74c961f mdiff/patch: fix bad hunk handling for unified diffs with zero context
Nicolas Venegas <nvenegas@atlassian.com>
parents: 15141
diff changeset
369
31269
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
370 hunkrange = astart, alen, bstart, blen
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
371 hunklines = (
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
372 ["@@ -%d,%d +%d,%d @@%s\n" % (hunkrange + (func,))]
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
373 + delta
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
374 + [' ' + l1[x] for x in xrange(a2, aend)]
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
375 )
5e7fd3a0b17f mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31268
diff changeset
376 yield hunkrange, hunklines
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
377
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
378 # 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
379 # below finds the spaces between those matching sequences and translates
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
380 # them into diff output.
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
381 #
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
382 hunk = None
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
383 ignoredlines = 0
15526
e6519c628454 mdiff: make diffblocks() return all blocks, matching and changed
Patrick Mezard <pmezard@gmail.com>
parents: 15525
diff changeset
384 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
385 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
386 if stype != '!':
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
387 if stype == '~':
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
388 # 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
389 # 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
390 # 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
391 # same sizes on both sides.
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
392 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
393 continue
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
394 delta = []
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
395 old = l1[a1:a2]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
396 new = l2[b1:b2]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
397
16089
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
398 b1 -= ignoredlines
2e8f4b82c551 mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)
Patrick Mezard <patrick@mezard.eu>
parents: 15657
diff changeset
399 b2 -= ignoredlines
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
400 astart = contextstart(a1)
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
401 bstart = contextstart(b1)
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
402 prev = None
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
403 if hunk:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
404 # 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
405 if astart < hunk[1] + opts.context + 1:
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
406 prev = hunk
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
407 astart = hunk[1]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
408 bstart = hunk[3]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
409 else:
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
410 for x in yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
411 yield x
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
412 if prev:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
413 # 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
414 hunk[1] = a2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
415 hunk[3] = b2
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
416 delta = hunk[4]
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
417 else:
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
418 # create a new hunk
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
419 hunk = [astart, a2, bstart, b2, delta]
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
420
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
421 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
422 delta[len(delta):] = ['-' + x for x in old]
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
423 delta[len(delta):] = ['+' + x for x in new]
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
424
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
425 if hunk:
10614
d0050f36e688 remove header handling out of mdiff.bunidiff, rename it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
426 for x in yieldhunk(hunk):
1637
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
427 yield x
3b1b44b917f4 Add new bdiff based unidiff generation.
mason@suse.com
parents: 1540
diff changeset
428
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
429 def b85diff(to, tn):
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
430 '''print base85-encoded binary diff'''
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
431 def fmtline(line):
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
432 l = len(line)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
433 if l <= 26:
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
434 l = chr(ord('A') + l - 1)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
435 else:
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
436 l = chr(l - 26 + ord('a') - 1)
32201
4462a981e8df base85: proxy through util module
Yuya Nishihara <yuya@tcha.org>
parents: 32200
diff changeset
437 return '%c%s\n' % (l, util.b85encode(line, True))
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
438
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
439 def chunk(text, csize=52):
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
440 l = len(text)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
441 i = 0
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
442 while i < l:
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
443 yield text[i:i + csize]
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
444 i += csize
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
445
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
446 if to is None:
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
447 to = ''
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
448 if tn is None:
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
449 tn = ''
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
450
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
451 if to == tn:
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
452 return ''
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
453
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
454 # TODO: deltas
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
455 ret = []
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
456 ret.append('GIT binary patch\n')
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
457 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
458 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
459 ret.append(fmtline(l))
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
460 ret.append('\n')
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17941
diff changeset
461
17939
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
462 return ''.join(ret)
d587925680d9 diff: move b85diff to mdiff module
Guillermo Pérez <bisho at fb.com>
parents: 16362
diff changeset
463
120
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
464 def patchtext(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
465 pos = 0
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
466 t = []
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
467 while pos < len(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
468 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
469 pos += 12
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
470 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
471 pos += l
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
472 return "".join(t)
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
473
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
474 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
475 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
476 # 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
477 return util.buffer(bin, 12)
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
478 return mpatch.patches(a, [bin])
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
479
4361
99c853a1408c add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4108
diff changeset
480 # 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
481 def get_matching_blocks(a, b):
99c853a1408c add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4108
diff changeset
482 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
483
5367
7530334bf301 revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents: 4878
diff changeset
484 def trivialdiffheader(length):
27711
7a678a12a5cf mdiff: don't emit a diff header for empty trivial deltas
Mike Hommey <mh@glandium.org>
parents: 27484
diff changeset
485 return struct.pack(">lll", 0, 0, length) if length else ''
5367
7530334bf301 revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents: 4878
diff changeset
486
24119
a5a06c9c7407 mdiff: add helper for making deltas which replace the full text of a revision
Mike Edgar <adgar@google.com>
parents: 23299
diff changeset
487 def replacediffheader(oldlen, newlen):
a5a06c9c7407 mdiff: add helper for making deltas which replace the full text of a revision
Mike Edgar <adgar@google.com>
parents: 23299
diff changeset
488 return struct.pack(">lll", 0, oldlen, newlen)