Merge branch 'da/difftool'
authorJunio C Hamano <gitster@pobox.com>
Wed, 29 Oct 2014 17:09:35 +0000 (10:09 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 29 Oct 2014 17:09:35 +0000 (10:09 -0700)
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

Documentation/git-difftool.txt
git-difftool--helper.sh
git-difftool.perl
t/t7800-difftool.sh
index 11887e63a05904d95f7d07d51b818721b33c0b66..333cf6ff91c59fd96b587257ad413268df9a1458 100644 (file)
@@ -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=<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]::
index 7ef36b9482ccc4111f2c888bf5ccbaa2421a5875..d4fb6dfe138fffd4d000c7d5aeb7787bea9970f4 100755 (executable)
@@ -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
@@ -84,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
index 598fcc23b930832a8cd3cfcff0c0d0c84ecd32bc..7df7c8a9a7c889fbf5f0b2d6e67be66bf6fea6b1 100755 (executable)
@@ -342,6 +342,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},
@@ -352,6 +353,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})) {
@@ -383,6 +386,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
index dc30a514bf681dde44dea32e671632ef6f0a47a7..69bde7aa288d1deebb7d6204e29f88978d880998 100755 (executable)
@@ -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 &&
@@ -301,6 +344,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 </dev/null >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