1 #include "clar_libgit2.h"
2 #include "git2/sys/repository.h"
5 #include "repository.h"
7 #include "../patch/patch_common.h"
9 static git_repository
*repo
= NULL
;
10 static git_diff_options binary_opts
= GIT_DIFF_OPTIONS_INIT
;
12 void test_apply_fromdiff__initialize(void)
14 repo
= cl_git_sandbox_init("renames");
16 binary_opts
.flags
|= GIT_DIFF_SHOW_BINARY
;
19 void test_apply_fromdiff__cleanup(void)
21 cl_git_sandbox_cleanup();
24 static int apply_gitbuf(
29 const char *patch_expected
,
30 const git_diff_options
*diff_opts
)
33 git_buf result
= GIT_BUF_INIT
;
34 git_buf patchbuf
= GIT_BUF_INIT
;
39 cl_git_pass(git_patch_from_buffers(&patch
,
40 old
? old
->ptr
: NULL
, old
? old
->size
: 0,
42 new ? new->ptr
: NULL
, new ? new->size
: 0,
47 cl_git_pass(git_patch_to_buf(&patchbuf
, patch
));
48 cl_assert_equal_s(patch_expected
, patchbuf
.ptr
);
51 error
= git_apply__patch(&result
, &filename
, &mode
, old
? old
->ptr
: NULL
, old
? old
->size
: 0, patch
, NULL
);
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
);
58 else if (error
== 0) {
59 cl_assert_equal_s(new->ptr
, result
.ptr
);
60 cl_assert_equal_s(newname
? newname
: oldname
, filename
);
61 cl_assert_equal_i(0100644, mode
);
65 git_buf_dispose(&result
);
66 git_buf_dispose(&patchbuf
);
67 git_patch_free(patch
);
77 const char *patch_expected
,
78 const git_diff_options
*diff_opts
)
80 git_buf o
= GIT_BUF_INIT
, n
= GIT_BUF_INIT
,
81 *optr
= NULL
, *nptr
= NULL
;
95 return apply_gitbuf(optr
, oldname
, nptr
, newname
, patch_expected
, diff_opts
);
98 void test_apply_fromdiff__change_middle(void)
100 cl_git_pass(apply_buf(
101 FILE_ORIGINAL
, "file.txt",
102 FILE_CHANGE_MIDDLE
, "file.txt",
103 PATCH_ORIGINAL_TO_CHANGE_MIDDLE
, NULL
));
106 void test_apply_fromdiff__change_middle_nocontext(void)
108 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
109 diff_opts
.context_lines
= 0;
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
));
117 void test_apply_fromdiff__change_firstline(void)
119 cl_git_pass(apply_buf(
120 FILE_ORIGINAL
, "file.txt",
121 FILE_CHANGE_FIRSTLINE
, "file.txt",
122 PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE
, NULL
));
125 void test_apply_fromdiff__lastline(void)
127 cl_git_pass(apply_buf(
128 FILE_ORIGINAL
, "file.txt",
129 FILE_CHANGE_LASTLINE
, "file.txt",
130 PATCH_ORIGINAL_TO_CHANGE_LASTLINE
, NULL
));
133 void test_apply_fromdiff__change_middle_and_lastline_nocontext(void)
135 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
136 diff_opts
.context_lines
= 0;
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
));
144 void test_apply_fromdiff__prepend(void)
146 cl_git_pass(apply_buf(
147 FILE_ORIGINAL
, "file.txt",
148 FILE_PREPEND
, "file.txt",
149 PATCH_ORIGINAL_TO_PREPEND
, NULL
));
152 void test_apply_fromdiff__prepend_nocontext(void)
154 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
155 diff_opts
.context_lines
= 0;
157 cl_git_pass(apply_buf(
158 FILE_ORIGINAL
, "file.txt",
159 FILE_PREPEND
, "file.txt",
160 PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT
, &diff_opts
));
163 void test_apply_fromdiff__prepend_and_change(void)
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
));
171 void test_apply_fromdiff__prepend_and_change_nocontext(void)
173 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
174 diff_opts
.context_lines
= 0;
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
));
182 void test_apply_fromdiff__delete_and_change(void)
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
));
190 void test_apply_fromdiff__delete_and_change_nocontext(void)
192 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
193 diff_opts
.context_lines
= 0;
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
));
201 void test_apply_fromdiff__delete_firstline(void)
203 cl_git_pass(apply_buf(
204 FILE_ORIGINAL
, "file.txt",
205 FILE_DELETE_FIRSTLINE
, "file.txt",
206 PATCH_ORIGINAL_TO_DELETE_FIRSTLINE
, NULL
));
209 void test_apply_fromdiff__append(void)
211 cl_git_pass(apply_buf(
212 FILE_ORIGINAL
, "file.txt",
213 FILE_APPEND
, "file.txt",
214 PATCH_ORIGINAL_TO_APPEND
, NULL
));
217 void test_apply_fromdiff__append_nocontext(void)
219 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
220 diff_opts
.context_lines
= 0;
222 cl_git_pass(apply_buf(
223 FILE_ORIGINAL
, "file.txt",
224 FILE_APPEND
, "file.txt",
225 PATCH_ORIGINAL_TO_APPEND_NOCONTEXT
, &diff_opts
));
228 void test_apply_fromdiff__prepend_and_append(void)
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
));
236 void test_apply_fromdiff__to_empty_file(void)
238 cl_git_pass(apply_buf(
239 FILE_ORIGINAL
, "file.txt",
241 PATCH_ORIGINAL_TO_EMPTY_FILE
, NULL
));
244 void test_apply_fromdiff__from_empty_file(void)
246 cl_git_pass(apply_buf(
248 FILE_ORIGINAL
, "file.txt",
249 PATCH_EMPTY_FILE_TO_ORIGINAL
, NULL
));
252 void test_apply_fromdiff__add(void)
254 cl_git_pass(apply_buf(
256 FILE_ORIGINAL
, "file.txt",
257 PATCH_ADD_ORIGINAL
, NULL
));
260 void test_apply_fromdiff__delete(void)
262 cl_git_pass(apply_buf(
263 FILE_ORIGINAL
, "file.txt",
265 PATCH_DELETE_ORIGINAL
, NULL
));
268 void test_apply_fromdiff__no_change(void)
270 cl_git_pass(apply_buf(
271 FILE_ORIGINAL
, "file.txt",
272 FILE_ORIGINAL
, "file.txt",
276 void test_apply_fromdiff__binary_add(void)
278 git_buf newfile
= GIT_BUF_INIT
;
280 newfile
.ptr
= FILE_BINARY_DELTA_MODIFIED
;
281 newfile
.size
= FILE_BINARY_DELTA_MODIFIED_LEN
;
283 cl_git_pass(apply_gitbuf(
285 &newfile
, "binary.bin",
286 NULL
, &binary_opts
));
289 void test_apply_fromdiff__binary_no_change(void)
291 git_buf original
= GIT_BUF_INIT
;
293 original
.ptr
= FILE_BINARY_DELTA_ORIGINAL
;
294 original
.size
= FILE_BINARY_DELTA_ORIGINAL_LEN
;
296 cl_git_pass(apply_gitbuf(
297 &original
, "binary.bin",
298 &original
, "binary.bin",
302 void test_apply_fromdiff__binary_change_delta(void)
304 git_buf original
= GIT_BUF_INIT
, modified
= GIT_BUF_INIT
;
306 original
.ptr
= FILE_BINARY_DELTA_ORIGINAL
;
307 original
.size
= FILE_BINARY_DELTA_ORIGINAL_LEN
;
309 modified
.ptr
= FILE_BINARY_DELTA_MODIFIED
;
310 modified
.size
= FILE_BINARY_DELTA_MODIFIED_LEN
;
312 cl_git_pass(apply_gitbuf(
313 &original
, "binary.bin",
314 &modified
, "binary.bin",
315 NULL
, &binary_opts
));
318 void test_apply_fromdiff__binary_change_literal(void)
320 git_buf original
= GIT_BUF_INIT
, modified
= GIT_BUF_INIT
;
322 original
.ptr
= FILE_BINARY_LITERAL_ORIGINAL
;
323 original
.size
= FILE_BINARY_LITERAL_ORIGINAL_LEN
;
325 modified
.ptr
= FILE_BINARY_LITERAL_MODIFIED
;
326 modified
.size
= FILE_BINARY_LITERAL_MODIFIED_LEN
;
328 cl_git_pass(apply_gitbuf(
329 &original
, "binary.bin",
330 &modified
, "binary.bin",
331 NULL
, &binary_opts
));
334 void test_apply_fromdiff__binary_delete(void)
336 git_buf original
= GIT_BUF_INIT
;
338 original
.ptr
= FILE_BINARY_DELTA_MODIFIED
;
339 original
.size
= FILE_BINARY_DELTA_MODIFIED_LEN
;
341 cl_git_pass(apply_gitbuf(
342 &original
, "binary.bin",
344 NULL
, &binary_opts
));
347 void test_apply_fromdiff__patching_correctly_truncates_source(void)
349 git_buf original
= GIT_BUF_INIT
, patched
= GIT_BUF_INIT
;
354 cl_git_pass(git_patch_from_buffers(&patch
,
355 "foo\nbar", 7, "file.txt",
356 "foo\nfoo", 7, "file.txt", NULL
));
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.
366 cl_git_fail_with(GIT_EAPPLYFAIL
,
367 git_apply__patch(&patched
, &path
, &mode
,
368 "foo\nbar\n", 5, patch
, NULL
));
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
));
374 git_buf_dispose(&original
);
375 git_buf_dispose(&patched
);
376 git_patch_free(patch
);