summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Henigan <tim.henigan@gmail.com>2012-03-29 09:39:18 -0400
committerJunio C Hamano <gitster@pobox.com>2012-04-23 12:00:42 -0700
commitbf73fc212a159210398b6d46ed5e9101c650e7db (patch)
tree9f53002fc3812a60ff11368b17cfbcd6d89b76c3
parent7e0abcec103b3649943b236881cf88e8fd6cf3a4 (diff)
downloadgit-bf73fc212a159210398b6d46ed5e9101c650e7db.tar.gz
difftool: print list of valid tools with '--tool-help'
Since bc7a96a (mergetool--lib: Refactor tools into separate files, 2011-08-18), it is possible to add a new diff tool by creating a simple script in the '$(git --exec-path)/mergetools' directory. Updating the difftool help text is still a manual process, and the documentation can easily go out of sync. This commit teaches difftool the '--tool-help' option, which: - Reads the list of valid tools from 'mergetools/*' - Determines which of them are actually installed - Determines which are capable of diffing (i.e. not just a merge tool) - Prints the resulting list for the user Signed-off-by: Tim Henigan <tim.henigan@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/git-difftool.txt11
-rwxr-xr-xgit-difftool.perl55
-rwxr-xr-xt/t7800-difftool.sh5
3 files changed, 64 insertions, 7 deletions
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index aba5e76c52..31fc2e3aed 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -36,11 +36,9 @@ OPTIONS
-t <tool>::
--tool=<tool>::
- Use the diff tool specified by <tool>.
- Valid diff tools are:
- araxis, bc3, deltawalker, diffuse, emerge, ecmerge, gvimdiff,
- kdiff3, kompare, meld, opendiff, p4merge, tkdiff, vimdiff and
- xxdiff.
+ Use the diff tool specified by <tool>. Valid values include
+ emerge, kompare, meld, and vimdiff. Run `git difftool --tool-help`
+ for the list of valid <tool> settings.
+
If a diff tool is not specified, 'git difftool'
will use the configuration variable `diff.tool`. If the
@@ -68,6 +66,9 @@ of the diff post-image. `$MERGED` is the name of the file which is
being compared. `$BASE` is provided for compatibility
with custom merge tool commands and has the same value as `$MERGED`.
+--tool-help::
+ Print a list of diff tools that may be used with `--tool`.
+
-x <command>::
--extcmd=<command>::
Specify a custom command for viewing diffs.
diff --git a/git-difftool.perl b/git-difftool.perl
index 850ebbe571..ae1e0525d8 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -15,12 +15,14 @@ use strict;
use warnings;
use File::Basename qw(dirname);
use File::Copy;
+use File::Find;
use File::stat;
use File::Path qw(mkpath);
use File::Temp qw(tempdir);
use Getopt::Long qw(:config pass_through);
use Git;
+my @tools;
my @working_tree;
my $rc;
my $repo = Git->repository();
@@ -30,7 +32,7 @@ sub usage
{
my $exitcode = shift;
print << 'USAGE';
-usage: git difftool [-t|--tool=<tool>]
+usage: git difftool [-t|--tool=<tool>] [--tool-help]
[-x|--extcmd=<cmd>]
[-g|--gui] [--no-gui]
[--prompt] [-y|--no-prompt]
@@ -62,6 +64,51 @@ sub find_worktree
my $workdir = find_worktree();
+sub filter_tool_scripts
+{
+ if (-d $_) {
+ if ($_ ne ".") {
+ # Ignore files in subdirectories
+ $File::Find::prune = 1;
+ }
+ } else {
+ if ((-f $_) && ($_ ne "defaults")) {
+ push(@tools, $_);
+ }
+ }
+}
+
+sub print_tool_help
+{
+ my ($cmd, @found, @notfound);
+ my $gitpath = Git::exec_path();
+
+ find(\&filter_tool_scripts, "$gitpath/mergetools");
+
+ foreach my $tool (@tools) {
+ $cmd = "TOOL_MODE=diff";
+ $cmd .= ' && . "$(git --exec-path)/git-mergetool--lib"';
+ $cmd .= " && get_merge_tool_path $tool >/dev/null 2>&1";
+ $cmd .= " && can_diff >/dev/null 2>&1";
+ if (system('sh', '-c', $cmd) == 0) {
+ push(@found, $tool);
+ } else {
+ push(@notfound, $tool);
+ }
+ }
+
+ print "'git difftool --tool=<tool>' may be set to one of the following:\n";
+ print "\t$_\n" for (sort(@found));
+
+ print "\nThe following tools are valid, but not currently available:\n";
+ print "\t$_\n" for (sort(@notfound));
+
+ print "\nNOTE: Some of the tools listed above only work in a windowed\n";
+ print "environment. If run in a terminal-only session, they will fail.\n";
+
+ exit(0);
+}
+
sub setup_dir_diff
{
# Run the diff; exit immediately if no diff found
@@ -230,18 +277,22 @@ sub write_to_file
# parse command-line options. all unrecognized options and arguments
# are passed through to the 'git diff' command.
-my ($difftool_cmd, $dirdiff, $extcmd, $gui, $help, $prompt);
+my ($difftool_cmd, $dirdiff, $extcmd, $gui, $help, $prompt, $tool_help);
GetOptions('g|gui!' => \$gui,
'd|dir-diff' => \$dirdiff,
'h' => \$help,
'prompt!' => \$prompt,
'y' => sub { $prompt = 0; },
't|tool:s' => \$difftool_cmd,
+ 'tool-help' => \$tool_help,
'x|extcmd:s' => \$extcmd);
if (defined($help)) {
usage(0);
}
+if (defined($tool_help)) {
+ print_tool_help();
+}
if (defined($difftool_cmd)) {
if (length($difftool_cmd) > 0) {
$ENV{GIT_DIFF_TOOL} = $difftool_cmd;
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 478c1bef37..bbe71e5f73 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -319,6 +319,11 @@ test_expect_success PERL 'say no to the second file' '
echo "$diff" | stdin_doesnot_contain br2
'
+test_expect_success PERL 'difftool --tool-help' '
+ tool_help=$(git difftool --tool-help) &&
+ echo "$tool_help" | stdin_contains tool
+'
+
test_expect_success PERL 'setup change in subdirectory' '
git checkout master &&
mkdir sub &&