From 25098690a0151ba29ec1c728d783366c1899624d Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Sun, 26 Oct 2014 09:09:20 +0100 Subject: [PATCH 1/2] difftool--helper: exit when reading a prompt answer fails An attempt to quit difftool by hitting Ctrl-D (EOF) at its prompt does not quit it, but is treated as if 'yes' was answered to the prompt and all following prompts, which is contrary to the user's intent. Fix the error check. Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- git-difftool--helper.sh | 3 ++- t/t7800-difftool.sh | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index 7ef36b948..aca0413c2 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -49,7 +49,8 @@ launch_merge_tool () { else printf "Launch '%s' [Y/n]: " "$merge_tool" fi - if read ans && test "$ans" = n + read ans || return + if test "$ans" = n then return fi diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index dc30a514b..9cf5dc934 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -301,6 +301,14 @@ test_expect_success PERL 'say no to the second file' ' ! grep br2 output ' +test_expect_success PERL 'ending prompt input with EOF' ' + git difftool -x cat branch output && + ! grep master output && + ! grep branch output && + ! grep m2 output && + ! grep br2 output +' + test_expect_success PERL 'difftool --tool-help' ' git difftool --tool-help >output && grep tool output From 2b52123fcf840686b69e10807fd0f985ec4167f3 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Sun, 26 Oct 2014 18:15:42 -0700 Subject: [PATCH 2/2] difftool: add support for --trust-exit-code Teach difftool to exit when a diff tool returns a non-zero exit code when either --trust-exit-code is specified or difftool.trustExitCode is true. Forward exit codes from invoked diff tools to the caller when --trust-exit-code is used. Suggested-by: Adri Farr <14farresa@gmail.com> Helped-by: Johannes Sixt Signed-off-by: David Aguilar Signed-off-by: Junio C Hamano --- Documentation/git-difftool.txt | 14 +++++++++++ git-difftool--helper.sh | 6 +++++ git-difftool.perl | 12 ++++++++++ t/t7800-difftool.sh | 43 ++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+) diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt index 11887e63a..333cf6ff9 100644 --- a/Documentation/git-difftool.txt +++ b/Documentation/git-difftool.txt @@ -91,6 +91,15 @@ instead. `--no-symlinks` is the default on Windows. the default diff tool will be read from the configured `diff.guitool` variable instead of `diff.tool`. +--[no-]trust-exit-code:: + 'git-difftool' invokes a diff tool individually on each file. + Errors reported by the diff tool are ignored by default. + Use `--trust-exit-code` to make 'git-difftool' exit when an + invoked diff tool returns a non-zero exit code. ++ +'git-difftool' will forward the exit code of the invoked tool when +'--trust-exit-code' is used. + See linkgit:git-diff[1] for the full list of supported options. CONFIG VARIABLES @@ -116,6 +125,11 @@ See the `--tool=` option above for more details. difftool.prompt:: Prompt before each invocation of the diff tool. +difftool.trustExitCode:: + Exit difftool if the invoked diff tool returns a non-zero exit status. ++ +See the `--trust-exit-code` option above for more details. + SEE ALSO -------- linkgit:git-diff[1]:: diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index aca0413c2..d4fb6dfe1 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -85,6 +85,12 @@ else while test $# -gt 6 do launch_merge_tool "$1" "$2" "$5" + status=$? + if test "$status" != 0 && + test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true + then + exit $status + fi shift 7 done fi diff --git a/git-difftool.perl b/git-difftool.perl index 18ca61e8d..9a1054a2b 100755 --- a/git-difftool.perl +++ b/git-difftool.perl @@ -346,6 +346,7 @@ sub main symlinks => $^O ne 'cygwin' && $^O ne 'MSWin32' && $^O ne 'msys', tool_help => undef, + trust_exit_code => undef, ); GetOptions('g|gui!' => \$opts{gui}, 'd|dir-diff' => \$opts{dirdiff}, @@ -356,6 +357,8 @@ sub main 'no-symlinks' => sub { $opts{symlinks} = 0; }, 't|tool:s' => \$opts{difftool_cmd}, 'tool-help' => \$opts{tool_help}, + 'trust-exit-code' => \$opts{trust_exit_code}, + 'no-trust-exit-code' => sub { $opts{trust_exit_code} = 0; }, 'x|extcmd:s' => \$opts{extcmd}); if (defined($opts{help})) { @@ -387,6 +390,15 @@ sub main } } + if (!defined $opts{trust_exit_code}) { + $opts{trust_exit_code} = Git::config_bool('difftool.trustExitCode'); + } + if ($opts{trust_exit_code}) { + $ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'true'; + } else { + $ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'false'; + } + # In directory diff mode, 'git-difftool--helper' is called once # to compare the a/b directories. In file diff mode, 'git diff' # will invoke a separate instance of 'git-difftool--helper' for diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 9cf5dc934..69bde7aa2 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -76,6 +76,49 @@ test_expect_success PERL 'difftool forwards arguments to diff' ' rm for-diff ' +test_expect_success PERL 'difftool ignores exit code' ' + test_config difftool.error.cmd false && + git difftool -y -t error branch +' + +test_expect_success PERL 'difftool forwards exit code with --trust-exit-code' ' + test_config difftool.error.cmd false && + test_must_fail git difftool -y --trust-exit-code -t error branch +' + +test_expect_success PERL 'difftool honors difftool.trustExitCode = true' ' + test_config difftool.error.cmd false && + test_config difftool.trustExitCode true && + test_must_fail git difftool -y -t error branch +' + +test_expect_success PERL 'difftool honors difftool.trustExitCode = false' ' + test_config difftool.error.cmd false && + test_config difftool.trustExitCode false && + git difftool -y -t error branch +' + +test_expect_success PERL 'difftool ignores exit code with --no-trust-exit-code' ' + test_config difftool.error.cmd false && + test_config difftool.trustExitCode true && + git difftool -y --no-trust-exit-code -t error branch +' + +test_expect_success PERL 'difftool stops on error with --trust-exit-code' ' + test_when_finished "rm -f for-diff .git/fail-right-file" && + test_when_finished "git reset -- for-diff" && + write_script .git/fail-right-file <<-\EOF && + echo "$2" + exit 1 + EOF + >for-diff && + git add for-diff && + echo file >expect && + test_must_fail git difftool -y --trust-exit-code \ + --extcmd .git/fail-right-file branch >actual && + test_cmp expect actual +' + test_expect_success PERL 'difftool honors --gui' ' difftool_test_setup && test_config merge.tool bogus-tool &&