* [PATCH 9/9 v8] difftool: print list of valid tools with '--tool-help'
@ 2012-03-28 18:34 Tim Henigan
2012-03-28 18:58 ` Junio C Hamano
0 siblings, 1 reply; 5+ messages in thread
From: Tim Henigan @ 2012-03-28 18:34 UTC (permalink / raw)
To: gitster, git, davvid; +Cc: Tim Henigan
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>
---
This replaces 9/9 in the previous version of the series.
Changes in v8:
- Replaced 'glob' with 'File::Find'. Glob will fail if file paths include
spaces. Using File::Find overcomes that limitation.
- Added 'TOOL_MODE=DIFF' prior to calling 'git-mergetool--lib.sh'. This
insures that the shell script executes as designed.
- difftool now calls 'can_diff' from 'git-mergetool--lib.sh' to insure that
only tools that are capable of diffing are shown as valid options. For
example, 'tortoisemerge' cannot be used as a diff viewer.
- The list of tools shown to the user is now sorted.
Documentation/git-difftool.txt | 11 +++++-----
git-difftool.perl | 43 ++++++++++++++++++++++++++++++++++++++--
t/t7800-difftool.sh | 5 +++++
3 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index aba5e76..31fc2e3 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 0fa131c..15fd572 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -16,6 +16,7 @@ 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);
@@ -28,7 +29,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]
@@ -38,6 +39,40 @@ USAGE
exit($exitcode);
}
+sub print_tool_help
+{
+ my ($cmd, @found, @notfound, @tools);
+ my $gitpath = Git::exec_path();
+
+ find(sub { push(@tools, $_) unless (-d $_) }, "$gitpath/mergetools");
+
+ for (@tools) {
+ my $tool = $_;
+ next if ($tool eq "defaults");
+
+ $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
@@ -132,18 +167,22 @@ sub setup_dir_diff
# 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 478c1be..bbe71e5 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 &&
--
1.7.10.rc2.21.g8cb1a
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 9/9 v8] difftool: print list of valid tools with '--tool-help'
2012-03-28 18:34 [PATCH 9/9 v8] difftool: print list of valid tools with '--tool-help' Tim Henigan
@ 2012-03-28 18:58 ` Junio C Hamano
2012-03-28 19:48 ` Tim Henigan
0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2012-03-28 18:58 UTC (permalink / raw)
To: Tim Henigan; +Cc: git, davvid
Tim Henigan <tim.henigan@gmail.com> writes:
> Changes in v8:
> - Replaced 'glob' with 'File::Find'. Glob will fail if file paths include
> spaces. Using File::Find overcomes that limitation.
OK, but doesn't File::Find recurse into its subdirectories? If you create
a 'foo' directory there and drop a 'bar' script in it, is the rest of the
code prepared to give you "git difftool -t foo/bar"?
> - Added 'TOOL_MODE=DIFF' prior to calling 'git-mergetool--lib.sh'. This
> insures that the shell script executes as designed.
> - difftool now calls 'can_diff' from 'git-mergetool--lib.sh' to insure that
> only tools that are capable of diffing are shown as valid options. For
> example, 'tortoisemerge' cannot be used as a diff viewer.
Good that you caught these brown-paper-bag bugs ;-) It feels a bit awkward
that nobody pointed these out, even though the series has been queued in
'pu' since its early iterations.
> diff --git a/git-difftool.perl b/git-difftool.perl
> index 0fa131c..15fd572 100755
> --- a/git-difftool.perl
> +++ b/git-difftool.perl
> @@ -38,6 +39,40 @@ USAGE
> exit($exitcode);
> }
>
> +sub print_tool_help
> +{
> + my ($cmd, @found, @notfound, @tools);
> + my $gitpath = Git::exec_path();
> +
> + find(sub { push(@tools, $_) unless (-d $_) }, "$gitpath/mergetools");
> +
> + for (@tools) {
> + my $tool = $_;
> + next if ($tool eq "defaults");
Now you use File::Find::find(), you probably should do this kind of
trivial filtering inside the callback, no?
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 9/9 v8] difftool: print list of valid tools with '--tool-help'
2012-03-28 18:58 ` Junio C Hamano
@ 2012-03-28 19:48 ` Tim Henigan
2012-03-28 20:02 ` Junio C Hamano
0 siblings, 1 reply; 5+ messages in thread
From: Tim Henigan @ 2012-03-28 19:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, davvid
On Wed, Mar 28, 2012 at 2:58 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Tim Henigan <tim.henigan@gmail.com> writes:
>
> OK, but doesn't File::Find recurse into its subdirectories? If you create
> a 'foo' directory there and drop a 'bar' script in it, is the rest of the
> code prepared to give you "git difftool -t foo/bar"?
It does recurse, but in this context '$_' only contains the current
file name within the directory...not the directory itself [1]. So if
we call 'find' on a directory that contains:
foo
bar/
baz
then @tools = ('foo', 'baz')
[1]: http://perldoc.perl.org/File/Find.html#The-wanted-function
>> + for (@tools) {
>> + my $tool = $_;
>> + next if ($tool eq "defaults");
>
> Now you use File::Find::find(), you probably should do this kind of
> trivial filtering inside the callback, no?
I thought about that, but the filter is so simple that it seemed like
overkill to add another function. If there is another revision of
this patch, I will reconsider.
As always, thanks for the review :)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 9/9 v8] difftool: print list of valid tools with '--tool-help'
2012-03-28 19:48 ` Tim Henigan
@ 2012-03-28 20:02 ` Junio C Hamano
2012-03-28 20:16 ` Tim Henigan
0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2012-03-28 20:02 UTC (permalink / raw)
To: Tim Henigan; +Cc: Junio C Hamano, git, davvid
Tim Henigan <tim.henigan@gmail.com> writes:
> On Wed, Mar 28, 2012 at 2:58 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> Tim Henigan <tim.henigan@gmail.com> writes:
>>
>> OK, but doesn't File::Find recurse into its subdirectories? If you create
>> a 'foo' directory there and drop a 'bar' script in it, is the rest of the
>> code prepared to give you "git difftool -t foo/bar"?
>
> It does recurse, but in this context '$_' only contains the current
> file name within the directory...not the directory itself [1]. So if
> we call 'find' on a directory that contains:
>
> foo
> bar/
> baz
>
> then @tools = ('foo', 'baz')
That is even worse, no? Is the rest of the code prepared to give you "git
difftool -t baz" in such a layout? What if you have another baz next to
foo and bar?
What I was hinting at was that you may want to $File::Find::prune=1 when
you find a subdirectory. While at it, you may also want to replace
the "unless -d $_" with "if -f $_ && -x _" or something.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 9/9 v8] difftool: print list of valid tools with '--tool-help'
2012-03-28 20:02 ` Junio C Hamano
@ 2012-03-28 20:16 ` Tim Henigan
0 siblings, 0 replies; 5+ messages in thread
From: Tim Henigan @ 2012-03-28 20:16 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, davvid
On Wed, Mar 28, 2012 at 4:02 PM, Junio C Hamano <gitster@pobox.com> wrote:
>
> That is even worse, no? Is the rest of the code prepared to give you "git
> difftool -t baz" in such a layout? What if you have another baz next to
> foo and bar?
>
> What I was hinting at was that you may want to $File::Find::prune=1 when
> you find a subdirectory. While at it, you may also want to replace
> the "unless -d $_" with "if -f $_ && -x _" or something.
I see now...sorry I missed your obvious point. I will look into this further.
The script makes some assumptions right now:
1) All tool config scripts must be located in "$(git --exec-path)/mergetools".
2) There is only one tool config in each script
- See my other other recent patch that splits vim/gvim [1]
3) The name of the tool script matches the name of the tool itself.
Do these assumptions seem reasonable? If so, perhaps I should add a
README to the mergetools directory that outlines these assumptions?
[1]: http://thread.gmane.org/gmane.comp.version-control.git/194179
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-03-28 20:16 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-28 18:34 [PATCH 9/9 v8] difftool: print list of valid tools with '--tool-help' Tim Henigan
2012-03-28 18:58 ` Junio C Hamano
2012-03-28 19:48 ` Tim Henigan
2012-03-28 20:02 ` Junio C Hamano
2012-03-28 20:16 ` Tim Henigan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.