summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Aguilar <davvid@gmail.com>2016-05-16 11:05:37 -0700
committerJunio C Hamano <gitster@pobox.com>2016-05-16 14:53:05 -0700
commit366f9cea18fbb7ebb0a75735da8c2a9d5a916809 (patch)
tree6f9e09c510489c4172077e939a79be99f6470247
parent951b551d0f349f145f8606b946d64fc452ad6a51 (diff)
downloadgit-366f9cea18fbb7ebb0a75735da8c2a9d5a916809.tar.gz
difftool: handle unmerged files in dir-diff modeda/difftool
When files are unmerged they can show up as both unmerged and modified in the output of `git diff --raw`. This causes difftool's dir-diff to create filesystem entries for the same path twice, which fails when it encounters a duplicate path. Ensure that each worktree path is only processed once. Add a test to demonstrate the breakage. Reported-by: Jan Smets <jan@smets.cx> Signed-off-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-xgit-difftool.perl5
-rwxr-xr-xt/t7800-difftool.sh23
2 files changed, 28 insertions, 0 deletions
diff --git a/git-difftool.perl b/git-difftool.perl
index 8cf0040590..ebd13baa6e 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -138,6 +138,7 @@ sub setup_dir_diff
my %submodule;
my %symlink;
my @working_tree = ();
+ my %working_tree_dups = ();
my @rawdiff = split('\0', $diffrtn);
my $i = 0;
@@ -188,6 +189,10 @@ EOF
}
if ($rmode ne $null_mode) {
+ # Avoid duplicate working_tree entries
+ if ($working_tree_dups{$dst_path}++) {
+ next;
+ }
my ($use, $wt_sha1) = use_wt_file($repo, $workdir,
$dst_path, $rsha1);
if ($use) {
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 4e713f7aa5..6a7207b950 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -419,6 +419,29 @@ run_dir_diff_test 'difftool --dir-diff when worktree file is missing' '
grep file2 output
'
+run_dir_diff_test 'difftool --dir-diff with unmerged files' '
+ test_when_finished git reset --hard &&
+ test_config difftool.echo.cmd "echo ok" &&
+ git checkout -B conflict-a &&
+ git checkout -B conflict-b &&
+ git checkout conflict-a &&
+ echo a >>file &&
+ git add file &&
+ git commit -m conflict-a &&
+ git checkout conflict-b &&
+ echo b >>file &&
+ git add file &&
+ git commit -m conflict-b &&
+ git checkout master &&
+ git merge conflict-a &&
+ test_must_fail git merge conflict-b &&
+ cat >expect <<-EOF &&
+ ok
+ EOF
+ git difftool --dir-diff $symlinks -t echo >actual &&
+ test_cmp expect actual
+'
+
write_script .git/CHECK_SYMLINKS <<\EOF
for f in file file2 sub/sub
do