Merge branch 'da/difftool'
authorJunio C Hamano <gitster@pobox.com>
Wed, 20 Jan 2010 22:42:20 +0000 (14:42 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Jan 2010 22:42:20 +0000 (14:42 -0800)
* da/difftool:
difftool: Update copyright notices to list each year separately
difftool: Use eval to expand '--extcmd' expressions
difftool: Add '-x' and as an alias for '--extcmd'
t7800-difftool.sh: Simplify the --extcmd test
git-diff.txt: Link to git-difftool
difftool: Allow specifying unconfigured commands with --extcmd
difftool--helper: Remove use of the GIT_MERGE_TOOL variable
difftool--helper: Update copyright and remove distracting comments
git-difftool: Add '--gui' for selecting a GUI tool
t7800-difftool: Set a bogus tool for use by tests

Documentation/git-diff.txt
Documentation/git-difftool.txt
git-difftool--helper.sh
git-difftool.perl
t/t7800-difftool.sh
index 0ac711230e24bf7238b2e3a215cdc3c4ce0d2087..723a64872fd4b43612d576781d915a7538189f46 100644 (file)
@@ -157,6 +157,10 @@ $ git diff -R                          <2>
 rewrites (very expensive).
 <2> Output diff in reverse.
 
+SEE ALSO
+--------
+linkgit:git-difftool[1]::
+       Show changes using common diff tools
 
 Author
 ------
index 8e9aed67d7f68c0234ee47dc147736bf3b8e5c4f..5c68cff9058654aff4657cd5f86f8dc2682eccde 100644 (file)
@@ -7,7 +7,7 @@ git-difftool - Show changes using common diff tools
 
 SYNOPSIS
 --------
-'git difftool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<'git diff' options>]
+'git difftool' [<options>] <commit>{0,2} [--] [<path>...]
 
 DESCRIPTION
 -----------
@@ -58,6 +58,18 @@ is set to the name of the temporary file containing the contents
 of the diff post-image.  `$BASE` is provided for compatibility
 with custom merge tool commands and has the same value as `$LOCAL`.
 
+-x <command>::
+--extcmd=<command>::
+       Specify a custom command for viewing diffs.
+       'git-difftool' ignores the configured defaults and runs
+       `$command $LOCAL $REMOTE` when this option is specified.
+
+-g::
+--gui::
+       When 'git-difftool' is invoked with the `-g` or `--gui` option
+       the default diff tool will be read from the configured
+       `diff.guitool` variable instead of `diff.tool`.
+
 See linkgit:git-diff[1] for the full list of supported options.
 
 CONFIG VARIABLES
@@ -68,6 +80,9 @@ difftool equivalents have not been defined.
 diff.tool::
        The default diff tool to use.
 
+diff.guitool::
+       The default diff tool to use when `--gui` is specified.
+
 difftool.<tool>.path::
        Override the path for the given tool.  This is useful in case
        your tool is not in the PATH.
index 57e8e3256d7b6578cda37815163d8945431aa6db..e43b5d64de3d06f96063f61d4907a8a95ed1c23b 100755 (executable)
@@ -3,9 +3,8 @@
 # This script is typically launched by using the 'git difftool'
 # convenience command.
 #
-# Copyright (c) 2009 David Aguilar
+# Copyright (c) 2009, 2010 David Aguilar
 
-# Load common functions from git-mergetool--lib
 TOOL_MODE=diff
 . git-mergetool--lib
 
@@ -20,7 +19,11 @@ should_prompt () {
        fi
 }
 
-# Sets up shell variables and runs a merge tool
+# Indicates that --extcmd=... was specified
+use_ext_cmd () {
+       test -n "$GIT_DIFFTOOL_EXTCMD"
+}
+
 launch_merge_tool () {
        # Merged is the filename as it appears in the work tree
        # Local is the contents of a/filename
@@ -35,20 +38,28 @@ launch_merge_tool () {
        # the user with the real $MERGED name before launching $merge_tool.
        if should_prompt; then
                printf "\nViewing: '$MERGED'\n"
-               printf "Hit return to launch '%s': " "$merge_tool"
+               if use_ext_cmd; then
+                       printf "Hit return to launch '%s': " \
+                               "$GIT_DIFFTOOL_EXTCMD"
+               else
+                       printf "Hit return to launch '%s': " "$merge_tool"
+               fi
                read ans
        fi
 
-       # Run the appropriate merge tool command
-       run_merge_tool "$merge_tool"
+       if use_ext_cmd; then
+               eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
+       else
+               run_merge_tool "$merge_tool"
+       fi
 }
 
-# Allow GIT_DIFF_TOOL and GIT_MERGE_TOOL to provide default values
-test -n "$GIT_MERGE_TOOL" && merge_tool="$GIT_MERGE_TOOL"
-test -n "$GIT_DIFF_TOOL" && merge_tool="$GIT_DIFF_TOOL"
-
-if test -z "$merge_tool"; then
-       merge_tool="$(get_merge_tool)" || exit
+if ! use_ext_cmd; then
+       if test -n "$GIT_DIFF_TOOL"; then
+               merge_tool="$GIT_DIFF_TOOL"
+       else
+               merge_tool="$(get_merge_tool)" || exit
+       fi
 fi
 
 # Launch the merge tool on each path provided by 'git diff'
index ba5e60a45e2c4a8b54e6a58e656b3978dcb45633..d975d072dbf0fab36266c3f3a71a69875206e4d8 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
-# Copyright (c) 2009 David Aguilar
+# Copyright (c) 2009, 2010 David Aguilar
 #
 # This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
 # git-difftool--helper script.
 use Cwd qw(abs_path);
 use File::Basename qw(dirname);
 
+require Git;
+
 my $DIR = abs_path(dirname($0));
 
 
 sub usage
 {
        print << 'USAGE';
-usage: git difftool [--tool=<tool>] [-y|--no-prompt] ["git diff" options]
+usage: git difftool [-t|--tool=<tool>] [-x|--extcmd=<cmd>]
+                    [-y|--no-prompt]   [-g|--gui]
+                    ['git diff' options]
 USAGE
        exit 1;
 }
@@ -63,6 +67,24 @@ sub generate_command
                        $ENV{GIT_DIFF_TOOL} = substr($arg, 7);
                        next;
                }
+               if ($arg eq '-x' || $arg eq '--extcmd') {
+                       usage() if $#ARGV <= $idx;
+                       $ENV{GIT_DIFFTOOL_EXTCMD} = $ARGV[$idx + 1];
+                       $skip_next = 1;
+                       next;
+               }
+               if ($arg =~ /^--extcmd=/) {
+                       $ENV{GIT_DIFFTOOL_EXTCMD} = substr($arg, 9);
+                       next;
+               }
+               if ($arg eq '-g' || $arg eq '--gui') {
+                       my $tool = Git::command_oneline('config',
+                                                       'diff.guitool');
+                       if (length($tool)) {
+                               $ENV{GIT_DIFF_TOOL} = $tool;
+                       }
+                       next;
+               }
                if ($arg eq '-y' || $arg eq '--no-prompt') {
                        $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
                        delete $ENV{GIT_DIFFTOOL_PROMPT};
index fff6a6d0eab4b27d5bc7ff4636913cb10296ab7b..fad54722575b70345d42628702c3519d6d413fae 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright (c) 2009 David Aguilar
+# Copyright (c) 2009, 2010 David Aguilar
 #
 
 test_description='git-difftool
@@ -15,10 +15,14 @@ if ! test_have_prereq PERL; then
        test_done
 fi
 
+LF='
+'
+
 remove_config_vars()
 {
        # Unset all config variables used by git-difftool
        git config --unset diff.tool
+       git config --unset diff.guitool
        git config --unset difftool.test-tool.cmd
        git config --unset difftool.prompt
        git config --unset merge.tool
@@ -31,11 +35,11 @@ restore_test_defaults()
        # Restores the test defaults used by several tests
        remove_config_vars
        unset GIT_DIFF_TOOL
-       unset GIT_MERGE_TOOL
        unset GIT_DIFFTOOL_PROMPT
        unset GIT_DIFFTOOL_NO_PROMPT
        git config diff.tool test-tool &&
        git config difftool.test-tool.cmd 'cat $LOCAL'
+       git config difftool.bogus-tool.cmd false
 }
 
 prompt_given()
@@ -71,11 +75,22 @@ test_expect_success 'custom commands' '
 
 # Ensures that git-difftool ignores bogus --tool values
 test_expect_success 'difftool ignores bad --tool values' '
-       diff=$(git difftool --no-prompt --tool=bogus-tool branch)
+       diff=$(git difftool --no-prompt --tool=bad-tool branch)
        test "$?" = 1 &&
        test "$diff" = ""
 '
 
+test_expect_success 'difftool honors --gui' '
+       git config merge.tool bogus-tool &&
+       git config diff.tool bogus-tool &&
+       git config diff.guitool test-tool &&
+
+       diff=$(git difftool --no-prompt --gui branch) &&
+       test "$diff" = "branch" &&
+
+       restore_test_defaults
+'
+
 # Specify the diff tool using $GIT_DIFF_TOOL
 test_expect_success 'GIT_DIFF_TOOL variable' '
        git config --unset diff.tool
@@ -94,15 +109,7 @@ test_expect_success 'GIT_DIFF_TOOL overrides' '
        git config diff.tool bogus-tool &&
        git config merge.tool bogus-tool &&
 
-       GIT_MERGE_TOOL=test-tool &&
-       export GIT_MERGE_TOOL &&
-       diff=$(git difftool --no-prompt branch) &&
-       test "$diff" = "branch" &&
-       unset GIT_MERGE_TOOL &&
-
-       GIT_MERGE_TOOL=bogus-tool &&
        GIT_DIFF_TOOL=test-tool &&
-       export GIT_MERGE_TOOL &&
        export GIT_DIFF_TOOL &&
 
        diff=$(git difftool --no-prompt branch) &&
@@ -210,7 +217,39 @@ test_expect_success 'difftool.<tool>.path' '
        diff=$(git difftool --tool=tkdiff --no-prompt branch) &&
        git config --unset difftool.tkdiff.path &&
        lines=$(echo "$diff" | grep file | wc -l) &&
-       test "$lines" -eq 1
+       test "$lines" -eq 1 &&
+
+       restore_test_defaults
+'
+
+test_expect_success 'difftool --extcmd=cat' '
+       diff=$(git difftool --no-prompt --extcmd=cat branch) &&
+       test "$diff" = branch"$LF"master
+'
+
+test_expect_success 'difftool --extcmd cat' '
+       diff=$(git difftool --no-prompt --extcmd cat branch) &&
+       test "$diff" = branch"$LF"master
+'
+
+test_expect_success 'difftool -x cat' '
+       diff=$(git difftool --no-prompt -x cat branch) &&
+       test "$diff" = branch"$LF"master
+'
+
+test_expect_success 'difftool --extcmd echo arg1' '
+       diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"echo\ \$1\" branch)
+       test "$diff" = file
+'
+
+test_expect_success 'difftool --extcmd cat arg1' '
+       diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$1\" branch)
+       test "$diff" = master
+'
+
+test_expect_success 'difftool --extcmd cat arg2' '
+       diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$2\" branch)
+       test "$diff" = branch
 '
 
 test_done