Commit d62e44cb by Segev Finer Committed by Edward Thomson

checkout: Fix removing untracked files by path in subdirectories

The checkout code didn't iterate into a subdir if it didn't match the
pathspec, but since the pathspec might match files in the subdir we
should recurse into it (In contrast to gitignore handling).

Fixes #5089
parent 2a1d97e6
...@@ -371,8 +371,13 @@ static int checkout_action_wd_only( ...@@ -371,8 +371,13 @@ static int checkout_action_wd_only(
if (!git_pathspec__match( if (!git_pathspec__match(
pathspec, wd->path, pathspec, wd->path,
(data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0, (data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0,
git_iterator_ignore_case(workdir), NULL, NULL)) git_iterator_ignore_case(workdir), NULL, NULL)) {
return git_iterator_advance(wditem, workdir);
if (wd->mode == GIT_FILEMODE_TREE)
return git_iterator_advance_into(wditem, workdir);
else
return git_iterator_advance(wditem, workdir);
}
/* check if item is tracked in the index but not in the checkout diff */ /* check if item is tracked in the index but not in the checkout diff */
if (data->index != NULL) { if (data->index != NULL) {
......
...@@ -109,6 +109,32 @@ void test_checkout_head__do_not_remove_untracked_file_in_subdir(void) ...@@ -109,6 +109,32 @@ void test_checkout_head__do_not_remove_untracked_file_in_subdir(void)
cl_assert(git_path_isfile("testrepo/tracked/subdir/untracked")); cl_assert(git_path_isfile("testrepo/tracked/subdir/untracked"));
} }
void test_checkout_head__do_remove_untracked_paths(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_index *index;
char *paths[] = {"tracked/untracked"};
cl_git_pass(p_mkdir("testrepo/tracked", 0755));
cl_git_pass(p_mkdir("testrepo/tracked/subdir", 0755));
cl_git_mkfile("testrepo/tracked/tracked", "tracked\n");
cl_git_mkfile("testrepo/tracked/untracked", "untracked\n");
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_index_add_bypath(index, "tracked/tracked"));
cl_git_pass(git_index_write(index));
git_index_free(index);
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
opts.paths.strings = paths;
opts.paths.count = 1;
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(git_path_isfile("testrepo/tracked/tracked"));
cl_assert(!git_path_isfile("testrepo/tracked/untracked"));
}
void test_checkout_head__do_remove_tracked_subdir(void) void test_checkout_head__do_remove_tracked_subdir(void)
{ {
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment