]> git.proxmox.com Git - libgit2.git/blame - tests/apply/fromdiff.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / apply / fromdiff.c
CommitLineData
7cb904ba
ET
1#include "clar_libgit2.h"
2#include "git2/sys/repository.h"
3
4#include "apply.h"
5#include "repository.h"
7cb904ba 6
8bca8b9e 7#include "../patch/patch_common.h"
7cb904ba
ET
8
9static git_repository *repo = NULL;
3149ff6f 10static git_diff_options binary_opts = GIT_DIFF_OPTIONS_INIT;
7cb904ba
ET
11
12void test_apply_fromdiff__initialize(void)
13{
14 repo = cl_git_sandbox_init("renames");
3149ff6f
ET
15
16 binary_opts.flags |= GIT_DIFF_SHOW_BINARY;
7cb904ba
ET
17}
18
19void test_apply_fromdiff__cleanup(void)
20{
21 cl_git_sandbox_cleanup();
22}
23
3149ff6f 24static int apply_gitbuf(
e579e0f7 25 const git_str *old,
7cb904ba 26 const char *oldname,
e579e0f7 27 const git_str *new,
7cb904ba
ET
28 const char *newname,
29 const char *patch_expected,
30 const git_diff_options *diff_opts)
31{
32 git_patch *patch;
e579e0f7 33 git_str result = GIT_STR_INIT;
7cb904ba
ET
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_buffers(&patch,
3149ff6f
ET
40 old ? old->ptr : NULL, old ? old->size : 0,
41 oldname,
42 new ? new->ptr : NULL, new ? new->size : 0,
43 newname,
7cb904ba 44 diff_opts));
7cb904ba 45
3149ff6f
ET
46 if (patch_expected) {
47 cl_git_pass(git_patch_to_buf(&patchbuf, patch));
48 cl_assert_equal_s(patch_expected, patchbuf.ptr);
49 }
7cb904ba 50
ac3d33df 51 error = git_apply__patch(&result, &filename, &mode, old ? old->ptr : NULL, old ? old->size : 0, patch, NULL);
7cb904ba
ET
52
53 if (error == 0 && new == NULL) {
54 cl_assert_equal_i(0, result.size);
55 cl_assert_equal_p(NULL, filename);
56 cl_assert_equal_i(0, mode);
3149ff6f
ET
57 }
58 else if (error == 0) {
59 cl_assert_equal_s(new->ptr, result.ptr);
60 cl_assert_equal_s(newname ? newname : oldname, filename);
7cb904ba
ET
61 cl_assert_equal_i(0100644, mode);
62 }
63
64 git__free(filename);
e579e0f7 65 git_str_dispose(&result);
ac3d33df 66 git_buf_dispose(&patchbuf);
7cb904ba
ET
67 git_patch_free(patch);
68
69 return error;
70}
71
3149ff6f
ET
72static int apply_buf(
73 const char *old,
74 const char *oldname,
75 const char *new,
76 const char *newname,
77 const char *patch_expected,
78 const git_diff_options *diff_opts)
79{
e579e0f7 80 git_str o = GIT_STR_INIT, n = GIT_STR_INIT,
3149ff6f
ET
81 *optr = NULL, *nptr = NULL;
82
83 if (old) {
84 o.ptr = (char *)old;
85 o.size = strlen(old);
86 optr = &o;
87 }
88
89 if (new) {
90 n.ptr = (char *)new;
91 n.size = strlen(new);
92 nptr = &n;
93 }
94
95 return apply_gitbuf(optr, oldname, nptr, newname, patch_expected, diff_opts);
96}
97
7cb904ba
ET
98void test_apply_fromdiff__change_middle(void)
99{
100 cl_git_pass(apply_buf(
101 FILE_ORIGINAL, "file.txt",
102 FILE_CHANGE_MIDDLE, "file.txt",
103 PATCH_ORIGINAL_TO_CHANGE_MIDDLE, NULL));
104}
105
106void test_apply_fromdiff__change_middle_nocontext(void)
107{
108 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
109 diff_opts.context_lines = 0;
110
111 cl_git_pass(apply_buf(
112 FILE_ORIGINAL, "file.txt",
113 FILE_CHANGE_MIDDLE, "file.txt",
114 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT, &diff_opts));
115}
116
117void test_apply_fromdiff__change_firstline(void)
118{
119 cl_git_pass(apply_buf(
120 FILE_ORIGINAL, "file.txt",
121 FILE_CHANGE_FIRSTLINE, "file.txt",
122 PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE, NULL));
123}
124
125void test_apply_fromdiff__lastline(void)
126{
127 cl_git_pass(apply_buf(
128 FILE_ORIGINAL, "file.txt",
129 FILE_CHANGE_LASTLINE, "file.txt",
130 PATCH_ORIGINAL_TO_CHANGE_LASTLINE, NULL));
131}
132
22a2d3d5
UG
133void test_apply_fromdiff__change_middle_and_lastline_nocontext(void)
134{
135 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
136 diff_opts.context_lines = 0;
137
138 cl_git_pass(apply_buf(
139 FILE_ORIGINAL, "file.txt",
140 FILE_CHANGE_MIDDLE_AND_LASTLINE, "file.txt",
141 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_AND_LASTLINE_NOCONTEXT, &diff_opts));
142}
143
7cb904ba
ET
144void test_apply_fromdiff__prepend(void)
145{
146 cl_git_pass(apply_buf(
147 FILE_ORIGINAL, "file.txt",
148 FILE_PREPEND, "file.txt",
149 PATCH_ORIGINAL_TO_PREPEND, NULL));
150}
151
152void test_apply_fromdiff__prepend_nocontext(void)
153{
154 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
155 diff_opts.context_lines = 0;
156
157 cl_git_pass(apply_buf(
158 FILE_ORIGINAL, "file.txt",
159 FILE_PREPEND, "file.txt",
160 PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT, &diff_opts));
161}
162
ac3d33df
JK
163void test_apply_fromdiff__prepend_and_change(void)
164{
165 cl_git_pass(apply_buf(
166 FILE_ORIGINAL, "file.txt",
167 FILE_PREPEND_AND_CHANGE, "file.txt",
168 PATCH_ORIGINAL_TO_PREPEND_AND_CHANGE, NULL));
169}
170
171void test_apply_fromdiff__prepend_and_change_nocontext(void)
172{
173 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
174 diff_opts.context_lines = 0;
175
176 cl_git_pass(apply_buf(
177 FILE_ORIGINAL, "file.txt",
178 FILE_PREPEND_AND_CHANGE, "file.txt",
179 PATCH_ORIGINAL_TO_PREPEND_AND_CHANGE_NOCONTEXT, &diff_opts));
180}
181
182void test_apply_fromdiff__delete_and_change(void)
183{
184 cl_git_pass(apply_buf(
185 FILE_ORIGINAL, "file.txt",
186 FILE_DELETE_AND_CHANGE, "file.txt",
187 PATCH_ORIGINAL_TO_DELETE_AND_CHANGE, NULL));
188}
189
190void test_apply_fromdiff__delete_and_change_nocontext(void)
191{
192 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
193 diff_opts.context_lines = 0;
194
195 cl_git_pass(apply_buf(
196 FILE_ORIGINAL, "file.txt",
197 FILE_DELETE_AND_CHANGE, "file.txt",
198 PATCH_ORIGINAL_TO_DELETE_AND_CHANGE_NOCONTEXT, &diff_opts));
199}
200
201void test_apply_fromdiff__delete_firstline(void)
202{
203 cl_git_pass(apply_buf(
204 FILE_ORIGINAL, "file.txt",
205 FILE_DELETE_FIRSTLINE, "file.txt",
206 PATCH_ORIGINAL_TO_DELETE_FIRSTLINE, NULL));
207}
208
7cb904ba
ET
209void test_apply_fromdiff__append(void)
210{
211 cl_git_pass(apply_buf(
212 FILE_ORIGINAL, "file.txt",
213 FILE_APPEND, "file.txt",
214 PATCH_ORIGINAL_TO_APPEND, NULL));
215}
216
217void test_apply_fromdiff__append_nocontext(void)
218{
219 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
220 diff_opts.context_lines = 0;
221
222 cl_git_pass(apply_buf(
223 FILE_ORIGINAL, "file.txt",
224 FILE_APPEND, "file.txt",
225 PATCH_ORIGINAL_TO_APPEND_NOCONTEXT, &diff_opts));
226}
227
228void test_apply_fromdiff__prepend_and_append(void)
229{
230 cl_git_pass(apply_buf(
231 FILE_ORIGINAL, "file.txt",
232 FILE_PREPEND_AND_APPEND, "file.txt",
233 PATCH_ORIGINAL_TO_PREPEND_AND_APPEND, NULL));
234}
235
236void test_apply_fromdiff__to_empty_file(void)
237{
238 cl_git_pass(apply_buf(
239 FILE_ORIGINAL, "file.txt",
240 "", NULL,
241 PATCH_ORIGINAL_TO_EMPTY_FILE, NULL));
242}
243
244void test_apply_fromdiff__from_empty_file(void)
245{
246 cl_git_pass(apply_buf(
247 "", NULL,
248 FILE_ORIGINAL, "file.txt",
249 PATCH_EMPTY_FILE_TO_ORIGINAL, NULL));
250}
251
252void test_apply_fromdiff__add(void)
253{
254 cl_git_pass(apply_buf(
255 NULL, NULL,
256 FILE_ORIGINAL, "file.txt",
257 PATCH_ADD_ORIGINAL, NULL));
258}
259
260void test_apply_fromdiff__delete(void)
261{
262 cl_git_pass(apply_buf(
263 FILE_ORIGINAL, "file.txt",
264 NULL, NULL,
265 PATCH_DELETE_ORIGINAL, NULL));
266}
0004386f
ET
267
268void test_apply_fromdiff__no_change(void)
269{
270 cl_git_pass(apply_buf(
271 FILE_ORIGINAL, "file.txt",
272 FILE_ORIGINAL, "file.txt",
273 "", NULL));
274}
3149ff6f
ET
275
276void test_apply_fromdiff__binary_add(void)
277{
e579e0f7 278 git_str newfile = GIT_STR_INIT;
3149ff6f
ET
279
280 newfile.ptr = FILE_BINARY_DELTA_MODIFIED;
281 newfile.size = FILE_BINARY_DELTA_MODIFIED_LEN;
282
283 cl_git_pass(apply_gitbuf(
284 NULL, NULL,
285 &newfile, "binary.bin",
286 NULL, &binary_opts));
287}
288
289void test_apply_fromdiff__binary_no_change(void)
290{
e579e0f7 291 git_str original = GIT_STR_INIT;
3149ff6f
ET
292
293 original.ptr = FILE_BINARY_DELTA_ORIGINAL;
294 original.size = FILE_BINARY_DELTA_ORIGINAL_LEN;
295
296 cl_git_pass(apply_gitbuf(
297 &original, "binary.bin",
298 &original, "binary.bin",
299 "", &binary_opts));
300}
301
302void test_apply_fromdiff__binary_change_delta(void)
303{
e579e0f7 304 git_str original = GIT_STR_INIT, modified = GIT_STR_INIT;
3149ff6f
ET
305
306 original.ptr = FILE_BINARY_DELTA_ORIGINAL;
307 original.size = FILE_BINARY_DELTA_ORIGINAL_LEN;
308
309 modified.ptr = FILE_BINARY_DELTA_MODIFIED;
310 modified.size = FILE_BINARY_DELTA_MODIFIED_LEN;
311
312 cl_git_pass(apply_gitbuf(
313 &original, "binary.bin",
314 &modified, "binary.bin",
315 NULL, &binary_opts));
316}
317
318void test_apply_fromdiff__binary_change_literal(void)
319{
e579e0f7 320 git_str original = GIT_STR_INIT, modified = GIT_STR_INIT;
3149ff6f
ET
321
322 original.ptr = FILE_BINARY_LITERAL_ORIGINAL;
323 original.size = FILE_BINARY_LITERAL_ORIGINAL_LEN;
324
325 modified.ptr = FILE_BINARY_LITERAL_MODIFIED;
326 modified.size = FILE_BINARY_LITERAL_MODIFIED_LEN;
327
328 cl_git_pass(apply_gitbuf(
329 &original, "binary.bin",
330 &modified, "binary.bin",
331 NULL, &binary_opts));
332}
333
334void test_apply_fromdiff__binary_delete(void)
335{
e579e0f7 336 git_str original = GIT_STR_INIT;
3149ff6f
ET
337
338 original.ptr = FILE_BINARY_DELTA_MODIFIED;
339 original.size = FILE_BINARY_DELTA_MODIFIED_LEN;
340
341 cl_git_pass(apply_gitbuf(
342 &original, "binary.bin",
343 NULL, NULL,
344 NULL, &binary_opts));
345}
22a2d3d5
UG
346
347void test_apply_fromdiff__patching_correctly_truncates_source(void)
348{
e579e0f7 349 git_str original = GIT_STR_INIT, patched = GIT_STR_INIT;
22a2d3d5
UG
350 git_patch *patch;
351 unsigned int mode;
352 char *path;
353
354 cl_git_pass(git_patch_from_buffers(&patch,
355 "foo\nbar", 7, "file.txt",
356 "foo\nfoo", 7, "file.txt", NULL));
357
358 /*
359 * Previously, we would fail to correctly truncate the source buffer if
360 * the source has more than one line and ends with a non-newline
361 * character. In the following call, we thus truncate the source string
362 * in the middle of the second line. Without the bug fixed, we would
363 * successfully apply the patch to the source and return success. With
364 * the overflow being fixed, we should return an error.
365 */
366 cl_git_fail_with(GIT_EAPPLYFAIL,
367 git_apply__patch(&patched, &path, &mode,
368 "foo\nbar\n", 5, patch, NULL));
369
370 /* Verify that the patch succeeds if we do not truncate */
371 cl_git_pass(git_apply__patch(&patched, &path, &mode,
372 "foo\nbar\n", 7, patch, NULL));
373
e579e0f7
MB
374 git_str_dispose(&original);
375 git_str_dispose(&patched);
22a2d3d5
UG
376 git_patch_free(patch);
377 git__free(path);
378}