index f276cf3b88ea40cb4e6d03c623ce27cb0204c63e..004182c99d27a6a5825d2429f9104fc7a8f1dc80 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -177,11 +177,15 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
/*
* This is like 'lstat()', except it refuses to follow symlinks
- * in the path.
+ * in the path, after skipping "skiplen".
*/
-int check_path(const char *path, int len, struct stat *st)
+static int check_path(const char *path, int len, struct stat *st, int skiplen)
{
- if (has_symlink_leading_path(path, len)) {
+ const char *slash = path + len;
+
+ while (path < slash && *slash != '/')
+ slash--;
+ if (!has_dirs_only_path(path, slash - path, skiplen)) {
errno = ENOENT;
return -1;
}
@@ -201,8 +205,8 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
strcpy(path + len, ce->name);
len += ce_namelen(ce);
- if (!check_path(path, len, &st)) {
- unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
+ if (!check_path(path, len, &st, state->base_dir_len)) {
+ unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
if (!changed)
return 0;
if (!state->force) {