]> git.proxmox.com Git - libgit2.git/blob - tests/apply/fromfile.c
New upstream version 0.28.1+dfsg.1
[libgit2.git] / tests / apply / fromfile.c
1 #include "clar_libgit2.h"
2 #include "git2/sys/repository.h"
3
4 #include "apply.h"
5 #include "patch.h"
6 #include "patch_parse.h"
7 #include "repository.h"
8 #include "buf_text.h"
9
10 #include "../patch/patch_common.h"
11
12 static git_repository *repo = NULL;
13
14 void test_apply_fromfile__initialize(void)
15 {
16 repo = cl_git_sandbox_init("renames");
17 }
18
19 void test_apply_fromfile__cleanup(void)
20 {
21 cl_git_sandbox_cleanup();
22 }
23
24 static int apply_patchfile(
25 const char *old,
26 size_t old_len,
27 const char *new,
28 size_t new_len,
29 const char *patchfile,
30 const char *filename_expected,
31 unsigned int mode_expected)
32 {
33 git_patch *patch;
34 git_buf result = GIT_BUF_INIT;
35 git_buf patchbuf = GIT_BUF_INIT;
36 char *filename;
37 unsigned int mode;
38 int error;
39
40 cl_git_pass(git_patch_from_buffer(&patch, patchfile, strlen(patchfile), NULL));
41
42 error = git_apply__patch(&result, &filename, &mode, old, old_len, patch, NULL);
43
44 if (error == 0) {
45 cl_assert_equal_i(new_len, result.size);
46 if (new_len)
47 cl_assert(memcmp(new, result.ptr, new_len) == 0);
48
49 cl_assert_equal_s(filename_expected, filename);
50 cl_assert_equal_i(mode_expected, mode);
51 }
52
53 git__free(filename);
54 git_buf_dispose(&result);
55 git_buf_dispose(&patchbuf);
56 git_patch_free(patch);
57
58 return error;
59 }
60
61 static int validate_and_apply_patchfile(
62 const char *old,
63 size_t old_len,
64 const char *new,
65 size_t new_len,
66 const char *patchfile,
67 const git_diff_options *diff_opts,
68 const char *filename_expected,
69 unsigned int mode_expected)
70 {
71 git_patch *patch_fromdiff;
72 git_buf validated = GIT_BUF_INIT;
73 int error;
74
75 cl_git_pass(git_patch_from_buffers(&patch_fromdiff,
76 old, old_len, "file.txt",
77 new, new_len, "file.txt",
78 diff_opts));
79 cl_git_pass(git_patch_to_buf(&validated, patch_fromdiff));
80
81 cl_assert_equal_s(patchfile, validated.ptr);
82
83 error = apply_patchfile(old, old_len, new, new_len, patchfile, filename_expected, mode_expected);
84
85 git_buf_dispose(&validated);
86 git_patch_free(patch_fromdiff);
87
88 return error;
89 }
90
91 void test_apply_fromfile__change_middle(void)
92 {
93 cl_git_pass(validate_and_apply_patchfile(
94 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
95 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
96 PATCH_ORIGINAL_TO_CHANGE_MIDDLE, NULL,
97 "file.txt", 0100644));
98 }
99
100 void test_apply_fromfile__change_middle_nocontext(void)
101 {
102 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
103 diff_opts.context_lines = 0;
104
105 cl_git_pass(validate_and_apply_patchfile(
106 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
107 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
108 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT,
109 &diff_opts, "file.txt", 0100644));
110 }
111
112
113 void test_apply_fromfile__change_firstline(void)
114 {
115 cl_git_pass(validate_and_apply_patchfile(
116 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
117 FILE_CHANGE_FIRSTLINE, strlen(FILE_CHANGE_FIRSTLINE),
118 PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE, NULL,
119 "file.txt", 0100644));
120 }
121
122 void test_apply_fromfile__lastline(void)
123 {
124 cl_git_pass(validate_and_apply_patchfile(
125 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
126 FILE_CHANGE_LASTLINE, strlen(FILE_CHANGE_LASTLINE),
127 PATCH_ORIGINAL_TO_CHANGE_LASTLINE, NULL,
128 "file.txt", 0100644));
129 }
130
131 void test_apply_fromfile__change_middle_shrink(void)
132 {
133 cl_git_pass(validate_and_apply_patchfile(
134 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
135 FILE_CHANGE_MIDDLE_SHRINK, strlen(FILE_CHANGE_MIDDLE_SHRINK),
136 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_SHRINK, NULL,
137 "file.txt", 0100644));
138 }
139
140 void test_apply_fromfile__change_middle_shrink_nocontext(void)
141 {
142 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
143 diff_opts.context_lines = 0;
144
145 cl_git_pass(validate_and_apply_patchfile(
146 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
147 FILE_CHANGE_MIDDLE_SHRINK, strlen(FILE_CHANGE_MIDDLE_SHRINK),
148 PATCH_ORIGINAL_TO_MIDDLE_SHRINK_NOCONTEXT, &diff_opts,
149 "file.txt", 0100644));
150 }
151
152 void test_apply_fromfile__change_middle_grow(void)
153 {
154 cl_git_pass(validate_and_apply_patchfile(
155 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
156 FILE_CHANGE_MIDDLE_GROW, strlen(FILE_CHANGE_MIDDLE_GROW),
157 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_GROW, NULL,
158 "file.txt", 0100644));
159 }
160
161 void test_apply_fromfile__change_middle_grow_nocontext(void)
162 {
163 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
164 diff_opts.context_lines = 0;
165
166 cl_git_pass(validate_and_apply_patchfile(
167 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
168 FILE_CHANGE_MIDDLE_GROW, strlen(FILE_CHANGE_MIDDLE_GROW),
169 PATCH_ORIGINAL_TO_MIDDLE_GROW_NOCONTEXT, &diff_opts,
170 "file.txt", 0100644));
171 }
172
173 void test_apply_fromfile__prepend(void)
174 {
175 cl_git_pass(validate_and_apply_patchfile(
176 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
177 FILE_PREPEND, strlen(FILE_PREPEND),
178 PATCH_ORIGINAL_TO_PREPEND, NULL, "file.txt", 0100644));
179 }
180
181 void test_apply_fromfile__prepend_nocontext(void)
182 {
183 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
184 diff_opts.context_lines = 0;
185
186 cl_git_pass(validate_and_apply_patchfile(
187 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
188 FILE_PREPEND, strlen(FILE_PREPEND),
189 PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT, &diff_opts,
190 "file.txt", 0100644));
191 }
192
193 void test_apply_fromfile__append(void)
194 {
195 cl_git_pass(validate_and_apply_patchfile(
196 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
197 FILE_APPEND, strlen(FILE_APPEND),
198 PATCH_ORIGINAL_TO_APPEND, NULL, "file.txt", 0100644));
199 }
200
201 void test_apply_fromfile__append_nocontext(void)
202 {
203 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
204 diff_opts.context_lines = 0;
205
206 cl_git_pass(validate_and_apply_patchfile(
207 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
208 FILE_APPEND, strlen(FILE_APPEND),
209 PATCH_ORIGINAL_TO_APPEND_NOCONTEXT, &diff_opts,
210 "file.txt", 0100644));
211 }
212
213 void test_apply_fromfile__prepend_and_append(void)
214 {
215 cl_git_pass(validate_and_apply_patchfile(
216 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
217 FILE_PREPEND_AND_APPEND, strlen(FILE_PREPEND_AND_APPEND),
218 PATCH_ORIGINAL_TO_PREPEND_AND_APPEND, NULL,
219 "file.txt", 0100644));
220 }
221
222 void test_apply_fromfile__to_empty_file(void)
223 {
224 cl_git_pass(validate_and_apply_patchfile(
225 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
226 "", 0,
227 PATCH_ORIGINAL_TO_EMPTY_FILE, NULL, "file.txt", 0100644));
228 }
229
230 void test_apply_fromfile__from_empty_file(void)
231 {
232 cl_git_pass(validate_and_apply_patchfile(
233 "", 0,
234 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
235 PATCH_EMPTY_FILE_TO_ORIGINAL, NULL, "file.txt", 0100644));
236 }
237
238 void test_apply_fromfile__add(void)
239 {
240 cl_git_pass(validate_and_apply_patchfile(
241 NULL, 0,
242 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
243 PATCH_ADD_ORIGINAL, NULL, "file.txt", 0100644));
244 }
245
246 void test_apply_fromfile__delete(void)
247 {
248 cl_git_pass(validate_and_apply_patchfile(
249 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
250 NULL, 0,
251 PATCH_DELETE_ORIGINAL, NULL, NULL, 0));
252 }
253
254
255 void test_apply_fromfile__rename_exact(void)
256 {
257 cl_git_pass(apply_patchfile(
258 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
259 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
260 PATCH_RENAME_EXACT, "newfile.txt", 0100644));
261 }
262
263 void test_apply_fromfile__rename_similar(void)
264 {
265 cl_git_pass(apply_patchfile(
266 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
267 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
268 PATCH_RENAME_SIMILAR, "newfile.txt", 0100644));
269 }
270
271 void test_apply_fromfile__rename_similar_quotedname(void)
272 {
273 cl_git_pass(apply_patchfile(
274 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
275 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
276 PATCH_RENAME_SIMILAR_QUOTEDNAME, "foo\"bar.txt", 0100644));
277 }
278
279 void test_apply_fromfile__modechange(void)
280 {
281 cl_git_pass(apply_patchfile(
282 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
283 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
284 PATCH_MODECHANGE_UNCHANGED, "file.txt", 0100755));
285 }
286
287 void test_apply_fromfile__modechange_with_modification(void)
288 {
289 cl_git_pass(apply_patchfile(
290 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
291 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
292 PATCH_MODECHANGE_MODIFIED, "file.txt", 0100755));
293 }
294
295 void test_apply_fromfile__noisy(void)
296 {
297 cl_git_pass(apply_patchfile(
298 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
299 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
300 PATCH_NOISY, "file.txt", 0100644));
301 }
302
303 void test_apply_fromfile__noisy_nocontext(void)
304 {
305 cl_git_pass(apply_patchfile(
306 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
307 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
308 PATCH_NOISY_NOCONTEXT, "file.txt", 0100644));
309 }
310
311 void test_apply_fromfile__fail_truncated_1(void)
312 {
313 git_patch *patch;
314 cl_git_fail(git_patch_from_buffer(&patch, PATCH_TRUNCATED_1,
315 strlen(PATCH_TRUNCATED_1), NULL));
316 }
317
318 void test_apply_fromfile__fail_truncated_2(void)
319 {
320 git_patch *patch;
321 cl_git_fail(git_patch_from_buffer(&patch, PATCH_TRUNCATED_2,
322 strlen(PATCH_TRUNCATED_2), NULL));
323 }
324
325 void test_apply_fromfile__fail_truncated_3(void)
326 {
327 git_patch *patch;
328 cl_git_fail(git_patch_from_buffer(&patch, PATCH_TRUNCATED_3,
329 strlen(PATCH_TRUNCATED_3), NULL));
330 }
331
332 void test_apply_fromfile__fail_corrupt_githeader(void)
333 {
334 git_patch *patch;
335 cl_git_fail(git_patch_from_buffer(&patch, PATCH_CORRUPT_GIT_HEADER,
336 strlen(PATCH_CORRUPT_GIT_HEADER), NULL));
337 }
338
339 void test_apply_fromfile__empty_context(void)
340 {
341 cl_git_pass(apply_patchfile(
342 FILE_EMPTY_CONTEXT_ORIGINAL, strlen(FILE_EMPTY_CONTEXT_ORIGINAL),
343 FILE_EMPTY_CONTEXT_MODIFIED, strlen(FILE_EMPTY_CONTEXT_MODIFIED),
344 PATCH_EMPTY_CONTEXT,
345 "file.txt", 0100644));
346 }
347
348 void test_apply_fromfile__append_no_nl(void)
349 {
350 cl_git_pass(validate_and_apply_patchfile(
351 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
352 FILE_APPEND_NO_NL, strlen(FILE_APPEND_NO_NL),
353 PATCH_APPEND_NO_NL, NULL, "file.txt", 0100644));
354 }
355
356 void test_apply_fromfile__fail_missing_new_file(void)
357 {
358 git_patch *patch;
359 cl_git_fail(git_patch_from_buffer(&patch,
360 PATCH_CORRUPT_MISSING_NEW_FILE,
361 strlen(PATCH_CORRUPT_MISSING_NEW_FILE), NULL));
362 }
363
364 void test_apply_fromfile__fail_missing_old_file(void)
365 {
366 git_patch *patch;
367 cl_git_fail(git_patch_from_buffer(&patch,
368 PATCH_CORRUPT_MISSING_OLD_FILE,
369 strlen(PATCH_CORRUPT_MISSING_OLD_FILE), NULL));
370 }
371
372 void test_apply_fromfile__fail_no_changes(void)
373 {
374 git_patch *patch;
375 cl_git_fail(git_patch_from_buffer(&patch,
376 PATCH_CORRUPT_NO_CHANGES,
377 strlen(PATCH_CORRUPT_NO_CHANGES), NULL));
378 }
379
380 void test_apply_fromfile__fail_missing_hunk_header(void)
381 {
382 git_patch *patch;
383 cl_git_fail(git_patch_from_buffer(&patch,
384 PATCH_CORRUPT_MISSING_HUNK_HEADER,
385 strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER), NULL));
386 }
387
388 void test_apply_fromfile__fail_not_a_patch(void)
389 {
390 git_patch *patch;
391 cl_git_fail(git_patch_from_buffer(&patch, PATCH_NOT_A_PATCH,
392 strlen(PATCH_NOT_A_PATCH), NULL));
393 }
394
395 void test_apply_fromfile__binary_add(void)
396 {
397 cl_git_pass(apply_patchfile(
398 NULL, 0,
399 FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
400 PATCH_BINARY_ADD, "binary.bin", 0100644));
401 }
402
403 void test_apply_fromfile__binary_change_delta(void)
404 {
405 cl_git_pass(apply_patchfile(
406 FILE_BINARY_DELTA_ORIGINAL, FILE_BINARY_DELTA_ORIGINAL_LEN,
407 FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
408 PATCH_BINARY_DELTA, "binary.bin", 0100644));
409 }
410
411 void test_apply_fromfile__binary_change_literal(void)
412 {
413 cl_git_pass(apply_patchfile(
414 FILE_BINARY_LITERAL_ORIGINAL, FILE_BINARY_LITERAL_ORIGINAL_LEN,
415 FILE_BINARY_LITERAL_MODIFIED, FILE_BINARY_LITERAL_MODIFIED_LEN,
416 PATCH_BINARY_LITERAL, "binary.bin", 0100644));
417 }
418
419 void test_apply_fromfile__binary_delete(void)
420 {
421 cl_git_pass(apply_patchfile(
422 FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
423 NULL, 0,
424 PATCH_BINARY_DELETE, NULL, 0));
425 }
426
427 void test_apply_fromfile__binary_change_does_not_apply(void)
428 {
429 /* try to apply patch backwards, ensure it does not apply */
430 cl_git_fail(apply_patchfile(
431 FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
432 FILE_BINARY_DELTA_ORIGINAL, FILE_BINARY_DELTA_ORIGINAL_LEN,
433 PATCH_BINARY_DELTA, "binary.bin", 0100644));
434 }
435
436 void test_apply_fromfile__binary_change_must_be_reversible(void)
437 {
438 cl_git_fail(apply_patchfile(
439 FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
440 NULL, 0,
441 PATCH_BINARY_NOT_REVERSIBLE, NULL, 0));
442 }
443
444 void test_apply_fromfile__empty_file_not_allowed(void)
445 {
446 git_patch *patch;
447
448 cl_git_fail(git_patch_from_buffer(&patch, "", 0, NULL));
449 cl_git_fail(git_patch_from_buffer(&patch, NULL, 0, NULL));
450 }