From bf4a577c6989f67fc7821eebd61a117726afc9d5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 13 Dec 2013 10:10:32 -0500 Subject: [PATCH] Overwrite ignored directories on checkout --- src/checkout.c | 7 +++++-- tests/checkout/tree.c | 47 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 50da83a4a..e642c975e 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -435,6 +435,7 @@ static int checkout_action_with_wd_dir( int *action, checkout_data *data, const git_diff_delta *delta, + git_iterator *workdir, const git_index_entry *wd) { *action = CHECKOUT_ACTION__NONE; @@ -451,7 +452,9 @@ static int checkout_action_with_wd_dir( if (delta->old_file.mode == GIT_FILEMODE_COMMIT) /* expected submodule (and maybe found one) */; else if (delta->new_file.mode != GIT_FILEMODE_TREE) - *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); + *action = git_iterator_current_is_ignored(workdir) ? + CHECKOUT_ACTION_IF(DONT_OVERWRITE_IGNORED, CONFLICT, REMOVE_AND_UPDATE) : + CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); break; case GIT_DELTA_DELETED: /* case 11 (and 27 for dir) */ if (delta->old_file.mode != GIT_FILEMODE_TREE) @@ -573,7 +576,7 @@ static int checkout_action( } } - return checkout_action_with_wd_dir(action, data, delta, wd); + return checkout_action_with_wd_dir(action, data, delta, workdir, wd); } /* case 6 - wd is after delta */ diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index 10a44b6b9..06aa6a594 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -235,7 +235,7 @@ void test_checkout_tree__can_remove_ignored(void) cl_assert(!git_path_isfile("testrepo/ignored_file")); } -static int checkout_tree_with_blob_ignored_in_workdir(int strategy) +static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir) { git_oid oid; git_object *obj = NULL; @@ -268,16 +268,27 @@ static int checkout_tree_with_blob_ignored_in_workdir(int strategy) opts.checkout_strategy = strategy; - cl_must_pass(p_mkdir("testrepo/ab", 0777)); - cl_git_mkfile("testrepo/ab/4.txt", "as you wish"); + if (isdir) { + cl_must_pass(p_mkdir("testrepo/ab", 0777)); + cl_must_pass(p_mkdir("testrepo/ab/4.txt", 0777)); + + cl_git_mkfile("testrepo/ab/4.txt/file1.txt", "as you wish"); + cl_git_mkfile("testrepo/ab/4.txt/file2.txt", "foo bar foo"); + cl_git_mkfile("testrepo/ab/4.txt/file3.txt", "inky blinky pinky clyde"); + + cl_assert(git_path_isdir("testrepo/ab/4.txt")); + } else { + cl_must_pass(p_mkdir("testrepo/ab", 0777)); + cl_git_mkfile("testrepo/ab/4.txt", "as you wish"); + + cl_assert(git_path_isfile("testrepo/ab/4.txt")); + } cl_git_pass(git_ignore_add_rule(g_repo, "ab/4.txt\n")); cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "ab/4.txt")); cl_assert_equal_i(1, ignored); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); - cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/subtrees")); cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); @@ -293,14 +304,14 @@ void test_checkout_tree__conflict_on_ignored_when_not_overwriting(void) int error; cl_git_fail(error = checkout_tree_with_blob_ignored_in_workdir( - GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DONT_OVERWRITE_IGNORED)); + GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DONT_OVERWRITE_IGNORED, false)); cl_assert_equal_i(GIT_EMERGECONFLICT, error); } void test_checkout_tree__can_overwrite_ignored_by_default(void) { - cl_git_pass(checkout_tree_with_blob_ignored_in_workdir(GIT_CHECKOUT_SAFE)); + cl_git_pass(checkout_tree_with_blob_ignored_in_workdir(GIT_CHECKOUT_SAFE, false)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); @@ -309,6 +320,28 @@ void test_checkout_tree__can_overwrite_ignored_by_default(void) assert_on_branch(g_repo, "subtrees"); } +void test_checkout_tree__conflict_on_ignored_folder_when_not_overwriting(void) +{ + int error; + + cl_git_fail(error = checkout_tree_with_blob_ignored_in_workdir( + GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DONT_OVERWRITE_IGNORED, true)); + + cl_assert_equal_i(GIT_EMERGECONFLICT, error); +} + +void test_checkout_tree__can_overwrite_ignored_folder_by_default(void) +{ + cl_git_pass(checkout_tree_with_blob_ignored_in_workdir(GIT_CHECKOUT_SAFE, true)); + + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); + + cl_assert(git_path_isfile("testrepo/ab/4.txt")); + + assert_on_branch(g_repo, "subtrees"); + +} + void test_checkout_tree__can_update_only(void) { git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;