Skip to content

Commit 4fa9801

Browse files
authored
Check for leftover content after a full delete (#9)
When applying a text fragment that deletes all content in the file, make sure there is no content left in the source after using all the lines in the fragment. If there is is extra content, it's a conflict: something added more lines to the file after generating the patch.
1 parent b5ae0bd commit 4fa9801

11 files changed

+357
-8
lines changed

gitdiff/apply.go

+13
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,19 @@ func (a *Applier) ApplyTextFragment(dst io.Writer, f *TextFragment) error {
259259
}
260260
}
261261
a.nextLine = fragStart + used
262+
263+
// new position of +0,0 mean a full delete, so check for leftovers
264+
if f.NewPosition == 0 && f.NewLines == 0 {
265+
var b [1][]byte
266+
n, err := a.lineSrc.ReadLinesAt(b[:], a.nextLine)
267+
if err != nil && err != io.EOF {
268+
return applyError(err, lineNum(a.nextLine))
269+
}
270+
if n > 0 {
271+
return applyError(&Conflict{"src still has content after full delete"}, lineNum(a.nextLine))
272+
}
273+
}
274+
262275
return nil
263276
}
264277

gitdiff/apply_test.go

+28-4
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,33 @@ func TestApplyBinaryFragment(t *testing.T) {
185185

186186
func TestApplyFile(t *testing.T) {
187187
tests := map[string]applyTest{
188-
"textModify": {Files: getApplyFiles("text_file_modify")},
189-
"binaryModify": {Files: getApplyFiles("bin_file_modify")},
190-
"modeChange": {Files: getApplyFiles("file_mode_change")},
188+
"textModify": {
189+
Files: applyFiles{
190+
Src: "file_text.src",
191+
Patch: "file_text_modify.patch",
192+
Out: "file_text_modify.out",
193+
},
194+
},
195+
"textDelete": {
196+
Files: applyFiles{
197+
Src: "file_text.src",
198+
Patch: "file_text_delete.patch",
199+
Out: "file_text_delete.out",
200+
},
201+
},
202+
"textErrorPartialDelete": {
203+
Files: applyFiles{
204+
Src: "file_text.src",
205+
Patch: "file_text_error_partial_delete.patch",
206+
},
207+
Err: &Conflict{},
208+
},
209+
"binaryModify": {
210+
Files: getApplyFiles("file_bin_modify"),
211+
},
212+
"modeChange": {
213+
Files: getApplyFiles("file_mode_change"),
214+
},
191215
}
192216

193217
for name, test := range tests {
@@ -233,7 +257,7 @@ func (at applyTest) run(t *testing.T, apply func(io.Writer, *Applier, *File) err
233257
}
234258

235259
if !bytes.Equal(out, dst.Bytes()) {
236-
t.Errorf("incorrect result after apply\nexpected:\n%x\nactual:\n%x", out, dst.Bytes())
260+
t.Errorf("incorrect result after apply\nexpected:\n%q\nactual:\n%q", out, dst.Bytes())
237261
}
238262
}
239263

gitdiff/testdata/apply/bin_file_modify.patch renamed to gitdiff/testdata/apply/file_bin_modify.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
diff --git a/gitdiff/testdata/apply/bin_file_modify.src b/gitdiff/testdata/apply/bin_file_modify.src
1+
diff --git a/gitdiff/testdata/apply/file_bin_modify.src b/gitdiff/testdata/apply/file_bin_modify.src
22
GIT binary patch
33
delta 172
44
zcmV;d08{^f2)qc8AP{I3VQ>J`s>wb0HU+h#6w8q?tUO~cHmDjZi2<8yZ9XmKhhMdo

gitdiff/testdata/apply/file_text_delete.out

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
diff --git a/gitdiff/testdata/apply/file_text.src.src b/gitdiff/testdata/apply/file_text.src
2+
deleted file mode 100644
3+
index 3805ad4..0000000
4+
--- a/gitdiff/testdata/apply/file_text.src.src
5+
+++ /dev/null
6+
@@ -1,200 +0,0 @@
7+
-this is line 1
8+
-this is line 2
9+
-this is line 3
10+
-this is line 4
11+
-this is line 5
12+
-this is line 6
13+
-this is line 7
14+
-this is line 8
15+
-this is line 9
16+
-this is line 10
17+
-this is line 11
18+
-this is line 12
19+
-this is line 13
20+
-this is line 14
21+
-this is line 15
22+
-this is line 16
23+
-this is line 17
24+
-this is line 18
25+
-this is line 19
26+
-this is line 20
27+
-this is line 21
28+
-this is line 22
29+
-this is line 23
30+
-this is line 24
31+
-this is line 25
32+
-this is line 26
33+
-this is line 27
34+
-this is line 28
35+
-this is line 29
36+
-this is line 30
37+
-this is line 31
38+
-this is line 32
39+
-this is line 33
40+
-this is line 34
41+
-this is line 35
42+
-this is line 36
43+
-this is line 37
44+
-this is line 38
45+
-this is line 39
46+
-this is line 40
47+
-this is line 41
48+
-this is line 42
49+
-this is line 43
50+
-this is line 44
51+
-this is line 45
52+
-this is line 46
53+
-this is line 47
54+
-this is line 48
55+
-this is line 49
56+
-this is line 50
57+
-this is line 51
58+
-this is line 52
59+
-this is line 53
60+
-this is line 54
61+
-this is line 55
62+
-this is line 56
63+
-this is line 57
64+
-this is line 58
65+
-this is line 59
66+
-this is line 60
67+
-this is line 61
68+
-this is line 62
69+
-this is line 63
70+
-this is line 64
71+
-this is line 65
72+
-this is line 66
73+
-this is line 67
74+
-this is line 68
75+
-this is line 69
76+
-this is line 70
77+
-this is line 71
78+
-this is line 72
79+
-this is line 73
80+
-this is line 74
81+
-this is line 75
82+
-this is line 76
83+
-this is line 77
84+
-this is line 78
85+
-this is line 79
86+
-this is line 80
87+
-this is line 81
88+
-this is line 82
89+
-this is line 83
90+
-this is line 84
91+
-this is line 85
92+
-this is line 86
93+
-this is line 87
94+
-this is line 88
95+
-this is line 89
96+
-this is line 90
97+
-this is line 91
98+
-this is line 92
99+
-this is line 93
100+
-this is line 94
101+
-this is line 95
102+
-this is line 96
103+
-this is line 97
104+
-this is line 98
105+
-this is line 99
106+
-this is line 100
107+
-this is line 101
108+
-this is line 102
109+
-this is line 103
110+
-this is line 104
111+
-this is line 105
112+
-this is line 106
113+
-this is line 107
114+
-this is line 108
115+
-this is line 109
116+
-this is line 110
117+
-this is line 111
118+
-this is line 112
119+
-this is line 113
120+
-this is line 114
121+
-this is line 115
122+
-this is line 116
123+
-this is line 117
124+
-this is line 118
125+
-this is line 119
126+
-this is line 120
127+
-this is line 121
128+
-this is line 122
129+
-this is line 123
130+
-this is line 124
131+
-this is line 125
132+
-this is line 126
133+
-this is line 127
134+
-this is line 128
135+
-this is line 129
136+
-this is line 130
137+
-this is line 131
138+
-this is line 132
139+
-this is line 133
140+
-this is line 134
141+
-this is line 135
142+
-this is line 136
143+
-this is line 137
144+
-this is line 138
145+
-this is line 139
146+
-this is line 140
147+
-this is line 141
148+
-this is line 142
149+
-this is line 143
150+
-this is line 144
151+
-this is line 145
152+
-this is line 146
153+
-this is line 147
154+
-this is line 148
155+
-this is line 149
156+
-this is line 150
157+
-this is line 151
158+
-this is line 152
159+
-this is line 153
160+
-this is line 154
161+
-this is line 155
162+
-this is line 156
163+
-this is line 157
164+
-this is line 158
165+
-this is line 159
166+
-this is line 160
167+
-this is line 161
168+
-this is line 162
169+
-this is line 163
170+
-this is line 164
171+
-this is line 165
172+
-this is line 166
173+
-this is line 167
174+
-this is line 168
175+
-this is line 169
176+
-this is line 170
177+
-this is line 171
178+
-this is line 172
179+
-this is line 173
180+
-this is line 174
181+
-this is line 175
182+
-this is line 176
183+
-this is line 177
184+
-this is line 178
185+
-this is line 179
186+
-this is line 180
187+
-this is line 181
188+
-this is line 182
189+
-this is line 183
190+
-this is line 184
191+
-this is line 185
192+
-this is line 186
193+
-this is line 187
194+
-this is line 188
195+
-this is line 189
196+
-this is line 190
197+
-this is line 191
198+
-this is line 192
199+
-this is line 193
200+
-this is line 194
201+
-this is line 195
202+
-this is line 196
203+
-this is line 197
204+
-this is line 198
205+
-this is line 199
206+
-this is line 200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
diff --git a/gitdiff/testdata/apply/file_text.src.src b/gitdiff/testdata/apply/file_text.src
2+
deleted file mode 100644
3+
index 3805ad4..0000000
4+
--- a/gitdiff/testdata/apply/file_text.src.src
5+
+++ /dev/null
6+
@@ -1,100 +0,0 @@
7+
-this is line 1
8+
-this is line 2
9+
-this is line 3
10+
-this is line 4
11+
-this is line 5
12+
-this is line 6
13+
-this is line 7
14+
-this is line 8
15+
-this is line 9
16+
-this is line 10
17+
-this is line 11
18+
-this is line 12
19+
-this is line 13
20+
-this is line 14
21+
-this is line 15
22+
-this is line 16
23+
-this is line 17
24+
-this is line 18
25+
-this is line 19
26+
-this is line 20
27+
-this is line 21
28+
-this is line 22
29+
-this is line 23
30+
-this is line 24
31+
-this is line 25
32+
-this is line 26
33+
-this is line 27
34+
-this is line 28
35+
-this is line 29
36+
-this is line 30
37+
-this is line 31
38+
-this is line 32
39+
-this is line 33
40+
-this is line 34
41+
-this is line 35
42+
-this is line 36
43+
-this is line 37
44+
-this is line 38
45+
-this is line 39
46+
-this is line 40
47+
-this is line 41
48+
-this is line 42
49+
-this is line 43
50+
-this is line 44
51+
-this is line 45
52+
-this is line 46
53+
-this is line 47
54+
-this is line 48
55+
-this is line 49
56+
-this is line 50
57+
-this is line 51
58+
-this is line 52
59+
-this is line 53
60+
-this is line 54
61+
-this is line 55
62+
-this is line 56
63+
-this is line 57
64+
-this is line 58
65+
-this is line 59
66+
-this is line 60
67+
-this is line 61
68+
-this is line 62
69+
-this is line 63
70+
-this is line 64
71+
-this is line 65
72+
-this is line 66
73+
-this is line 67
74+
-this is line 68
75+
-this is line 69
76+
-this is line 70
77+
-this is line 71
78+
-this is line 72
79+
-this is line 73
80+
-this is line 74
81+
-this is line 75
82+
-this is line 76
83+
-this is line 77
84+
-this is line 78
85+
-this is line 79
86+
-this is line 80
87+
-this is line 81
88+
-this is line 82
89+
-this is line 83
90+
-this is line 84
91+
-this is line 85
92+
-this is line 86
93+
-this is line 87
94+
-this is line 88
95+
-this is line 89
96+
-this is line 90
97+
-this is line 91
98+
-this is line 92
99+
-this is line 93
100+
-this is line 94
101+
-this is line 95
102+
-this is line 96
103+
-this is line 97
104+
-this is line 98
105+
-this is line 99
106+
-this is line 100

gitdiff/testdata/apply/text_file_modify.patch renamed to gitdiff/testdata/apply/file_text_modify.patch

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
diff --git a/gitdiff/testdata/apply/text_file_modify.src b/gitdiff/testdata/apply/text_file_modify.src
2-
--- a/gitdiff/testdata/apply/text_file_modify.src
3-
+++ b/gitdiff/testdata/apply/text_file_modify.src
1+
diff --git a/gitdiff/testdata/apply/file_text.src b/gitdiff/testdata/apply/file_text.src
2+
--- a/gitdiff/testdata/apply/file_text.src
3+
+++ b/gitdiff/testdata/apply/file_text.src
44
@@ -1,4 +1,4 @@
55
-this is line 1
66
+the first line is different

0 commit comments

Comments
 (0)