summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2017-06-08 22:23:53 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2017-06-10 19:16:48 +0100
commit83989d70ecd39324a9c262e75ce27b6a33cf78fc (patch)
treec3230a07092b2679a68a9d25ae96f15cd3e77ef6
parent0ef405b3c8c0213282ef15c48462f16d03442bac (diff)
downloadlibgit2-83989d70ecd39324a9c262e75ce27b6a33cf78fc.tar.gz
checkout: cope with untracked files in directory deletion
When deleting a directory during checkout, do not simply delete the directory, since there may be untracked files. Instead, go into the iterator and examine each file. In the original code (the code with the faulty assumption), we look to see if there's an index entry beneath the directory that we want to remove. Eg, it looks to see if we have a workdir entry foo and an index entry foo/bar.txt. If this is not the case, then the working directory must have precious files in that directory. This part is okay. The part that's not okay is if there is an index entry foo/bar.txt. It just blows away the whole damned directory. That's not cool. Instead, by simply pushing the directory itself onto the stack and iterating each entry, we will deal with the files one by one - whether they're in the index (and can be force removed) or not (and are precious). The original code was a bad optimization, assuming that we didn't need to git_iterator_advance_into if there was any index entry in the folder. That's wrong - we could have optimized this iff all folder entries are in the index. Instead, we need to simply dig into the directory and analyze its entries.
-rw-r--r--src/checkout.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 9d1eed59f..25018d291 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -370,10 +370,8 @@ static int checkout_action_wd_only(
*/
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);
}
}