summaryrefslogtreecommitdiff
path: root/entry.c
diff options
context:
space:
mode:
authorMatheus Tavares <matheus.bernardino@usp.br>2021-03-18 18:43:47 (GMT)
committerJunio C Hamano <gitster@pobox.com>2021-03-18 19:58:10 (GMT)
commitfab78a0c3defddff87ea5aa7dd32c5e444c43f1f (patch)
treed18015c917149b5b89c61f96d5857d60dfa7ef14 /entry.c
parent462b4e8dfd688b8964da77daf17b64da5bdc54ad (diff)
downloadgit-fab78a0c3defddff87ea5aa7dd32c5e444c43f1f.zip
git-fab78a0c3defddff87ea5aa7dd32c5e444c43f1f.tar.gz
git-fab78a0c3defddff87ea5aa7dd32c5e444c43f1f.tar.bz2
checkout: don't follow symlinks when removing entries
At 1d718a5108 ("do not overwrite untracked symlinks", 2011-02-20), symlink.c:check_leading_path() started returning different codes for FL_ENOENT and FL_SYMLINK. But one of its callers, unlink_entry(), was not adjusted for this change, so it started to follow symlinks on the leading path of to-be-removed entries. Fix that and add a regression test. Note that since 1d718a5108 check_leading_path() no longer differentiates the case where it found a symlink in the path's leading components from the cases where it found a regular file or failed to lstat() the component. So, a side effect of this current patch is that unlink_entry() now returns early in all of these three cases. And because we no longer try to unlink such paths, we also don't get the warning from remove_or_warn(). For the regular file and symlink cases, it's questionable whether the warning was useful in the first place: unlink_entry() removes tracked paths that should no longer be present in the state we are checking out to. If the path had its leading dir replaced by another file, it means that the basename already doesn't exist, so there is no need for a warning. Sure, we are leaving a regular file or symlink behind at the path's dirname, but this file is either untracked now (so again, no need to warn), or it will be replaced by a tracked file during the next phase of this checkout operation. As for failing to lstat() one of the leading components, the basename might still exist only we cannot unlink it (e.g. due to the lack of the required permissions). Since the user expect it to be removed (especially with checkout's --no-overlay option), add back the warning in this more relevant case. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'entry.c')
-rw-r--r--entry.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/entry.c b/entry.c
index a0532f1..a8c4b8b 100644
--- a/entry.c
+++ b/entry.c
@@ -530,7 +530,7 @@ void unlink_entry(const struct cache_entry *ce)
submodule_move_head(ce->name, "HEAD", NULL,
SUBMODULE_MOVE_HEAD_FORCE);
}
- if (!check_leading_path(ce->name, ce_namelen(ce)))
+ if (check_leading_path(ce->name, ce_namelen(ce), 1) >= 0)
return;
if (remove_or_warn(ce->ce_mode, ce->name))
return;