зеркало из https://github.com/microsoft/git.git
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 <newren@gmail.com> Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
5fa0f5238b
Коммит
83e3ad3b12
|
@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -452,6 +452,34 @@ test_expect_success 'merge-recursive d/f conflict result' '
|
|||
|
||||
'
|
||||
|
||||
test_expect_success SYMLINKS 'dir in working tree with symlink ancestor does not produce d/f conflict' '
|
||||
git init sym &&
|
||||
(
|
||||
cd sym &&
|
||||
ln -s . foo &&
|
||||
mkdir bar &&
|
||||
>bar/file &&
|
||||
git add foo bar/file &&
|
||||
git commit -m "foo symlink" &&
|
||||
|
||||
git checkout -b branch1 &&
|
||||
git commit --allow-empty -m "empty commit" &&
|
||||
|
||||
git checkout master &&
|
||||
git rm foo &&
|
||||
mkdir foo &&
|
||||
>foo/bar &&
|
||||
git add foo/bar &&
|
||||
git commit -m "replace foo symlink with real foo dir and foo/bar file" &&
|
||||
|
||||
git checkout branch1 &&
|
||||
|
||||
git cherry-pick master &&
|
||||
test_path_is_dir foo &&
|
||||
test_path_is_file foo/bar
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'reset and 3-way merge' '
|
||||
|
||||
git reset --hard "$c2" &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче