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>
			
			
				maint
			
			
		
							parent
							
								
									7e0abcec10
								
							
						
					
					
						commit
						bf73fc212a
					
				|  | @ -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. | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 && | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Tim Henigan
						Tim Henigan