Mercurial > hg
annotate mercurial/mdiff.py @ 10545:b9e4a67329cd stable
Updated contrib/vim/patchreview.* to version 0.2.1
1) adds a :DiffReview command to review code changes
in the current workspace.
2) removes the need to have patchutils (specifically filterdiff)
installed on the system by implementing patch extraction in
pure vim script.
author | Manpreet Singh <junkblocker@yahoo.com> |
---|---|
date | Wed, 24 Feb 2010 13:12:17 -0800 |
parents | 08a0f04b56bd |
children | d0050f36e688 |
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 | 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 | 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 _ |
8312
b87a50b7125c
separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents:
8225
diff
changeset
|
9 import bdiff, mpatch, util |
b87a50b7125c
separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents:
8225
diff
changeset
|
10 import re, struct |
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 | 26 git enables the git extended patch format |
3199
096f1c73cdc3
Add -D/--nodates options to hg diff/export that removes dates from diff headers
Stephen Darnell <stephen@darnell.plus.com>
parents:
3026
diff
changeset
|
27 nodates removes dates from diff headers |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
28 ignorews ignores all whitespace changes in the diff |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
29 ignorewsamount ignores changes in the amount of whitespace |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10185
diff
changeset
|
30 ignoreblanklines ignores changes whose lines are all blank |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10185
diff
changeset
|
31 upgrade generates git diffs to avoid data loss |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10185
diff
changeset
|
32 ''' |
396
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
361
diff
changeset
|
33 |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
34 defaults = { |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
35 'context': 3, |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
36 'text': False, |
5863
3d1f9dcecdea
diff: don't show function name by default
Matt Mackall <mpm@selenic.com>
parents:
5482
diff
changeset
|
37 'showfunc': False, |
2907 | 38 'git': False, |
3199
096f1c73cdc3
Add -D/--nodates options to hg diff/export that removes dates from diff headers
Stephen Darnell <stephen@darnell.plus.com>
parents:
3026
diff
changeset
|
39 'nodates': False, |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
40 'ignorews': False, |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
41 'ignorewsamount': False, |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
42 'ignoreblanklines': False, |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10185
diff
changeset
|
43 'upgrade': False, |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
44 } |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
45 |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
46 __slots__ = defaults.keys() |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
47 |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
48 def __init__(self, **opts): |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
49 for k in self.__slots__: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
50 v = opts.get(k) |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
51 if v is None: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
52 v = self.defaults[k] |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
53 setattr(self, k, v) |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
54 |
6467
65029a3aafc2
Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents:
5863
diff
changeset
|
55 try: |
65029a3aafc2
Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents:
5863
diff
changeset
|
56 self.context = int(self.context) |
65029a3aafc2
Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents:
5863
diff
changeset
|
57 except ValueError: |
65029a3aafc2
Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents:
5863
diff
changeset
|
58 raise util.Abort(_('diff context lines count must be ' |
65029a3aafc2
Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents:
5863
diff
changeset
|
59 'an integer, not %r') % self.context) |
65029a3aafc2
Let --unified default to diff.unified (issue 1076)
Patrick Mezard <pmezard@gmail.com>
parents:
5863
diff
changeset
|
60 |
10185
7637fe4f525d
mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents:
9827
diff
changeset
|
61 def copy(self, **kwargs): |
7637fe4f525d
mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents:
9827
diff
changeset
|
62 opts = dict((k, getattr(self, k)) for k in self.defaults) |
7637fe4f525d
mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents:
9827
diff
changeset
|
63 opts.update(kwargs) |
7637fe4f525d
mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents:
9827
diff
changeset
|
64 return diffopts(**opts) |
7637fe4f525d
mq: preserve --git flag when merging patches
Patrick Mezard <pmezard@gmail.com>
parents:
9827
diff
changeset
|
65 |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
66 defaultopts = diffopts() |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
67 |
9827
4fe9ca519637
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents:
8632
diff
changeset
|
68 def wsclean(opts, text, blank=True): |
4878
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
69 if opts.ignorews: |
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
70 text = re.sub('[ \t]+', '', text) |
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
71 elif opts.ignorewsamount: |
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
72 text = re.sub('[ \t]+', ' ', text) |
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
73 text = re.sub('[ \t]+\n', '\n', text) |
9827
4fe9ca519637
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents:
8632
diff
changeset
|
74 if blank and opts.ignoreblanklines: |
4878
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
75 text = re.sub('\n+', '', text) |
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
76 return text |
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
77 |
7200
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
78 def diffline(revs, a, b, opts): |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
79 parts = ['diff'] |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
80 if opts.git: |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
81 parts.append('--git') |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
82 if revs and not opts.git: |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
83 parts.append(' '.join(["-r %s" % rev for rev in revs])) |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
84 if opts.git: |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
85 parts.append('a/%s' % a) |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
86 parts.append('b/%s' % b) |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
87 else: |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
88 parts.append(a) |
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
89 return ' '.join(parts) + '\n' |
7204
ad28279053ef
Remove trailing space
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7200
diff
changeset
|
90 |
5482
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5367
diff
changeset
|
91 def unidiff(a, ad, b, bd, fn1, fn2, r=None, opts=defaultopts): |
4679
826659bd8053
git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4361
diff
changeset
|
92 def datetag(date, addtab=True): |
826659bd8053
git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4361
diff
changeset
|
93 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
|
94 return '\t%s\n' % date |
5482
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5367
diff
changeset
|
95 if addtab and ' ' in fn1: |
4679
826659bd8053
git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4361
diff
changeset
|
96 return '\t\n' |
826659bd8053
git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4361
diff
changeset
|
97 return '\n' |
3026
d838bfac668d
Remove dates from git export file lines - they confuse git-apply
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
98 |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
99 if not a and not b: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
100 return "" |
1379 | 101 epoch = util.datestr((0, 0)) |
264
4c1d7072d5cd
Attempt to make diff deal with null sources properly
mpm@selenic.com
parents:
249
diff
changeset
|
102 |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
103 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
|
104 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
|
105 return "" |
5482
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5367
diff
changeset
|
106 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
|
107 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
|
108 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
|
109 if a is None: |
4679
826659bd8053
git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4361
diff
changeset
|
110 l1 = '--- /dev/null%s' % datetag(epoch, False) |
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
|
111 else: |
5482
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5367
diff
changeset
|
112 l1 = "--- %s%s" % ("a/" + fn1, datetag(ad)) |
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5367
diff
changeset
|
113 l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd)) |
264
4c1d7072d5cd
Attempt to make diff deal with null sources properly
mpm@selenic.com
parents:
249
diff
changeset
|
114 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
|
115 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
|
116 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
|
117 a = splitnewlines(a) |
5482
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5367
diff
changeset
|
118 l1 = "--- %s%s" % ("a/" + fn1, datetag(ad)) |
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
|
119 if b is None: |
4679
826659bd8053
git patches: correct handling of filenames with spaces
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4361
diff
changeset
|
120 l2 = '+++ /dev/null%s' % datetag(epoch, False) |
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
|
121 else: |
5482
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5367
diff
changeset
|
122 l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd)) |
264
4c1d7072d5cd
Attempt to make diff deal with null sources properly
mpm@selenic.com
parents:
249
diff
changeset
|
123 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
|
124 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
|
125 else: |
2251
35fb62a3a673
fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2248
diff
changeset
|
126 al = splitnewlines(a) |
35fb62a3a673
fix speed regression in mdiff caused by line split bugfix.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2248
diff
changeset
|
127 bl = splitnewlines(b) |
5482
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5367
diff
changeset
|
128 l = list(bunidiff(a, b, al, bl, "a/" + fn1, "b/" + fn2, opts=opts)) |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
129 if not l: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
130 return "" |
272
467cea2bf2d8
diff: use tab to separate date from filename
mpm@selenic.com
parents:
264
diff
changeset
|
131 # difflib uses a space, rather than a tab |
3026
d838bfac668d
Remove dates from git export file lines - they confuse git-apply
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
132 l[0] = "%s%s" % (l[0][:-2], datetag(ad)) |
d838bfac668d
Remove dates from git export file lines - they confuse git-apply
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
133 l[1] = "%s%s" % (l[1][:-2], datetag(bd)) |
170 | 134 |
135 for ln in xrange(len(l)): | |
136 if l[ln][-1] != '\n': | |
137 l[ln] += "\n\ No newline at end of file\n" | |
138 | |
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
|
139 if r: |
7200
ca5ac40949dc
patch/diff: use a separate function to write the first line of a file diff
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6871
diff
changeset
|
140 l.insert(0, diffline(r, fn1, fn2, opts)) |
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
|
141 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
142 return "".join(l) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
143 |
1637 | 144 # somewhat self contained replacement for difflib.unified_diff |
145 # t1 and t2 are the text to be diffed | |
146 # l1 and l2 are the text broken up into lines | |
147 # header1 and header2 are the filenames for the diff output | |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
148 def bunidiff(t1, t2, l1, l2, header1, header2, opts=defaultopts): |
1637 | 149 def contextend(l, len): |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
150 ret = l + opts.context |
1637 | 151 if ret > len: |
152 ret = len | |
153 return ret | |
154 | |
155 def contextstart(l): | |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
156 ret = l - opts.context |
1637 | 157 if ret < 0: |
158 return 0 | |
159 return ret | |
160 | |
161 def yieldhunk(hunk, header): | |
162 if header: | |
163 for x in header: | |
164 yield x | |
165 (astart, a2, bstart, b2, delta) = hunk | |
166 aend = contextend(a2, len(l1)) | |
167 alen = aend - astart | |
168 blen = b2 - bstart + aend - a2 | |
169 | |
170 func = "" | |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
171 if opts.showfunc: |
1637 | 172 # walk backwards from the start of the context |
173 # to find a line starting with an alphanumeric char. | |
7436
07faba78cf5a
diff: fix obscure off-by-one error in diff -p
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7204
diff
changeset
|
174 for x in xrange(astart - 1, -1, -1): |
1637 | 175 t = l1[x].rstrip() |
176 if funcre.match(t): | |
177 func = ' ' + t[:40] | |
178 break | |
179 | |
180 yield "@@ -%d,%d +%d,%d @@%s\n" % (astart + 1, alen, | |
181 bstart + 1, blen, func) | |
182 for x in delta: | |
183 yield x | |
184 for x in xrange(a2, aend): | |
185 yield ' ' + l1[x] | |
186 | |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
187 header = ["--- %s\t\n" % header1, "+++ %s\t\n" % header2] |
1637 | 188 |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2859
diff
changeset
|
189 if opts.showfunc: |
1637 | 190 funcre = re.compile('\w') |
191 | |
192 # bdiff.blocks gives us the matching sequences in the files. The loop | |
193 # below finds the spaces between those matching sequences and translates | |
194 # them into diff output. | |
195 # | |
9827
4fe9ca519637
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents:
8632
diff
changeset
|
196 if opts.ignorews or opts.ignorewsamount: |
4fe9ca519637
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents:
8632
diff
changeset
|
197 t1 = wsclean(opts, t1, False) |
4fe9ca519637
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents:
8632
diff
changeset
|
198 t2 = wsclean(opts, t2, False) |
4fe9ca519637
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents:
8632
diff
changeset
|
199 |
1637 | 200 diff = bdiff.blocks(t1, t2) |
201 hunk = None | |
8632
9e055cfdd620
replace "i in range(len(xs))" with "i, x in enumerate(xs)"
Martin Geisler <mg@lazybytes.net>
parents:
8312
diff
changeset
|
202 for i, s1 in enumerate(diff): |
1637 | 203 # The first match is special. |
204 # we've either found a match starting at line 0 or a match later | |
205 # in the file. If it starts later, old and new below will both be | |
206 # empty and we'll continue to the next match. | |
207 if i > 0: | |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
208 s = diff[i - 1] |
1637 | 209 else: |
210 s = [0, 0, 0, 0] | |
211 delta = [] | |
212 a1 = s[1] | |
213 a2 = s1[0] | |
214 b1 = s[3] | |
215 b2 = s1[2] | |
216 | |
217 old = l1[a1:a2] | |
218 new = l2[b1:b2] | |
219 | |
220 # bdiff sometimes gives huge matches past eof, this check eats them, | |
221 # and deals with the special first match case described above | |
222 if not old and not new: | |
223 continue | |
224 | |
9827
4fe9ca519637
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Patrick Mezard <pmezard@gmail.com>
parents:
8632
diff
changeset
|
225 if opts.ignoreblanklines: |
4878
372d93f03d3a
diff: correctly handle combinations of whitespace options
Matt Mackall <mpm@selenic.com>
parents:
4679
diff
changeset
|
226 if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)): |
1637 | 227 continue |
228 | |
229 astart = contextstart(a1) | |
230 bstart = contextstart(b1) | |
231 prev = None | |
232 if hunk: | |
233 # 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
|
234 if astart < hunk[1] + opts.context + 1: |
1637 | 235 prev = hunk |
236 astart = hunk[1] | |
237 bstart = hunk[3] | |
238 else: | |
239 for x in yieldhunk(hunk, header): | |
240 yield x | |
241 # we only want to yield the header if the files differ, and | |
242 # we only want to yield it once. | |
243 header = None | |
244 if prev: | |
245 # we've joined the previous hunk, record the new ending points. | |
246 hunk[1] = a2 | |
247 hunk[3] = b2 | |
248 delta = hunk[4] | |
249 else: | |
250 # create a new hunk | |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
251 hunk = [astart, a2, bstart, b2, delta] |
1637 | 252 |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
253 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
|
254 delta[len(delta):] = ['-' + x for x in old] |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
255 delta[len(delta):] = ['+' + x for x in new] |
1637 | 256 |
257 if hunk: | |
258 for x in yieldhunk(hunk, header): | |
259 yield x | |
260 | |
120
bae6f0328f63
Add a function to return the new text from a binary diff
mpm@selenic.com
parents:
75
diff
changeset
|
261 def patchtext(bin): |
bae6f0328f63
Add a function to return the new text from a binary diff
mpm@selenic.com
parents:
75
diff
changeset
|
262 pos = 0 |
bae6f0328f63
Add a function to return the new text from a binary diff
mpm@selenic.com
parents:
75
diff
changeset
|
263 t = [] |
bae6f0328f63
Add a function to return the new text from a binary diff
mpm@selenic.com
parents:
75
diff
changeset
|
264 while pos < len(bin): |
bae6f0328f63
Add a function to return the new text from a binary diff
mpm@selenic.com
parents:
75
diff
changeset
|
265 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
|
266 pos += 12 |
bae6f0328f63
Add a function to return the new text from a binary diff
mpm@selenic.com
parents:
75
diff
changeset
|
267 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
|
268 pos += l |
bae6f0328f63
Add a function to return the new text from a binary diff
mpm@selenic.com
parents:
75
diff
changeset
|
269 return "".join(t) |
bae6f0328f63
Add a function to return the new text from a binary diff
mpm@selenic.com
parents:
75
diff
changeset
|
270 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
271 def patch(a, bin): |
1379 | 272 return mpatch.patches(a, [bin]) |
432 | 273 |
4361
99c853a1408c
add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4108
diff
changeset
|
274 # 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
|
275 def get_matching_blocks(a, b): |
99c853a1408c
add mdiff.get_matching_blocks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4108
diff
changeset
|
276 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
|
277 |
5367
7530334bf301
revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents:
4878
diff
changeset
|
278 def trivialdiffheader(length): |
7530334bf301
revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents:
4878
diff
changeset
|
279 return struct.pack(">lll", 0, 0, length) |
7530334bf301
revlog: generate trivial deltas against null revision
Matt Mackall <mpm@selenic.com>
parents:
4878
diff
changeset
|
280 |
1379 | 281 patches = mpatch.patches |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
1723
diff
changeset
|
282 patchedsize = mpatch.patchedsize |
432 | 283 textdiff = bdiff.bdiff |