Skip to content

Commit 6a4f5da

Browse files
committed
Merge branch 'da/difftool-dir-diff-symlink-fix'
"git difftool --dir-diff" mishandled symbolic links. * da/difftool-dir-diff-symlink-fix: difftool: fix symlink-file writing in dir-diff mode
2 parents 92382d1 + 5bafb35 commit 6a4f5da

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

builtin/difftool.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,11 +557,13 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
557557
if (*entry->left) {
558558
add_path(&ldir, ldir_len, entry->path);
559559
ensure_leading_directories(ldir.buf);
560+
unlink(ldir.buf);
560561
write_file(ldir.buf, "%s", entry->left);
561562
}
562563
if (*entry->right) {
563564
add_path(&rdir, rdir_len, entry->path);
564565
ensure_leading_directories(rdir.buf);
566+
unlink(rdir.buf);
565567
write_file(rdir.buf, "%s", entry->right);
566568
}
567569
}

t/t7800-difftool.sh

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,6 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
674674
rm c &&
675675
ln -s d c &&
676676
cat >expect <<-EOF &&
677-
b
678677
c
679678
680679
c
@@ -710,7 +709,6 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
710709
# Deleted symlinks
711710
rm -f c &&
712711
cat >expect <<-EOF &&
713-
b
714712
c
715713
716714
EOF
@@ -723,6 +721,71 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
723721
test_cmp expect actual
724722
'
725723

724+
test_expect_success SYMLINKS 'difftool --dir-diff writes symlinks as raw text' '
725+
# Start out on a branch called "branch-init".
726+
git init -b branch-init symlink-files &&
727+
(
728+
cd symlink-files &&
729+
# This test ensures that symlinks are written as raw text.
730+
# The "cat" tools output link and file contents.
731+
git config difftool.cat-left-link.cmd "cat \"\$LOCAL/link\"" &&
732+
git config difftool.cat-left-a.cmd "cat \"\$LOCAL/file-a\"" &&
733+
git config difftool.cat-right-link.cmd "cat \"\$REMOTE/link\"" &&
734+
git config difftool.cat-right-b.cmd "cat \"\$REMOTE/file-b\"" &&
735+
736+
# Record the empty initial state so that we can come back here
737+
# later and not have to consider the any cases where difftool
738+
# will create symlinks back into the worktree.
739+
test_tick &&
740+
git commit --allow-empty -m init &&
741+
742+
# Create a file called "file-a" with a symlink pointing to it.
743+
git switch -c branch-a &&
744+
echo a >file-a &&
745+
ln -s file-a link &&
746+
git add file-a link &&
747+
test_tick &&
748+
git commit -m link-to-file-a &&
749+
750+
# Create a file called "file-b" and point the symlink to it.
751+
git switch -c branch-b &&
752+
echo b >file-b &&
753+
rm link &&
754+
ln -s file-b link &&
755+
git add file-b link &&
756+
git rm file-a &&
757+
test_tick &&
758+
git commit -m link-to-file-b &&
759+
760+
# Checkout the initial branch so that the --symlinks behavior is
761+
# not activated. The two directories should be completely
762+
# independent with no symlinks pointing back here.
763+
git switch branch-init &&
764+
765+
# The left link must be "file-a" and "file-a" must contain "a".
766+
echo file-a >expect &&
767+
git difftool --symlinks --dir-diff --tool cat-left-link \
768+
branch-a branch-b >actual &&
769+
test_cmp expect actual &&
770+
771+
echo a >expect &&
772+
git difftool --symlinks --dir-diff --tool cat-left-a \
773+
branch-a branch-b >actual &&
774+
test_cmp expect actual &&
775+
776+
# The right link must be "file-b" and "file-b" must contain "b".
777+
echo file-b >expect &&
778+
git difftool --symlinks --dir-diff --tool cat-right-link \
779+
branch-a branch-b >actual &&
780+
test_cmp expect actual &&
781+
782+
echo b >expect &&
783+
git difftool --symlinks --dir-diff --tool cat-right-b \
784+
branch-a branch-b >actual &&
785+
test_cmp expect actual
786+
)
787+
'
788+
726789
test_expect_success 'add -N and difftool -d' '
727790
test_when_finished git reset --hard &&
728791

0 commit comments

Comments
 (0)