]>
Commit | Line | Data |
---|---|---|
020cda99 | 1 | #include "clar_libgit2.h" |
bebdbcd4 | 2 | #include "checkout_helpers.h" |
020cda99 | 3 | |
4 | #include "git2/checkout.h" | |
22a2d3d5 | 5 | #include "futils.h" |
020cda99 | 6 | #include "repository.h" |
7c2a2172 | 7 | #include "remote.h" |
ac3d33df | 8 | #include "repo/repo_helpers.h" |
020cda99 | 9 | |
10 | static git_repository *g_repo; | |
e579e0f7 | 11 | static git_str g_global_path = GIT_STR_INIT; |
020cda99 | 12 | |
020cda99 | 13 | void test_checkout_index__initialize(void) |
14 | { | |
15 | git_tree *tree; | |
16 | ||
020cda99 | 17 | g_repo = cl_git_sandbox_init("testrepo"); |
18 | ||
19 | cl_git_pass(git_repository_head_tree(&tree, g_repo)); | |
20 | ||
21 | reset_index_to_treeish((git_object *)tree); | |
22 | git_tree_free(tree); | |
23 | ||
24 | cl_git_rewritefile( | |
25 | "./testrepo/.gitattributes", | |
26 | "* text eol=lf\n"); | |
ac3d33df JK |
27 | |
28 | git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, | |
29 | &g_global_path); | |
020cda99 | 30 | } |
31 | ||
32 | void test_checkout_index__cleanup(void) | |
33 | { | |
ac3d33df JK |
34 | git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, |
35 | g_global_path.ptr); | |
e579e0f7 | 36 | git_str_dispose(&g_global_path); |
ac3d33df | 37 | |
020cda99 | 38 | cl_git_sandbox_cleanup(); |
f3f4c6b5 | 39 | |
ac3d33df JK |
40 | /* try to remove directories created by tests */ |
41 | cl_fixture_cleanup("alternative"); | |
42 | cl_fixture_cleanup("symlink"); | |
43 | cl_fixture_cleanup("symlink.git"); | |
44 | cl_fixture_cleanup("tmp_global_path"); | |
020cda99 | 45 | } |
46 | ||
020cda99 | 47 | void test_checkout_index__cannot_checkout_a_bare_repository(void) |
48 | { | |
ac3d33df | 49 | cl_git_sandbox_cleanup(); |
020cda99 | 50 | g_repo = cl_git_sandbox_init("testrepo.git"); |
51 | ||
bbe6dbec | 52 | cl_git_fail(git_checkout_index(g_repo, NULL, NULL)); |
020cda99 | 53 | } |
54 | ||
c214fa1c | 55 | void test_checkout_index__can_create_missing_files(void) |
020cda99 | 56 | { |
6affd71f | 57 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
7e5c8a5b | 58 | |
e579e0f7 MB |
59 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); |
60 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); | |
61 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); | |
020cda99 | 62 | |
96b82b11 | 63 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
cf208031 | 64 | |
7e5c8a5b | 65 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 66 | |
050ab995 RB |
67 | check_file_contents("./testrepo/README", "hey there\n"); |
68 | check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); | |
69 | check_file_contents("./testrepo/new.txt", "my new file\n"); | |
020cda99 | 70 | } |
71 | ||
c214fa1c | 72 | void test_checkout_index__can_remove_untracked_files(void) |
73 | { | |
6affd71f | 74 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
7e5c8a5b | 75 | |
ac2fba0e | 76 | git_futils_mkdir("./testrepo/dir/subdir/subsubdir", 0755, GIT_MKDIR_PATH); |
c214fa1c | 77 | cl_git_mkfile("./testrepo/dir/one", "one\n"); |
78 | cl_git_mkfile("./testrepo/dir/subdir/two", "two\n"); | |
79 | ||
e579e0f7 | 80 | cl_assert_equal_i(true, git_fs_path_isdir("./testrepo/dir/subdir/subsubdir")); |
c214fa1c | 81 | |
7e5c8a5b | 82 | opts.checkout_strategy = |
96b82b11 ET |
83 | GIT_CHECKOUT_SAFE | |
84 | GIT_CHECKOUT_RECREATE_MISSING | | |
85 | GIT_CHECKOUT_REMOVE_UNTRACKED; | |
cf208031 | 86 | |
7e5c8a5b | 87 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
c214fa1c | 88 | |
e579e0f7 | 89 | cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/dir")); |
c214fa1c | 90 | } |
91 | ||
22a2d3d5 UG |
92 | void test_checkout_index__can_disable_pathspec_match(void) |
93 | { | |
94 | char *files_to_checkout[] = { "test10.txt", "test11.txt"}; | |
95 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; | |
96 | git_object *objects; | |
97 | git_index *index; | |
98 | ||
99 | /* reset to beginning of history (i.e. just a README file) */ | |
100 | opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED; | |
101 | ||
102 | cl_git_pass(git_revparse_single(&objects, g_repo, "8496071c1b46c854b31185ea97743be6a8774479")); | |
103 | cl_git_pass(git_checkout_tree(g_repo, objects, &opts)); | |
104 | cl_git_pass(git_repository_set_head_detached(g_repo, git_object_id(objects))); | |
105 | git_object_free(objects); | |
106 | ||
107 | cl_git_pass(git_repository_index(&index, g_repo)); | |
108 | ||
109 | /* We create 4 files and commit them */ | |
110 | cl_git_mkfile("testrepo/test9.txt", "original\n"); | |
111 | cl_git_mkfile("testrepo/test10.txt", "original\n"); | |
112 | cl_git_mkfile("testrepo/test11.txt", "original\n"); | |
113 | cl_git_mkfile("testrepo/test12.txt", "original\n"); | |
114 | ||
115 | cl_git_pass(git_index_add_bypath(index, "test9.txt")); | |
116 | cl_git_pass(git_index_add_bypath(index, "test10.txt")); | |
117 | cl_git_pass(git_index_add_bypath(index, "test11.txt")); | |
118 | cl_git_pass(git_index_add_bypath(index, "test12.txt")); | |
119 | cl_git_pass(git_index_write(index)); | |
120 | ||
121 | cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit our test files"); | |
122 | ||
123 | /* We modify the content of all 4 of our files */ | |
124 | cl_git_rewritefile("testrepo/test9.txt", "modified\n"); | |
125 | cl_git_rewritefile("testrepo/test10.txt", "modified\n"); | |
126 | cl_git_rewritefile("testrepo/test11.txt", "modified\n"); | |
127 | cl_git_rewritefile("testrepo/test12.txt", "modified\n"); | |
128 | ||
129 | /* We checkout only test10.txt and test11.txt */ | |
130 | opts.checkout_strategy = | |
131 | GIT_CHECKOUT_FORCE | | |
132 | GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH; | |
133 | opts.paths.strings = files_to_checkout; | |
134 | opts.paths.count = ARRAY_SIZE(files_to_checkout); | |
135 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); | |
136 | ||
137 | /* The only files that have been reverted to their original content | |
138 | should be test10.txt and test11.txt */ | |
139 | check_file_contents("testrepo/test9.txt", "modified\n"); | |
140 | check_file_contents("testrepo/test10.txt", "original\n"); | |
141 | check_file_contents("testrepo/test11.txt", "original\n"); | |
142 | check_file_contents("testrepo/test12.txt", "modified\n"); | |
143 | ||
144 | git_index_free(index); | |
145 | } | |
146 | ||
020cda99 | 147 | void test_checkout_index__honor_the_specified_pathspecs(void) |
148 | { | |
6affd71f | 149 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
020cda99 | 150 | char *entries[] = { "*.txt" }; |
151 | ||
7e5c8a5b RB |
152 | opts.paths.strings = entries; |
153 | opts.paths.count = 1; | |
020cda99 | 154 | |
e579e0f7 MB |
155 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); |
156 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); | |
157 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); | |
020cda99 | 158 | |
96b82b11 | 159 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
cf208031 | 160 | |
7e5c8a5b | 161 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 162 | |
e579e0f7 | 163 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); |
050ab995 RB |
164 | check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); |
165 | check_file_contents("./testrepo/new.txt", "my new file\n"); | |
020cda99 | 166 | } |
167 | ||
020cda99 | 168 | void test_checkout_index__honor_the_gitattributes_directives(void) |
169 | { | |
6affd71f | 170 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
020cda99 | 171 | const char *attributes = |
172 | "branch_file.txt text eol=crlf\n" | |
173 | "new.txt text eol=lf\n"; | |
174 | ||
175 | cl_git_mkfile("./testrepo/.gitattributes", attributes); | |
1323c6d1 | 176 | cl_repo_set_bool(g_repo, "core.autocrlf", false); |
020cda99 | 177 | |
96b82b11 | 178 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
cf208031 | 179 | |
7e5c8a5b | 180 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 181 | |
050ab995 RB |
182 | check_file_contents("./testrepo/README", "hey there\n"); |
183 | check_file_contents("./testrepo/new.txt", "my new file\n"); | |
184 | check_file_contents("./testrepo/branch_file.txt", "hi\r\nbye!\r\n"); | |
020cda99 | 185 | } |
186 | ||
187 | void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void) | |
188 | { | |
189 | #ifdef GIT_WIN32 | |
6affd71f | 190 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
020cda99 | 191 | const char *expected_readme_text = "hey there\r\n"; |
192 | ||
193 | cl_git_pass(p_unlink("./testrepo/.gitattributes")); | |
1323c6d1 | 194 | cl_repo_set_bool(g_repo, "core.autocrlf", true); |
020cda99 | 195 | |
96b82b11 | 196 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
cf208031 | 197 | |
7e5c8a5b | 198 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 199 | |
050ab995 | 200 | check_file_contents("./testrepo/README", expected_readme_text); |
020cda99 | 201 | #endif |
202 | } | |
203 | ||
ac3d33df | 204 | static void populate_symlink_workdir(void) |
7c2a2172 | 205 | { |
e579e0f7 | 206 | git_str path = GIT_STR_INIT; |
7c2a2172 L |
207 | git_repository *repo; |
208 | git_remote *origin; | |
209 | git_object *target; | |
7c2a2172 L |
210 | |
211 | const char *url = git_repository_path(g_repo); | |
212 | ||
e579e0f7 | 213 | cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), "symlink.git")); |
22a2d3d5 | 214 | cl_git_pass(git_repository_init(&repo, path.ptr, true)); |
7c2a2172 L |
215 | cl_git_pass(git_repository_set_workdir(repo, "symlink", 1)); |
216 | ||
ac3d33df JK |
217 | /* Delete the `origin` repo (if it exists) so we can recreate it. */ |
218 | git_remote_delete(repo, GIT_REMOTE_ORIGIN); | |
219 | ||
7c2a2172 | 220 | cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); |
8f0104ec | 221 | cl_git_pass(git_remote_fetch(origin, NULL, NULL, NULL)); |
7c2a2172 L |
222 | git_remote_free(origin); |
223 | ||
224 | cl_git_pass(git_revparse_single(&target, repo, "remotes/origin/master")); | |
225 | cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); | |
22a2d3d5 | 226 | |
7c2a2172 L |
227 | git_object_free(target); |
228 | git_repository_free(repo); | |
e579e0f7 | 229 | git_str_dispose(&path); |
ac3d33df JK |
230 | } |
231 | ||
232 | void test_checkout_index__honor_coresymlinks_default_true(void) | |
233 | { | |
234 | char link_data[GIT_PATH_MAX]; | |
235 | int link_size = GIT_PATH_MAX; | |
236 | ||
237 | cl_must_pass(p_mkdir("symlink", 0777)); | |
238 | ||
e579e0f7 | 239 | if (!git_fs_path_supports_symlinks("symlink/test")) |
ac3d33df | 240 | cl_skip(); |
7c2a2172 L |
241 | |
242 | #ifdef GIT_WIN32 | |
ac3d33df JK |
243 | /* |
244 | * Windows explicitly requires the global configuration to have | |
245 | * core.symlinks=true in addition to actual filesystem support. | |
246 | */ | |
247 | create_tmp_global_config("tmp_global_path", "core.symlinks", "true"); | |
248 | #endif | |
249 | ||
250 | populate_symlink_workdir(); | |
251 | ||
252 | link_size = p_readlink("./symlink/link_to_new.txt", link_data, link_size); | |
253 | cl_assert(link_size >= 0); | |
254 | ||
255 | link_data[link_size] = '\0'; | |
256 | cl_assert_equal_i(link_size, strlen("new.txt")); | |
257 | cl_assert_equal_s(link_data, "new.txt"); | |
258 | check_file_contents("./symlink/link_to_new.txt", "my new file\n"); | |
259 | } | |
260 | ||
261 | void test_checkout_index__honor_coresymlinks_default_false(void) | |
262 | { | |
263 | cl_must_pass(p_mkdir("symlink", 0777)); | |
264 | ||
265 | #ifndef GIT_WIN32 | |
266 | /* | |
267 | * This test is largely for Windows platforms to ensure that | |
268 | * we respect an unset core.symlinks even when the platform | |
269 | * supports symlinks. Bail entirely on POSIX platforms that | |
270 | * do support symlinks. | |
271 | */ | |
e579e0f7 | 272 | if (git_fs_path_supports_symlinks("symlink/test")) |
ac3d33df JK |
273 | cl_skip(); |
274 | #endif | |
275 | ||
276 | populate_symlink_workdir(); | |
7c2a2172 | 277 | check_file_contents("./symlink/link_to_new.txt", "new.txt"); |
ac3d33df JK |
278 | } |
279 | ||
280 | void test_checkout_index__coresymlinks_set_to_true_fails_when_unsupported(void) | |
281 | { | |
282 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; | |
283 | ||
e579e0f7 | 284 | if (git_fs_path_supports_symlinks("testrepo/test")) { |
ac3d33df | 285 | cl_skip(); |
7c2a2172 | 286 | } |
7c2a2172 | 287 | |
ac3d33df JK |
288 | cl_repo_set_bool(g_repo, "core.symlinks", true); |
289 | ||
290 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; | |
291 | cl_git_fail(git_checkout_index(g_repo, NULL, &opts)); | |
7c2a2172 L |
292 | } |
293 | ||
020cda99 | 294 | void test_checkout_index__honor_coresymlinks_setting_set_to_true(void) |
295 | { | |
6affd71f | 296 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
ac3d33df JK |
297 | char link_data[GIT_PATH_MAX]; |
298 | size_t link_size = GIT_PATH_MAX; | |
299 | ||
e579e0f7 | 300 | if (!git_fs_path_supports_symlinks("testrepo/test")) { |
ac3d33df JK |
301 | cl_skip(); |
302 | } | |
7e5c8a5b | 303 | |
1323c6d1 | 304 | cl_repo_set_bool(g_repo, "core.symlinks", true); |
020cda99 | 305 | |
96b82b11 | 306 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
cf208031 | 307 | |
7e5c8a5b | 308 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 309 | |
ac3d33df JK |
310 | link_size = p_readlink("./testrepo/link_to_new.txt", link_data, link_size); |
311 | link_data[link_size] = '\0'; | |
312 | cl_assert_equal_i(link_size, strlen("new.txt")); | |
313 | cl_assert_equal_s(link_data, "new.txt"); | |
314 | check_file_contents("./testrepo/link_to_new.txt", "my new file\n"); | |
020cda99 | 315 | } |
316 | ||
317 | void test_checkout_index__honor_coresymlinks_setting_set_to_false(void) | |
318 | { | |
6affd71f | 319 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
7e5c8a5b | 320 | |
1323c6d1 | 321 | cl_repo_set_bool(g_repo, "core.symlinks", false); |
020cda99 | 322 | |
96b82b11 | 323 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
cf208031 | 324 | |
7e5c8a5b | 325 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 326 | |
050ab995 | 327 | check_file_contents("./testrepo/link_to_new.txt", "new.txt"); |
020cda99 | 328 | } |
329 | ||
c214fa1c | 330 | void test_checkout_index__donot_overwrite_modified_file_by_default(void) |
020cda99 | 331 | { |
6affd71f | 332 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
7e5c8a5b | 333 | |
020cda99 | 334 | cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!"); |
020cda99 | 335 | |
ad9a921b RB |
336 | /* set this up to not return an error code on conflicts, but it |
337 | * still will not have permission to overwrite anything... | |
338 | */ | |
7e5c8a5b | 339 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_ALLOW_CONFLICTS; |
ad9a921b | 340 | |
7e5c8a5b | 341 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 342 | |
050ab995 | 343 | check_file_contents("./testrepo/new.txt", "This isn't what's stored!"); |
020cda99 | 344 | } |
345 | ||
c214fa1c | 346 | void test_checkout_index__can_overwrite_modified_file(void) |
020cda99 | 347 | { |
6affd71f | 348 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
7e5c8a5b | 349 | |
020cda99 | 350 | cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!"); |
020cda99 | 351 | |
7e5c8a5b | 352 | opts.checkout_strategy = GIT_CHECKOUT_FORCE; |
ad9a921b | 353 | |
7e5c8a5b | 354 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 355 | |
050ab995 | 356 | check_file_contents("./testrepo/new.txt", "my new file\n"); |
020cda99 | 357 | } |
358 | ||
359 | void test_checkout_index__options_disable_filters(void) | |
360 | { | |
6affd71f | 361 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
7e5c8a5b | 362 | |
020cda99 | 363 | cl_git_mkfile("./testrepo/.gitattributes", "*.txt text eol=crlf\n"); |
364 | ||
96b82b11 | 365 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
7e5c8a5b | 366 | opts.disable_filters = false; |
cf208031 | 367 | |
7e5c8a5b | 368 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 369 | |
050ab995 | 370 | check_file_contents("./testrepo/new.txt", "my new file\r\n"); |
020cda99 | 371 | |
372 | p_unlink("./testrepo/new.txt"); | |
373 | ||
7e5c8a5b RB |
374 | opts.disable_filters = true; |
375 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); | |
020cda99 | 376 | |
050ab995 | 377 | check_file_contents("./testrepo/new.txt", "my new file\n"); |
020cda99 | 378 | } |
379 | ||
380 | void test_checkout_index__options_dir_modes(void) | |
381 | { | |
6affd71f | 382 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
020cda99 | 383 | struct stat st; |
384 | git_oid oid; | |
385 | git_commit *commit; | |
780f3e54 | 386 | mode_t um; |
020cda99 | 387 | |
b8f9059d RB |
388 | if (!cl_is_chmod_supported()) |
389 | return; | |
390 | ||
2508cc66 | 391 | cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir")); |
020cda99 | 392 | cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); |
393 | ||
394 | reset_index_to_treeish((git_object *)commit); | |
395 | ||
96b82b11 | 396 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
7e5c8a5b | 397 | opts.dir_mode = 0701; |
cf208031 | 398 | |
7e5c8a5b | 399 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 400 | |
780f3e54 RB |
401 | /* umask will influence actual directory creation mode */ |
402 | (void)p_umask(um = p_umask(022)); | |
403 | ||
020cda99 | 404 | cl_git_pass(p_stat("./testrepo/a", &st)); |
26917fd9 FR |
405 | /* Haiku & Hurd use other mode bits, so we must mask them out */ |
406 | cl_assert_equal_i_fmt(st.st_mode & (S_IFMT | 07777), (GIT_FILEMODE_TREE | 0701) & ~um, "%07o"); | |
020cda99 | 407 | |
408 | /* File-mode test, since we're on the 'dir' branch */ | |
409 | cl_git_pass(p_stat("./testrepo/a/b.txt", &st)); | |
26917fd9 | 410 | cl_assert_equal_i_fmt(st.st_mode & (S_IFMT | 07777), GIT_FILEMODE_BLOB_EXECUTABLE & ~um, "%07o"); |
020cda99 | 411 | |
412 | git_commit_free(commit); | |
020cda99 | 413 | } |
414 | ||
415 | void test_checkout_index__options_override_file_modes(void) | |
416 | { | |
6affd71f | 417 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
020cda99 | 418 | struct stat st; |
419 | ||
b8f9059d RB |
420 | if (!cl_is_chmod_supported()) |
421 | return; | |
422 | ||
96b82b11 | 423 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
7e5c8a5b | 424 | opts.file_mode = 0700; |
020cda99 | 425 | |
7e5c8a5b | 426 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 427 | |
428 | cl_git_pass(p_stat("./testrepo/new.txt", &st)); | |
c97d407d | 429 | cl_assert_equal_i_fmt(st.st_mode & GIT_MODE_PERMS_MASK, 0700, "%07o"); |
020cda99 | 430 | } |
431 | ||
432 | void test_checkout_index__options_open_flags(void) | |
433 | { | |
6affd71f | 434 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
7e5c8a5b | 435 | |
020cda99 | 436 | cl_git_mkfile("./testrepo/new.txt", "hi\n"); |
437 | ||
e74340b0 ET |
438 | opts.checkout_strategy = |
439 | GIT_CHECKOUT_FORCE | GIT_CHECKOUT_DONT_REMOVE_EXISTING; | |
7e5c8a5b | 440 | opts.file_open_flags = O_CREAT | O_RDWR | O_APPEND; |
c214fa1c | 441 | |
7e5c8a5b | 442 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
020cda99 | 443 | |
050ab995 | 444 | check_file_contents("./testrepo/new.txt", "hi\nmy new file\n"); |
020cda99 | 445 | } |
9e592583 | 446 | |
cf208031 | 447 | struct notify_data { |
9e592583 | 448 | const char *file; |
449 | const char *sha; | |
450 | }; | |
451 | ||
7e5c8a5b RB |
452 | static int test_checkout_notify_cb( |
453 | git_checkout_notify_t why, | |
454 | const char *path, | |
455 | const git_diff_file *baseline, | |
456 | const git_diff_file *target, | |
457 | const git_diff_file *workdir, | |
9e592583 | 458 | void *payload) |
459 | { | |
cf208031 | 460 | struct notify_data *expectations = (struct notify_data *)payload; |
9e592583 | 461 | |
7e5c8a5b | 462 | GIT_UNUSED(workdir); |
9e592583 | 463 | |
7e5c8a5b RB |
464 | cl_assert_equal_i(GIT_CHECKOUT_NOTIFY_CONFLICT, why); |
465 | cl_assert_equal_s(expectations->file, path); | |
9950bb4e CMN |
466 | cl_assert_equal_i(0, git_oid_streq(&baseline->id, expectations->sha)); |
467 | cl_assert_equal_i(0, git_oid_streq(&target->id, expectations->sha)); | |
9e592583 | 468 | |
469 | return 0; | |
470 | } | |
471 | ||
472 | void test_checkout_index__can_notify_of_skipped_files(void) | |
473 | { | |
6affd71f | 474 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
cf208031 | 475 | struct notify_data data; |
9e592583 | 476 | |
477 | cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!"); | |
478 | ||
479 | /* | |
480 | * $ git ls-tree HEAD | |
481 | * 100644 blob a8233120f6ad708f843d861ce2b7228ec4e3dec6 README | |
482 | * 100644 blob 3697d64be941a53d4ae8f6a271e4e3fa56b022cc branch_file.txt | |
483 | * 100644 blob a71586c1dfe8a71c6cbf6c129f404c5642ff31bd new.txt | |
484 | */ | |
485 | data.file = "new.txt"; | |
486 | data.sha = "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd"; | |
487 | ||
96b82b11 ET |
488 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | |
489 | GIT_CHECKOUT_RECREATE_MISSING | | |
490 | GIT_CHECKOUT_ALLOW_CONFLICTS; | |
7e5c8a5b RB |
491 | opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT; |
492 | opts.notify_cb = test_checkout_notify_cb; | |
493 | opts.notify_payload = &data; | |
9e592583 | 494 | |
7e5c8a5b | 495 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
9e592583 | 496 | } |
497 | ||
cf208031 | 498 | static int dont_notify_cb( |
7e5c8a5b RB |
499 | git_checkout_notify_t why, |
500 | const char *path, | |
501 | const git_diff_file *baseline, | |
502 | const git_diff_file *target, | |
503 | const git_diff_file *workdir, | |
9e592583 | 504 | void *payload) |
505 | { | |
7e5c8a5b RB |
506 | GIT_UNUSED(why); |
507 | GIT_UNUSED(path); | |
508 | GIT_UNUSED(baseline); | |
509 | GIT_UNUSED(target); | |
510 | GIT_UNUSED(workdir); | |
9e592583 | 511 | GIT_UNUSED(payload); |
512 | ||
513 | cl_assert(false); | |
514 | ||
515 | return 0; | |
516 | } | |
517 | ||
518 | void test_checkout_index__wont_notify_of_expected_line_ending_changes(void) | |
519 | { | |
6affd71f | 520 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
7e5c8a5b | 521 | |
9e592583 | 522 | cl_git_pass(p_unlink("./testrepo/.gitattributes")); |
1323c6d1 | 523 | cl_repo_set_bool(g_repo, "core.autocrlf", true); |
32def5af | 524 | |
9e592583 | 525 | cl_git_mkfile("./testrepo/new.txt", "my new file\r\n"); |
526 | ||
7e5c8a5b | 527 | opts.checkout_strategy = |
96b82b11 ET |
528 | GIT_CHECKOUT_SAFE | |
529 | GIT_CHECKOUT_RECREATE_MISSING | | |
530 | GIT_CHECKOUT_ALLOW_CONFLICTS; | |
7e5c8a5b RB |
531 | opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT; |
532 | opts.notify_cb = dont_notify_cb; | |
533 | opts.notify_payload = NULL; | |
9e592583 | 534 | |
7e5c8a5b | 535 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
2c8bbb27 BS |
536 | } |
537 | ||
cf208031 RB |
538 | static void checkout_progress_counter( |
539 | const char *path, size_t cur, size_t tot, void *payload) | |
2c8bbb27 | 540 | { |
1fc375e6 | 541 | GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot); |
cf208031 | 542 | (*(int *)payload)++; |
2c8bbb27 BS |
543 | } |
544 | ||
545 | void test_checkout_index__calls_progress_callback(void) | |
546 | { | |
6affd71f | 547 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
cf208031 RB |
548 | int calls = 0; |
549 | ||
96b82b11 | 550 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
7e5c8a5b RB |
551 | opts.progress_cb = checkout_progress_counter; |
552 | opts.progress_payload = &calls; | |
2c8bbb27 | 553 | |
7e5c8a5b | 554 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
cf208031 | 555 | cl_assert(calls > 0); |
9e592583 | 556 | } |
32def5af RB |
557 | |
558 | void test_checkout_index__can_overcome_name_clashes(void) | |
559 | { | |
6affd71f | 560 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
32def5af RB |
561 | git_index *index; |
562 | ||
563 | cl_git_pass(git_repository_index(&index, g_repo)); | |
564 | git_index_clear(index); | |
565 | ||
566 | cl_git_mkfile("./testrepo/path0", "content\r\n"); | |
567 | cl_git_pass(p_mkdir("./testrepo/path1", 0777)); | |
568 | cl_git_mkfile("./testrepo/path1/file1", "content\r\n"); | |
569 | ||
25743bd7 ET |
570 | cl_git_pass(git_index_add_bypath(index, "path0")); |
571 | cl_git_pass(git_index_add_bypath(index, "path1/file1")); | |
ad9a921b | 572 | |
32def5af RB |
573 | cl_git_pass(p_unlink("./testrepo/path0")); |
574 | cl_git_pass(git_futils_rmdir_r( | |
575 | "./testrepo/path1", NULL, GIT_RMDIR_REMOVE_FILES)); | |
576 | ||
577 | cl_git_mkfile("./testrepo/path1", "content\r\n"); | |
578 | cl_git_pass(p_mkdir("./testrepo/path0", 0777)); | |
579 | cl_git_mkfile("./testrepo/path0/file0", "content\r\n"); | |
580 | ||
e579e0f7 MB |
581 | cl_assert(git_fs_path_isfile("./testrepo/path1")); |
582 | cl_assert(git_fs_path_isfile("./testrepo/path0/file0")); | |
ad9a921b | 583 | |
7e5c8a5b | 584 | opts.checkout_strategy = |
ac3d33df | 585 | GIT_CHECKOUT_SAFE | |
96b82b11 ET |
586 | GIT_CHECKOUT_RECREATE_MISSING | |
587 | GIT_CHECKOUT_ALLOW_CONFLICTS; | |
7e5c8a5b | 588 | cl_git_pass(git_checkout_index(g_repo, index, &opts)); |
32def5af | 589 | |
e579e0f7 MB |
590 | cl_assert(git_fs_path_isfile("./testrepo/path1")); |
591 | cl_assert(git_fs_path_isfile("./testrepo/path0/file0")); | |
32def5af | 592 | |
7e5c8a5b RB |
593 | opts.checkout_strategy = GIT_CHECKOUT_FORCE; |
594 | cl_git_pass(git_checkout_index(g_repo, index, &opts)); | |
ad9a921b | 595 | |
e579e0f7 MB |
596 | cl_assert(git_fs_path_isfile("./testrepo/path0")); |
597 | cl_assert(git_fs_path_isfile("./testrepo/path1/file1")); | |
ad9a921b | 598 | |
32def5af RB |
599 | git_index_free(index); |
600 | } | |
b81aa2f1 BS |
601 | |
602 | void test_checkout_index__validates_struct_version(void) | |
603 | { | |
6affd71f | 604 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
b81aa2f1 BS |
605 | const git_error *err; |
606 | ||
7e5c8a5b RB |
607 | opts.version = 1024; |
608 | cl_git_fail(git_checkout_index(g_repo, NULL, &opts)); | |
b81aa2f1 | 609 | |
ac3d33df JK |
610 | err = git_error_last(); |
611 | cl_assert_equal_i(err->klass, GIT_ERROR_INVALID); | |
b81aa2f1 | 612 | |
7e5c8a5b | 613 | opts.version = 0; |
ac3d33df | 614 | git_error_clear(); |
7e5c8a5b | 615 | cl_git_fail(git_checkout_index(g_repo, NULL, &opts)); |
b81aa2f1 | 616 | |
ac3d33df JK |
617 | err = git_error_last(); |
618 | cl_assert_equal_i(err->klass, GIT_ERROR_INVALID); | |
b81aa2f1 | 619 | } |
817d6251 RB |
620 | |
621 | void test_checkout_index__can_update_prefixed_files(void) | |
622 | { | |
6affd71f | 623 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
817d6251 | 624 | |
e579e0f7 MB |
625 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); |
626 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); | |
627 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); | |
2f089539 | 628 | |
817d6251 RB |
629 | cl_git_mkfile("./testrepo/READ", "content\n"); |
630 | cl_git_mkfile("./testrepo/README.after", "content\n"); | |
631 | cl_git_pass(p_mkdir("./testrepo/branch_file", 0777)); | |
632 | cl_git_pass(p_mkdir("./testrepo/branch_file/contained_dir", 0777)); | |
633 | cl_git_mkfile("./testrepo/branch_file/contained_file", "content\n"); | |
634 | cl_git_pass(p_mkdir("./testrepo/branch_file.txt.after", 0777)); | |
635 | ||
2f089539 | 636 | opts.checkout_strategy = |
96b82b11 ET |
637 | GIT_CHECKOUT_SAFE | |
638 | GIT_CHECKOUT_RECREATE_MISSING | | |
639 | GIT_CHECKOUT_REMOVE_UNTRACKED; | |
817d6251 RB |
640 | |
641 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); | |
642 | ||
2f089539 RB |
643 | /* remove untracked will remove the .gitattributes file before the blobs |
644 | * were created, so they will have had crlf filtering applied on Windows | |
645 | */ | |
050ab995 RB |
646 | check_file_contents_nocr("./testrepo/README", "hey there\n"); |
647 | check_file_contents_nocr("./testrepo/branch_file.txt", "hi\nbye!\n"); | |
648 | check_file_contents_nocr("./testrepo/new.txt", "my new file\n"); | |
817d6251 | 649 | |
e579e0f7 MB |
650 | cl_assert(!git_fs_path_exists("testrepo/READ")); |
651 | cl_assert(!git_fs_path_exists("testrepo/README.after")); | |
652 | cl_assert(!git_fs_path_exists("testrepo/branch_file")); | |
653 | cl_assert(!git_fs_path_exists("testrepo/branch_file.txt.after")); | |
817d6251 | 654 | } |
2a3b3e03 | 655 | |
656 | void test_checkout_index__can_checkout_a_newly_initialized_repository(void) | |
657 | { | |
ac3d33df | 658 | cl_git_sandbox_cleanup(); |
2a3b3e03 | 659 | g_repo = cl_git_sandbox_init("empty_standard_repo"); |
ac3d33df | 660 | |
2a3b3e03 | 661 | cl_git_remove_placeholders(git_repository_path(g_repo), "dummy-marker.txt"); |
662 | ||
663 | cl_git_pass(git_checkout_index(g_repo, NULL, NULL)); | |
664 | } | |
b8acb775 SS |
665 | |
666 | void test_checkout_index__issue_1397(void) | |
667 | { | |
6affd71f | 668 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
b8acb775 | 669 | |
ac3d33df | 670 | cl_git_sandbox_cleanup(); |
b8acb775 SS |
671 | g_repo = cl_git_sandbox_init("issue_1397"); |
672 | ||
1098cfae | 673 | cl_repo_set_bool(g_repo, "core.autocrlf", true); |
b8acb775 SS |
674 | |
675 | opts.checkout_strategy = GIT_CHECKOUT_FORCE; | |
676 | ||
677 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); | |
678 | ||
050ab995 | 679 | check_file_contents("./issue_1397/crlf_file.txt", "first line\r\nsecond line\r\nboth with crlf"); |
b8acb775 | 680 | } |
9094ae5a RB |
681 | |
682 | void test_checkout_index__target_directory(void) | |
683 | { | |
6affd71f | 684 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
9094ae5a RB |
685 | checkout_counts cts; |
686 | memset(&cts, 0, sizeof(cts)); | |
687 | ||
96b82b11 ET |
688 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | |
689 | GIT_CHECKOUT_RECREATE_MISSING; | |
9094ae5a | 690 | opts.target_directory = "alternative"; |
e579e0f7 | 691 | cl_assert(!git_fs_path_isdir("alternative")); |
9094ae5a RB |
692 | |
693 | opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL; | |
694 | opts.notify_cb = checkout_count_callback; | |
695 | opts.notify_payload = &cts; | |
696 | ||
697 | /* create some files that *would* conflict if we were using the wd */ | |
698 | cl_git_mkfile("testrepo/README", "I'm in the way!\n"); | |
699 | cl_git_mkfile("testrepo/new.txt", "my new file\n"); | |
700 | ||
701 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); | |
702 | ||
703 | cl_assert_equal_i(0, cts.n_untracked); | |
704 | cl_assert_equal_i(0, cts.n_ignored); | |
705 | cl_assert_equal_i(4, cts.n_updates); | |
706 | ||
707 | check_file_contents("./alternative/README", "hey there\n"); | |
708 | check_file_contents("./alternative/branch_file.txt", "hi\nbye!\n"); | |
709 | check_file_contents("./alternative/new.txt", "my new file\n"); | |
d4f98ba4 RB |
710 | |
711 | cl_git_pass(git_futils_rmdir_r( | |
712 | "alternative", NULL, GIT_RMDIR_REMOVE_FILES)); | |
713 | } | |
714 | ||
715 | void test_checkout_index__target_directory_from_bare(void) | |
716 | { | |
6affd71f | 717 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
d4f98ba4 RB |
718 | git_index *index; |
719 | git_object *head = NULL; | |
720 | checkout_counts cts; | |
721 | memset(&cts, 0, sizeof(cts)); | |
722 | ||
ac3d33df | 723 | cl_git_sandbox_cleanup(); |
d4f98ba4 RB |
724 | g_repo = cl_git_sandbox_init("testrepo.git"); |
725 | cl_assert(git_repository_is_bare(g_repo)); | |
726 | ||
727 | cl_git_pass(git_repository_index(&index, g_repo)); | |
728 | cl_git_pass(git_revparse_single(&head, g_repo, "HEAD^{tree}")); | |
729 | cl_git_pass(git_index_read_tree(index, (const git_tree *)head)); | |
730 | cl_git_pass(git_index_write(index)); | |
731 | git_index_free(index); | |
732 | ||
96b82b11 ET |
733 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | |
734 | GIT_CHECKOUT_RECREATE_MISSING; | |
d4f98ba4 RB |
735 | |
736 | opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL; | |
737 | opts.notify_cb = checkout_count_callback; | |
738 | opts.notify_payload = &cts; | |
739 | ||
740 | /* fail to checkout a bare repo */ | |
741 | cl_git_fail(git_checkout_index(g_repo, NULL, &opts)); | |
742 | ||
743 | opts.target_directory = "alternative"; | |
e579e0f7 | 744 | cl_assert(!git_fs_path_isdir("alternative")); |
d4f98ba4 RB |
745 | |
746 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); | |
747 | ||
748 | cl_assert_equal_i(0, cts.n_untracked); | |
749 | cl_assert_equal_i(0, cts.n_ignored); | |
750 | cl_assert_equal_i(3, cts.n_updates); | |
751 | ||
f3f4c6b5 RB |
752 | /* files will have been filtered if needed, so strip CR */ |
753 | check_file_contents_nocr("./alternative/README", "hey there\n"); | |
754 | check_file_contents_nocr("./alternative/branch_file.txt", "hi\nbye!\n"); | |
755 | check_file_contents_nocr("./alternative/new.txt", "my new file\n"); | |
d4f98ba4 RB |
756 | |
757 | cl_git_pass(git_futils_rmdir_r( | |
758 | "alternative", NULL, GIT_RMDIR_REMOVE_FILES)); | |
d90390c1 | 759 | |
760 | git_object_free(head); | |
d4f98ba4 RB |
761 | } |
762 | ||
763 | void test_checkout_index__can_get_repo_from_index(void) | |
764 | { | |
765 | git_index *index; | |
6affd71f | 766 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
d4f98ba4 | 767 | |
e579e0f7 MB |
768 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); |
769 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); | |
770 | cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); | |
d4f98ba4 | 771 | |
96b82b11 | 772 | opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; |
d4f98ba4 RB |
773 | |
774 | cl_git_pass(git_repository_index(&index, g_repo)); | |
775 | ||
776 | cl_git_pass(git_checkout_index(NULL, index, &opts)); | |
777 | ||
778 | check_file_contents("./testrepo/README", "hey there\n"); | |
779 | check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); | |
780 | check_file_contents("./testrepo/new.txt", "my new file\n"); | |
781 | ||
782 | git_index_free(index); | |
9094ae5a | 783 | } |
8d3b2ee3 | 784 | |
2d24816b | 785 | static void add_conflict(git_index *index, const char *path) |
8d3b2ee3 | 786 | { |
8d3b2ee3 ET |
787 | git_index_entry entry; |
788 | ||
789 | memset(&entry, 0, sizeof(git_index_entry)); | |
790 | ||
8d3b2ee3 | 791 | entry.mode = 0100644; |
2d24816b | 792 | entry.path = path; |
8d3b2ee3 ET |
793 | |
794 | git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46"); | |
ac3d33df | 795 | GIT_INDEX_ENTRY_STAGE_SET(&entry, 1); |
8d3b2ee3 ET |
796 | cl_git_pass(git_index_add(index, &entry)); |
797 | ||
798 | git_oid_fromstr(&entry.id, "4e886e602529caa9ab11d71f86634bd1b6e0de10"); | |
ac3d33df | 799 | GIT_INDEX_ENTRY_STAGE_SET(&entry, 2); |
8d3b2ee3 ET |
800 | cl_git_pass(git_index_add(index, &entry)); |
801 | ||
802 | git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863"); | |
ac3d33df | 803 | GIT_INDEX_ENTRY_STAGE_SET(&entry, 3); |
8d3b2ee3 | 804 | cl_git_pass(git_index_add(index, &entry)); |
8d3b2ee3 ET |
805 | } |
806 | ||
807 | void test_checkout_index__writes_conflict_file(void) | |
808 | { | |
2d24816b | 809 | git_index *index; |
8d3b2ee3 | 810 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
e579e0f7 | 811 | git_str conflicting_buf = GIT_STR_INIT; |
8d3b2ee3 | 812 | |
2d24816b ET |
813 | cl_git_pass(git_repository_index(&index, g_repo)); |
814 | ||
815 | add_conflict(index, "conflicting.txt"); | |
816 | cl_git_pass(git_index_write(index)); | |
817 | ||
8d3b2ee3 ET |
818 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
819 | ||
820 | cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt")); | |
821 | cl_assert(strcmp(conflicting_buf.ptr, | |
822 | "<<<<<<< ours\n" | |
823 | "this file is changed in master and branch\n" | |
824 | "=======\n" | |
825 | "this file is changed in branch and master\n" | |
826 | ">>>>>>> theirs\n") == 0); | |
e579e0f7 | 827 | git_str_dispose(&conflicting_buf); |
2d24816b ET |
828 | |
829 | git_index_free(index); | |
830 | } | |
831 | ||
832 | void test_checkout_index__adding_conflict_removes_stage_0(void) | |
833 | { | |
834 | git_index *new_index, *index; | |
835 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; | |
836 | ||
837 | cl_git_pass(git_index_new(&new_index)); | |
838 | ||
839 | add_conflict(new_index, "new.txt"); | |
840 | cl_git_pass(git_checkout_index(g_repo, new_index, &opts)); | |
841 | ||
842 | cl_git_pass(git_repository_index(&index, g_repo)); | |
843 | ||
844 | cl_assert(git_index_get_bypath(index, "new.txt", 0) == NULL); | |
845 | cl_assert(git_index_get_bypath(index, "new.txt", 1) != NULL); | |
846 | cl_assert(git_index_get_bypath(index, "new.txt", 2) != NULL); | |
847 | cl_assert(git_index_get_bypath(index, "new.txt", 3) != NULL); | |
848 | ||
849 | git_index_free(index); | |
850 | git_index_free(new_index); | |
8d3b2ee3 ET |
851 | } |
852 | ||
853 | void test_checkout_index__conflicts_honor_coreautocrlf(void) | |
854 | { | |
855 | #ifdef GIT_WIN32 | |
2d24816b | 856 | git_index *index; |
8d3b2ee3 | 857 | git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; |
e579e0f7 | 858 | git_str conflicting_buf = GIT_STR_INIT; |
8d3b2ee3 ET |
859 | |
860 | cl_git_pass(p_unlink("./testrepo/.gitattributes")); | |
861 | cl_repo_set_bool(g_repo, "core.autocrlf", true); | |
862 | ||
2d24816b ET |
863 | cl_git_pass(git_repository_index(&index, g_repo)); |
864 | ||
865 | add_conflict(index, "conflicting.txt"); | |
866 | cl_git_pass(git_index_write(index)); | |
867 | ||
8d3b2ee3 ET |
868 | cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); |
869 | ||
870 | cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt")); | |
871 | cl_assert(strcmp(conflicting_buf.ptr, | |
872 | "<<<<<<< ours\r\n" | |
873 | "this file is changed in master and branch\r\n" | |
874 | "=======\r\n" | |
875 | "this file is changed in branch and master\r\n" | |
876 | ">>>>>>> theirs\r\n") == 0); | |
e579e0f7 | 877 | git_str_dispose(&conflicting_buf); |
2d24816b ET |
878 | |
879 | git_index_free(index); | |
8d3b2ee3 ET |
880 | #endif |
881 | } |