Skip to content

Commit 9ce57f1

Browse files
committed
Merge branch 'da/difftool'
Allow diff tool backend to stop early by exiting with a non-zero status. * da/difftool: difftool: add support for --trust-exit-code difftool--helper: exit when reading a prompt answer fails
2 parents e82935d + 2b52123 commit 9ce57f1

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

Documentation/git-difftool.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ instead. `--no-symlinks` is the default on Windows.
9191
the default diff tool will be read from the configured
9292
`diff.guitool` variable instead of `diff.tool`.
9393

94+
--[no-]trust-exit-code::
95+
'git-difftool' invokes a diff tool individually on each file.
96+
Errors reported by the diff tool are ignored by default.
97+
Use `--trust-exit-code` to make 'git-difftool' exit when an
98+
invoked diff tool returns a non-zero exit code.
99+
+
100+
'git-difftool' will forward the exit code of the invoked tool when
101+
'--trust-exit-code' is used.
102+
94103
See linkgit:git-diff[1] for the full list of supported options.
95104

96105
CONFIG VARIABLES
@@ -116,6 +125,11 @@ See the `--tool=<tool>` option above for more details.
116125
difftool.prompt::
117126
Prompt before each invocation of the diff tool.
118127

128+
difftool.trustExitCode::
129+
Exit difftool if the invoked diff tool returns a non-zero exit status.
130+
+
131+
See the `--trust-exit-code` option above for more details.
132+
119133
SEE ALSO
120134
--------
121135
linkgit:git-diff[1]::

git-difftool--helper.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ launch_merge_tool () {
4949
else
5050
printf "Launch '%s' [Y/n]: " "$merge_tool"
5151
fi
52-
if read ans && test "$ans" = n
52+
read ans || return
53+
if test "$ans" = n
5354
then
5455
return
5556
fi
@@ -84,6 +85,12 @@ else
8485
while test $# -gt 6
8586
do
8687
launch_merge_tool "$1" "$2" "$5"
88+
status=$?
89+
if test "$status" != 0 &&
90+
test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true
91+
then
92+
exit $status
93+
fi
8794
shift 7
8895
done
8996
fi

git-difftool.perl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ sub main
342342
symlinks => $^O ne 'cygwin' &&
343343
$^O ne 'MSWin32' && $^O ne 'msys',
344344
tool_help => undef,
345+
trust_exit_code => undef,
345346
);
346347
GetOptions('g|gui!' => \$opts{gui},
347348
'd|dir-diff' => \$opts{dirdiff},
@@ -352,6 +353,8 @@ sub main
352353
'no-symlinks' => sub { $opts{symlinks} = 0; },
353354
't|tool:s' => \$opts{difftool_cmd},
354355
'tool-help' => \$opts{tool_help},
356+
'trust-exit-code' => \$opts{trust_exit_code},
357+
'no-trust-exit-code' => sub { $opts{trust_exit_code} = 0; },
355358
'x|extcmd:s' => \$opts{extcmd});
356359

357360
if (defined($opts{help})) {
@@ -383,6 +386,15 @@ sub main
383386
}
384387
}
385388

389+
if (!defined $opts{trust_exit_code}) {
390+
$opts{trust_exit_code} = Git::config_bool('difftool.trustExitCode');
391+
}
392+
if ($opts{trust_exit_code}) {
393+
$ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'true';
394+
} else {
395+
$ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'false';
396+
}
397+
386398
# In directory diff mode, 'git-difftool--helper' is called once
387399
# to compare the a/b directories. In file diff mode, 'git diff'
388400
# will invoke a separate instance of 'git-difftool--helper' for

t/t7800-difftool.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,49 @@ test_expect_success PERL 'difftool forwards arguments to diff' '
7676
rm for-diff
7777
'
7878

79+
test_expect_success PERL 'difftool ignores exit code' '
80+
test_config difftool.error.cmd false &&
81+
git difftool -y -t error branch
82+
'
83+
84+
test_expect_success PERL 'difftool forwards exit code with --trust-exit-code' '
85+
test_config difftool.error.cmd false &&
86+
test_must_fail git difftool -y --trust-exit-code -t error branch
87+
'
88+
89+
test_expect_success PERL 'difftool honors difftool.trustExitCode = true' '
90+
test_config difftool.error.cmd false &&
91+
test_config difftool.trustExitCode true &&
92+
test_must_fail git difftool -y -t error branch
93+
'
94+
95+
test_expect_success PERL 'difftool honors difftool.trustExitCode = false' '
96+
test_config difftool.error.cmd false &&
97+
test_config difftool.trustExitCode false &&
98+
git difftool -y -t error branch
99+
'
100+
101+
test_expect_success PERL 'difftool ignores exit code with --no-trust-exit-code' '
102+
test_config difftool.error.cmd false &&
103+
test_config difftool.trustExitCode true &&
104+
git difftool -y --no-trust-exit-code -t error branch
105+
'
106+
107+
test_expect_success PERL 'difftool stops on error with --trust-exit-code' '
108+
test_when_finished "rm -f for-diff .git/fail-right-file" &&
109+
test_when_finished "git reset -- for-diff" &&
110+
write_script .git/fail-right-file <<-\EOF &&
111+
echo "$2"
112+
exit 1
113+
EOF
114+
>for-diff &&
115+
git add for-diff &&
116+
echo file >expect &&
117+
test_must_fail git difftool -y --trust-exit-code \
118+
--extcmd .git/fail-right-file branch >actual &&
119+
test_cmp expect actual
120+
'
121+
79122
test_expect_success PERL 'difftool honors --gui' '
80123
difftool_test_setup &&
81124
test_config merge.tool bogus-tool &&
@@ -301,6 +344,14 @@ test_expect_success PERL 'say no to the second file' '
301344
! grep br2 output
302345
'
303346

347+
test_expect_success PERL 'ending prompt input with EOF' '
348+
git difftool -x cat branch </dev/null >output &&
349+
! grep master output &&
350+
! grep branch output &&
351+
! grep m2 output &&
352+
! grep br2 output
353+
'
354+
304355
test_expect_success PERL 'difftool --tool-help' '
305356
git difftool --tool-help >output &&
306357
grep tool output

0 commit comments

Comments
 (0)