Merge pull request #4260 from libgit2/ethomson/forced_checkout_2
Update to forced checkout and untracked files
diff --git a/src/checkout.c b/src/checkout.c
index 9d1eed5..25018d2 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -370,10 +370,8 @@
*/
const git_index_entry *e = git_index_get_byindex(data->index, pos);
- if (e != NULL && data->diff->pfxcomp(e->path, wd->path) == 0) {
- notify = GIT_CHECKOUT_NOTIFY_DIRTY;
- remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0);
- }
+ if (e != NULL && data->diff->pfxcomp(e->path, wd->path) == 0)
+ return git_iterator_advance_into(wditem, workdir);
}
}
diff --git a/src/fileops.c b/src/fileops.c
index bda17f0..2f3f58d 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -770,6 +770,9 @@
if (en == ENOENT || en == ENOTDIR) {
/* do nothing */
+ } else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0 &&
+ en == EBUSY) {
+ error = git_path_set_error(errno, path, "rmdir");
} else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) {
error = GIT_ITEROVER;
} else {
diff --git a/tests/checkout/head.c b/tests/checkout/head.c
index 07cc1d2..ded86df 100644
--- a/tests/checkout/head.c
+++ b/tests/checkout/head.c
@@ -38,7 +38,7 @@
cl_git_pass(git_repository_index(&index, g_repo));
p_mkdir("testrepo/newdir", 0777);
- cl_git_mkfile("testrepo/newdir/newfile.txt", "new file\n");
+ cl_git_mkfile("testrepo/newdir/newfile.txt", "new file\n");
cl_git_pass(git_index_add_bypath(index, "newdir/newfile.txt"));
cl_git_pass(git_index_write(index));
@@ -60,3 +60,79 @@
git_index_free(index);
}
+
+void test_checkout_head__do_not_remove_untracked_file(void)
+{
+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+ git_index *index;
+
+ cl_git_pass(p_mkdir("testrepo/tracked", 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;
+ 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_not_remove_untracked_file_in_subdir(void)
+{
+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+ git_index *index;
+
+ 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/subdir/tracked", "tracked\n");
+ cl_git_mkfile("testrepo/tracked/subdir/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_add_bypath(index, "tracked/subdir/tracked"));
+ cl_git_pass(git_index_write(index));
+
+ git_index_free(index);
+
+ opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+ cl_git_pass(git_checkout_head(g_repo, &opts));
+
+ cl_assert(!git_path_isfile("testrepo/tracked/tracked"));
+ cl_assert(!git_path_isfile("testrepo/tracked/subdir/tracked"));
+ cl_assert(git_path_isfile("testrepo/tracked/subdir/untracked"));
+}
+
+void test_checkout_head__do_remove_tracked_subdir(void)
+{
+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+ git_index *index;
+
+ cl_git_pass(p_mkdir("testrepo/subdir", 0755));
+ cl_git_pass(p_mkdir("testrepo/subdir/tracked", 0755));
+ cl_git_mkfile("testrepo/subdir/tracked-file", "tracked\n");
+ cl_git_mkfile("testrepo/subdir/untracked-file", "untracked\n");
+ cl_git_mkfile("testrepo/subdir/tracked/tracked1", "tracked\n");
+ cl_git_mkfile("testrepo/subdir/tracked/tracked2", "tracked\n");
+
+ cl_git_pass(git_repository_index(&index, g_repo));
+ cl_git_pass(git_index_add_bypath(index, "subdir/tracked-file"));
+ cl_git_pass(git_index_add_bypath(index, "subdir/tracked/tracked1"));
+ cl_git_pass(git_index_add_bypath(index, "subdir/tracked/tracked2"));
+ cl_git_pass(git_index_write(index));
+
+ git_index_free(index);
+
+ opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+ cl_git_pass(git_checkout_head(g_repo, &opts));
+
+ cl_assert(!git_path_isdir("testrepo/subdir/tracked"));
+ cl_assert(!git_path_isfile("testrepo/subdir/tracked-file"));
+ cl_assert(git_path_isfile("testrepo/subdir/untracked-file"));
+}