From 83e3ad3b126125d23eea10283d85682a1a680daa Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Wed, 18 Sep 2019 13:27:38 -0700 Subject: merge-recursive: symlink's descendants not in way When the working tree has: - bar (directory) - bar/file (file) - foo (symlink to .) (note that lstat() for "foo/bar" would tell us that it is a directory) and the user merges a commit that deletes the foo symlink and instead contains: - bar (directory, as above) - bar/file (file, as above) - foo (directory) - foo/bar (file) the merge should happen without requiring user intervention. However, this does not happen. This is because dir_in_way(), when checking the working tree, thinks that "foo/bar" is a directory. But a symlink should be treated much the same as a file: since dir_in_way() is only checking to see if there is a directory in the way, we don't want symlinks in leading paths to sometimes cause dir_in_way() to return true. Teach dir_in_way() to also check for symlinks in leading paths before reporting whether a directory is in the way. Helped-by: Elijah Newren Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- merge-recursive.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'merge-recursive.c') diff --git a/merge-recursive.c b/merge-recursive.c index 6b812d67e3..22a12cfeba 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -764,7 +764,8 @@ static int dir_in_way(struct index_state *istate, const char *path, strbuf_release(&dirpath); return check_working_copy && !lstat(path, &st) && S_ISDIR(st.st_mode) && - !(empty_ok && is_empty_dir(path)); + !(empty_ok && is_empty_dir(path)) && + !has_symlink_leading_path(path, strlen(path)); } /* -- cgit v1.2.3