##// END OF EJS Templates
diffhelpers: be more tolerant for stripped empty lines of CRLF ending...
Yuya Nishihara -
r37593:230eb959 default
parent child Browse files
Show More
@@ -1,77 +1,77 b''
1 1 # diffhelpers.py - helper routines for patch
2 2 #
3 3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from .i18n import _
11 11
12 12 from . import (
13 13 error,
14 14 )
15 15
16 16 def addlines(fp, hunk, lena, lenb, a, b):
17 17 """Read lines from fp into the hunk
18 18
19 19 The hunk is parsed into two arrays, a and b. a gets the old state of
20 20 the text, b gets the new state. The control char from the hunk is saved
21 21 when inserting into a, but not b (for performance while deleting files.)
22 22 """
23 23 while True:
24 24 todoa = lena - len(a)
25 25 todob = lenb - len(b)
26 26 num = max(todoa, todob)
27 27 if num == 0:
28 28 break
29 29 for i in xrange(num):
30 30 s = fp.readline()
31 31 if not s:
32 32 raise error.ParseError(_('incomplete hunk'))
33 33 if s == "\\ No newline at end of file\n":
34 34 fixnewline(hunk, a, b)
35 35 continue
36 if s == "\n":
36 if s == '\n' or s == '\r\n':
37 37 # Some patches may be missing the control char
38 38 # on empty lines. Supply a leading space.
39 s = " \n"
39 s = ' ' + s
40 40 hunk.append(s)
41 41 if s.startswith('+'):
42 42 b.append(s[1:])
43 43 elif s.startswith('-'):
44 44 a.append(s)
45 45 else:
46 46 b.append(s[1:])
47 47 a.append(s)
48 48
49 49 def fixnewline(hunk, a, b):
50 50 """Fix up the last lines of a and b when the patch has no newline at EOF"""
51 51 l = hunk[-1]
52 52 # tolerate CRLF in last line
53 53 if l.endswith('\r\n'):
54 54 hline = l[:-2]
55 55 else:
56 56 hline = l[:-1]
57 57
58 58 if hline.startswith((' ', '+')):
59 59 b[-1] = hline[1:]
60 60 if hline.startswith((' ', '-')):
61 61 a[-1] = hline
62 62 hunk[-1] = hline
63 63
64 64 def testhunk(a, b, bstart):
65 65 """Compare the lines in a with the lines in b
66 66
67 67 a is assumed to have a control char at the start of each line, this char
68 68 is ignored in the compare.
69 69 """
70 70 alen = len(a)
71 71 blen = len(b)
72 72 if alen > blen - bstart:
73 73 return False
74 74 for i in xrange(alen):
75 75 if a[i][1:] != b[i + bstart]:
76 76 return False
77 77 return True
@@ -1,146 +1,173 b''
1 1 $ cat > makepatch.py <<EOF
2 > f = open('eol.diff', 'wb')
2 > import sys
3 > f = open(sys.argv[2], 'wb')
3 4 > w = f.write
4 5 > w(b'test message\n')
5 6 > w(b'diff --git a/a b/a\n')
6 7 > w(b'--- a/a\n')
7 8 > w(b'+++ b/a\n')
8 9 > w(b'@@ -1,5 +1,5 @@\n')
9 10 > w(b' a\n')
10 11 > w(b'-bbb\r\n')
11 12 > w(b'+yyyy\r\n')
12 13 > w(b' cc\r\n')
13 > w(b' \n')
14 > w({'empty:lf': b' \n',
15 > 'empty:crlf': b' \r\n',
16 > 'empty:stripped-lf': b'\n',
17 > 'empty:stripped-crlf': b'\r\n'}[sys.argv[1]])
14 18 > w(b' d\n')
15 19 > w(b'-e\n')
16 20 > w(b'\ No newline at end of file\n')
17 21 > w(b'+z\r\n')
18 22 > w(b'\ No newline at end of file\r\n')
19 23 > EOF
20 24
21 25 $ hg init repo
22 26 $ cd repo
23 27 $ echo '\.diff' > .hgignore
24 28
25 29
26 30 Test different --eol values
27 31
28 32 $ $PYTHON -c 'open("a", "wb").write(b"a\nbbb\ncc\n\nd\ne")'
29 33 $ hg ci -Am adda
30 34 adding .hgignore
31 35 adding a
32 $ $PYTHON ../makepatch.py
33
36 $ $PYTHON ../makepatch.py empty:lf eol.diff
37 $ $PYTHON ../makepatch.py empty:crlf eol-empty-crlf.diff
38 $ $PYTHON ../makepatch.py empty:stripped-lf eol-empty-stripped-lf.diff
39 $ $PYTHON ../makepatch.py empty:stripped-crlf eol-empty-stripped-crlf.diff
34 40
35 41 invalid eol
36 42
37 43 $ hg --config patch.eol='LFCR' import eol.diff
38 44 applying eol.diff
39 45 abort: unsupported line endings type: LFCR
40 46 [255]
41 47 $ hg revert -a
42 48
43 49
44 50 force LF
45 51
46 52 $ hg --traceback --config patch.eol='LF' import eol.diff
47 53 applying eol.diff
54 $ hg id
55 9e4ef7b3d4af tip
48 56 $ cat a
49 57 a
50 58 yyyy
51 59 cc
52 60
53 61 d
54 62 e (no-eol)
55 63 $ hg st
56 64
65 (test empty-line variants: all of them should generate the same revision)
66
67 $ hg up -qC 0
68 $ hg --config patch.eol='LF' import eol-empty-crlf.diff
69 applying eol-empty-crlf.diff
70 $ hg id
71 9e4ef7b3d4af tip
72
73 $ hg up -qC 0
74 $ hg --config patch.eol='LF' import eol-empty-stripped-lf.diff
75 applying eol-empty-stripped-lf.diff
76 $ hg id
77 9e4ef7b3d4af tip
78
79 $ hg up -qC 0
80 $ hg --config patch.eol='LF' import eol-empty-stripped-crlf.diff
81 applying eol-empty-stripped-crlf.diff
82 $ hg id
83 9e4ef7b3d4af tip
57 84
58 85 force CRLF
59 86
60 87 $ hg up -C 0
61 88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 89 $ hg --traceback --config patch.eol='CRLF' import eol.diff
63 90 applying eol.diff
64 91 $ cat a
65 92 a\r (esc)
66 93 yyyy\r (esc)
67 94 cc\r (esc)
68 95 \r (esc)
69 96 d\r (esc)
70 97 e (no-eol)
71 98 $ hg st
72 99
73 100
74 101 auto EOL on LF file
75 102
76 103 $ hg up -C 0
77 104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 105 $ hg --traceback --config patch.eol='auto' import eol.diff
79 106 applying eol.diff
80 107 $ cat a
81 108 a
82 109 yyyy
83 110 cc
84 111
85 112 d
86 113 e (no-eol)
87 114 $ hg st
88 115
89 116
90 117 auto EOL on CRLF file
91 118
92 119 $ $PYTHON -c 'open("a", "wb").write(b"a\r\nbbb\r\ncc\r\n\r\nd\r\ne")'
93 120 $ hg commit -m 'switch EOLs in a'
94 121 $ hg --traceback --config patch.eol='auto' import eol.diff
95 122 applying eol.diff
96 123 $ cat a
97 124 a\r (esc)
98 125 yyyy\r (esc)
99 126 cc\r (esc)
100 127 \r (esc)
101 128 d\r (esc)
102 129 e (no-eol)
103 130 $ hg st
104 131
105 132
106 133 auto EOL on new file or source without any EOL
107 134
108 135 $ $PYTHON -c 'open("noeol", "wb").write(b"noeol")'
109 136 $ hg add noeol
110 137 $ hg commit -m 'add noeol'
111 138 $ $PYTHON -c 'open("noeol", "wb").write(b"noeol\r\nnoeol\n")'
112 139 $ $PYTHON -c 'open("neweol", "wb").write(b"neweol\nneweol\r\n")'
113 140 $ hg add neweol
114 141 $ hg diff --git > noeol.diff
115 142 $ hg revert --no-backup noeol neweol
116 143 $ rm neweol
117 144 $ hg --traceback --config patch.eol='auto' import -m noeol noeol.diff
118 145 applying noeol.diff
119 146 $ cat noeol
120 147 noeol\r (esc)
121 148 noeol
122 149 $ cat neweol
123 150 neweol
124 151 neweol\r (esc)
125 152 $ hg st
126 153
127 154
128 155 Test --eol and binary patches
129 156
130 157 $ $PYTHON -c 'open("b", "wb").write(b"a\x00\nb\r\nd")'
131 158 $ hg ci -Am addb
132 159 adding b
133 160 $ $PYTHON -c 'open("b", "wb").write(b"a\x00\nc\r\nd")'
134 161 $ hg diff --git > bin.diff
135 162 $ hg revert --no-backup b
136 163
137 164 binary patch with --eol
138 165
139 166 $ hg import --config patch.eol='CRLF' -m changeb bin.diff
140 167 applying bin.diff
141 168 $ cat b
142 169 a\x00 (esc)
143 170 c\r (esc)
144 171 d (no-eol)
145 172 $ hg st
146 173 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now