difftool: handle unmerged files in dir-diff mode

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>

David Aguilar committed May 16, 2016 at 11:05 UTC 366f9cea18fbb7ebb0a75735da8c2a9d5a916809
2 files changed +28
git-difftool.perl
+5
@@ -138,6 +138,7 @@ sub setup_dir_diff
138 my %submodule;
139 my %symlink;
140 my @working_tree = ();
141 + my %working_tree_dups = ();
142 my @rawdiff = split('\0', $diffrtn);
143
144 my $i = 0;
@@ -188,6 +189,10 @@ EOF
189 }
190
191 if ($rmode ne $null_mode) {
192 + # Avoid duplicate working_tree entries
193 + if ($working_tree_dups{$dst_path}++) {
194 + next;
195 + }
196 my ($use, $wt_sha1) = use_wt_file($repo, $workdir,
197 $dst_path, $rsha1);
198 if ($use) {
t/t7800-difftool.sh
+23
@@ -419,6 +419,29 @@ run_dir_diff_test 'difftool --dir-diff when worktree file is missing' '
419 grep file2 output
420 '
421
422 +run_dir_diff_test 'difftool --dir-diff with unmerged files' '
423 + test_when_finished git reset --hard &&
424 + test_config difftool.echo.cmd "echo ok" &&
425 + git checkout -B conflict-a &&
426 + git checkout -B conflict-b &&
427 + git checkout conflict-a &&
428 + echo a >>file &&
429 + git add file &&
430 + git commit -m conflict-a &&
431 + git checkout conflict-b &&
432 + echo b >>file &&
433 + git add file &&
434 + git commit -m conflict-b &&
435 + git checkout master &&
436 + git merge conflict-a &&
437 + test_must_fail git merge conflict-b &&
438 + cat >expect <<-EOF &&
439 + ok
440 + EOF
441 + git difftool --dir-diff $symlinks -t echo >actual &&
442 + test_cmp expect actual
443 +'
444 +
445 write_script .git/CHECK_SYMLINKS <<\EOF
446 for f in file file2 sub/sub
447 do