path: root/merge-recursive.c
diff options
authorJonathan Tan <>2019-09-18 20:27:38 (GMT)
committerJunio C Hamano <>2019-09-20 17:15:57 (GMT)
commit83e3ad3b126125d23eea10283d85682a1a680daa (patch)
tree633d455b9afead846c749e5f93ed20be471771ed /merge-recursive.c
parent5fa0f5238b0cd46cfe7f6fa76c3f526ea98148d9 (diff)
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 <>
Diffstat (limited to 'merge-recursive.c')
1 files changed, 2 insertions, 1 deletions
diff --git a/merge-recursive.c b/merge-recursive.c
index 6b812d6..22a12cf 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,
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));