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