Skip to content

Commit bf73fc2

Browse files
thenigangitster
authored andcommitted
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>
1 parent 7e0abce commit bf73fc2

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

Documentation/git-difftool.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,9 @@ OPTIONS
3636

3737
-t <tool>::
3838
--tool=<tool>::
39-
Use the diff tool specified by <tool>.
40-
Valid diff tools are:
41-
araxis, bc3, deltawalker, diffuse, emerge, ecmerge, gvimdiff,
42-
kdiff3, kompare, meld, opendiff, p4merge, tkdiff, vimdiff and
43-
xxdiff.
39+
Use the diff tool specified by <tool>. Valid values include
40+
emerge, kompare, meld, and vimdiff. Run `git difftool --tool-help`
41+
for the list of valid <tool> settings.
4442
+
4543
If a diff tool is not specified, 'git difftool'
4644
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
6866
being compared. `$BASE` is provided for compatibility
6967
with custom merge tool commands and has the same value as `$MERGED`.
7068

69+
--tool-help::
70+
Print a list of diff tools that may be used with `--tool`.
71+
7172
-x <command>::
7273
--extcmd=<command>::
7374
Specify a custom command for viewing diffs.

git-difftool.perl

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
use warnings;
1616
use File::Basename qw(dirname);
1717
use File::Copy;
18+
use File::Find;
1819
use File::stat;
1920
use File::Path qw(mkpath);
2021
use File::Temp qw(tempdir);
2122
use Getopt::Long qw(:config pass_through);
2223
use Git;
2324

25+
my @tools;
2426
my @working_tree;
2527
my $rc;
2628
my $repo = Git->repository();
@@ -30,7 +32,7 @@ sub usage
3032
{
3133
my $exitcode = shift;
3234
print << 'USAGE';
33-
usage: git difftool [-t|--tool=<tool>]
35+
usage: git difftool [-t|--tool=<tool>] [--tool-help]
3436
[-x|--extcmd=<cmd>]
3537
[-g|--gui] [--no-gui]
3638
[--prompt] [-y|--no-prompt]
@@ -62,6 +64,51 @@ sub find_worktree
6264

6365
my $workdir = find_worktree();
6466

67+
sub filter_tool_scripts
68+
{
69+
if (-d $_) {
70+
if ($_ ne ".") {
71+
# Ignore files in subdirectories
72+
$File::Find::prune = 1;
73+
}
74+
} else {
75+
if ((-f $_) && ($_ ne "defaults")) {
76+
push(@tools, $_);
77+
}
78+
}
79+
}
80+
81+
sub print_tool_help
82+
{
83+
my ($cmd, @found, @notfound);
84+
my $gitpath = Git::exec_path();
85+
86+
find(\&filter_tool_scripts, "$gitpath/mergetools");
87+
88+
foreach my $tool (@tools) {
89+
$cmd = "TOOL_MODE=diff";
90+
$cmd .= ' && . "$(git --exec-path)/git-mergetool--lib"';
91+
$cmd .= " && get_merge_tool_path $tool >/dev/null 2>&1";
92+
$cmd .= " && can_diff >/dev/null 2>&1";
93+
if (system('sh', '-c', $cmd) == 0) {
94+
push(@found, $tool);
95+
} else {
96+
push(@notfound, $tool);
97+
}
98+
}
99+
100+
print "'git difftool --tool=<tool>' may be set to one of the following:\n";
101+
print "\t$_\n" for (sort(@found));
102+
103+
print "\nThe following tools are valid, but not currently available:\n";
104+
print "\t$_\n" for (sort(@notfound));
105+
106+
print "\nNOTE: Some of the tools listed above only work in a windowed\n";
107+
print "environment. If run in a terminal-only session, they will fail.\n";
108+
109+
exit(0);
110+
}
111+
65112
sub setup_dir_diff
66113
{
67114
# Run the diff; exit immediately if no diff found
@@ -230,18 +277,22 @@ sub write_to_file
230277

231278
# parse command-line options. all unrecognized options and arguments
232279
# are passed through to the 'git diff' command.
233-
my ($difftool_cmd, $dirdiff, $extcmd, $gui, $help, $prompt);
280+
my ($difftool_cmd, $dirdiff, $extcmd, $gui, $help, $prompt, $tool_help);
234281
GetOptions('g|gui!' => \$gui,
235282
'd|dir-diff' => \$dirdiff,
236283
'h' => \$help,
237284
'prompt!' => \$prompt,
238285
'y' => sub { $prompt = 0; },
239286
't|tool:s' => \$difftool_cmd,
287+
'tool-help' => \$tool_help,
240288
'x|extcmd:s' => \$extcmd);
241289

242290
if (defined($help)) {
243291
usage(0);
244292
}
293+
if (defined($tool_help)) {
294+
print_tool_help();
295+
}
245296
if (defined($difftool_cmd)) {
246297
if (length($difftool_cmd) > 0) {
247298
$ENV{GIT_DIFF_TOOL} = $difftool_cmd;

t/t7800-difftool.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,11 @@ test_expect_success PERL 'say no to the second file' '
319319
echo "$diff" | stdin_doesnot_contain br2
320320
'
321321

322+
test_expect_success PERL 'difftool --tool-help' '
323+
tool_help=$(git difftool --tool-help) &&
324+
echo "$tool_help" | stdin_contains tool
325+
'
326+
322327
test_expect_success PERL 'setup change in subdirectory' '
323328
git checkout master &&
324329
mkdir sub &&

0 commit comments

Comments
 (0)