Merge branch 'da/difftool'
* da/difftool: mergetool--lib: simplify API usage by removing more global variables Fix misspelled mergetool.keepBackup difftool/mergetool: refactor commands to use git-mergetool--lib mergetool: use $( ... ) instead of `backticks` bash completion: add git-difftool difftool: add support for a difftool.prompt config variable difftool: add various git-difftool tests difftool: move 'git-difftool' out of contrib difftool/mergetool: add diffuse as merge and diff tool difftool: add a -y shortcut for --no-prompt difftool: use perl built-ins when testing for msys difftool: remove the backup file feature difftool: remove merge options for opendiff, tkdiff, kdiff3 and xxdiff git-mergetool: add new merge tool TortoiseMerge git-mergetool/difftool: make (g)vimdiff workable under Windows doc/merge-config: list ecmerge as a built-in merge tool
This commit is contained in:
@ -910,6 +910,26 @@ _git_diff ()
|
||||
__git_complete_file
|
||||
}
|
||||
|
||||
__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
|
||||
tkdiff vimdiff gvimdiff xxdiff
|
||||
"
|
||||
|
||||
_git_difftool ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--tool=*)
|
||||
__gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
|
||||
return
|
||||
;;
|
||||
--*)
|
||||
__gitcomp "--tool="
|
||||
return
|
||||
;;
|
||||
esac
|
||||
COMPREPLY=()
|
||||
}
|
||||
|
||||
__git_fetch_options="
|
||||
--quiet --verbose --append --upload-pack --force --keep --depth=
|
||||
--tags --no-tags
|
||||
@ -1172,10 +1192,7 @@ _git_mergetool ()
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--tool=*)
|
||||
__gitcomp "
|
||||
kdiff3 tkdiff meld xxdiff emerge
|
||||
vimdiff gvimdiff ecmerge opendiff
|
||||
" "" "${cur##--tool=}"
|
||||
__gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
|
||||
return
|
||||
;;
|
||||
--*)
|
||||
@ -1901,6 +1918,7 @@ _git ()
|
||||
config) _git_config ;;
|
||||
describe) _git_describe ;;
|
||||
diff) _git_diff ;;
|
||||
difftool) _git_difftool ;;
|
||||
fetch) _git_fetch ;;
|
||||
format-patch) _git_format_patch ;;
|
||||
fsck) _git_fsck ;;
|
||||
|
@ -1,73 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright (c) 2009 David Aguilar
|
||||
#
|
||||
# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
|
||||
# git-difftool-helper script. This script exports
|
||||
# GIT_EXTERNAL_DIFF and GIT_PAGER for use by git, and
|
||||
# GIT_DIFFTOOL_NO_PROMPT and GIT_DIFF_TOOL for use by git-difftool-helper.
|
||||
# Any arguments that are unknown to this script are forwarded to 'git diff'.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname);
|
||||
|
||||
my $DIR = abs_path(dirname($0));
|
||||
|
||||
|
||||
sub usage
|
||||
{
|
||||
print << 'USAGE';
|
||||
usage: git difftool [--tool=<tool>] [--no-prompt] ["git diff" options]
|
||||
USAGE
|
||||
exit 1;
|
||||
}
|
||||
|
||||
sub setup_environment
|
||||
{
|
||||
$ENV{PATH} = "$DIR:$ENV{PATH}";
|
||||
$ENV{GIT_PAGER} = '';
|
||||
$ENV{GIT_EXTERNAL_DIFF} = 'git-difftool-helper';
|
||||
}
|
||||
|
||||
sub exe
|
||||
{
|
||||
my $exe = shift;
|
||||
return defined $ENV{COMSPEC} ? "$exe.exe" : $exe;
|
||||
}
|
||||
|
||||
sub generate_command
|
||||
{
|
||||
my @command = (exe('git'), 'diff');
|
||||
my $skip_next = 0;
|
||||
my $idx = -1;
|
||||
for my $arg (@ARGV) {
|
||||
$idx++;
|
||||
if ($skip_next) {
|
||||
$skip_next = 0;
|
||||
next;
|
||||
}
|
||||
if ($arg eq '-t' or $arg eq '--tool') {
|
||||
usage() if $#ARGV <= $idx;
|
||||
$ENV{GIT_DIFF_TOOL} = $ARGV[$idx + 1];
|
||||
$skip_next = 1;
|
||||
next;
|
||||
}
|
||||
if ($arg =~ /^--tool=/) {
|
||||
$ENV{GIT_DIFF_TOOL} = substr($arg, 7);
|
||||
next;
|
||||
}
|
||||
if ($arg eq '--no-prompt') {
|
||||
$ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
|
||||
next;
|
||||
}
|
||||
if ($arg eq '-h' or $arg eq '--help') {
|
||||
usage();
|
||||
}
|
||||
push @command, $arg;
|
||||
}
|
||||
return @command
|
||||
}
|
||||
|
||||
setup_environment();
|
||||
exec(generate_command());
|
@ -1,249 +0,0 @@
|
||||
#!/bin/sh
|
||||
# git-difftool-helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher.
|
||||
# It supports kdiff3, kompare, tkdiff, xxdiff, meld, opendiff,
|
||||
# emerge, ecmerge, vimdiff, gvimdiff, and custom user-configurable tools.
|
||||
# This script is typically launched by using the 'git difftool'
|
||||
# convenience command.
|
||||
#
|
||||
# Copyright (c) 2009 David Aguilar
|
||||
|
||||
# Set GIT_DIFFTOOL_NO_PROMPT to bypass the per-file prompt.
|
||||
should_prompt () {
|
||||
! test -n "$GIT_DIFFTOOL_NO_PROMPT"
|
||||
}
|
||||
|
||||
# Should we keep the backup .orig file?
|
||||
keep_backup_mode="$(git config --bool merge.keepBackup || echo true)"
|
||||
keep_backup () {
|
||||
test "$keep_backup_mode" = "true"
|
||||
}
|
||||
|
||||
# This function manages the backup .orig file.
|
||||
# A backup $MERGED.orig file is created if changes are detected.
|
||||
cleanup_temp_files () {
|
||||
if test -n "$MERGED"; then
|
||||
if keep_backup && test "$MERGED" -nt "$BACKUP"; then
|
||||
test -f "$BACKUP" && mv -- "$BACKUP" "$MERGED.orig"
|
||||
else
|
||||
rm -f -- "$BACKUP"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# This is called when users Ctrl-C out of git-difftool-helper
|
||||
sigint_handler () {
|
||||
cleanup_temp_files
|
||||
exit 1
|
||||
}
|
||||
|
||||
# This function prepares temporary files and launches the appropriate
|
||||
# merge tool.
|
||||
launch_merge_tool () {
|
||||
# Merged is the filename as it appears in the work tree
|
||||
# Local is the contents of a/filename
|
||||
# Remote is the contents of b/filename
|
||||
# Custom merge tool commands might use $BASE so we provide it
|
||||
MERGED="$1"
|
||||
LOCAL="$2"
|
||||
REMOTE="$3"
|
||||
BASE="$1"
|
||||
ext="$$$(expr "$MERGED" : '.*\(\.[^/]*\)$')"
|
||||
BACKUP="$MERGED.BACKUP.$ext"
|
||||
|
||||
# Create and ensure that we clean up $BACKUP
|
||||
test -f "$MERGED" && cp -- "$MERGED" "$BACKUP"
|
||||
trap sigint_handler INT
|
||||
|
||||
# $LOCAL and $REMOTE are temporary files so prompt
|
||||
# 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"
|
||||
read ans
|
||||
fi
|
||||
|
||||
# Run the appropriate merge tool command
|
||||
case "$merge_tool" in
|
||||
kdiff3)
|
||||
basename=$(basename "$MERGED")
|
||||
"$merge_tool_path" --auto \
|
||||
--L1 "$basename (A)" \
|
||||
--L2 "$basename (B)" \
|
||||
-o "$MERGED" "$LOCAL" "$REMOTE" \
|
||||
> /dev/null 2>&1
|
||||
;;
|
||||
|
||||
kompare)
|
||||
"$merge_tool_path" "$LOCAL" "$REMOTE"
|
||||
;;
|
||||
|
||||
tkdiff)
|
||||
"$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"
|
||||
;;
|
||||
|
||||
meld)
|
||||
"$merge_tool_path" "$LOCAL" "$REMOTE"
|
||||
;;
|
||||
|
||||
vimdiff)
|
||||
"$merge_tool_path" -c "wincmd l" "$LOCAL" "$REMOTE"
|
||||
;;
|
||||
|
||||
gvimdiff)
|
||||
"$merge_tool_path" -c "wincmd l" -f "$LOCAL" "$REMOTE"
|
||||
;;
|
||||
|
||||
xxdiff)
|
||||
"$merge_tool_path" \
|
||||
-X \
|
||||
-R 'Accel.SaveAsMerged: "Ctrl-S"' \
|
||||
-R 'Accel.Search: "Ctrl+F"' \
|
||||
-R 'Accel.SearchForward: "Ctrl-G"' \
|
||||
--merged-file "$MERGED" \
|
||||
"$LOCAL" "$REMOTE"
|
||||
;;
|
||||
|
||||
opendiff)
|
||||
"$merge_tool_path" "$LOCAL" "$REMOTE" \
|
||||
-merge "$MERGED" | cat
|
||||
;;
|
||||
|
||||
ecmerge)
|
||||
"$merge_tool_path" "$LOCAL" "$REMOTE" \
|
||||
--default --mode=merge2 --to="$MERGED"
|
||||
;;
|
||||
|
||||
emerge)
|
||||
"$merge_tool_path" -f emerge-files-command \
|
||||
"$LOCAL" "$REMOTE" "$(basename "$MERGED")"
|
||||
;;
|
||||
|
||||
*)
|
||||
if test -n "$merge_tool_cmd"; then
|
||||
( eval $merge_tool_cmd )
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
cleanup_temp_files
|
||||
}
|
||||
|
||||
# Verifies that (difftool|mergetool).<tool>.cmd exists
|
||||
valid_custom_tool() {
|
||||
merge_tool_cmd="$(git config difftool.$1.cmd)"
|
||||
test -z "$merge_tool_cmd" &&
|
||||
merge_tool_cmd="$(git config mergetool.$1.cmd)"
|
||||
test -n "$merge_tool_cmd"
|
||||
}
|
||||
|
||||
# Verifies that the chosen merge tool is properly setup.
|
||||
# Built-in merge tools are always valid.
|
||||
valid_tool() {
|
||||
case "$1" in
|
||||
kdiff3 | kompare | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)
|
||||
;; # happy
|
||||
*)
|
||||
if ! valid_custom_tool "$1"
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Sets up the merge_tool_path variable.
|
||||
# This handles the difftool.<tool>.path configuration.
|
||||
# This also falls back to mergetool defaults.
|
||||
init_merge_tool_path() {
|
||||
merge_tool_path=$(git config difftool."$1".path)
|
||||
test -z "$merge_tool_path" &&
|
||||
merge_tool_path=$(git config mergetool."$1".path)
|
||||
if test -z "$merge_tool_path"; then
|
||||
case "$1" in
|
||||
emerge)
|
||||
merge_tool_path=emacs
|
||||
;;
|
||||
*)
|
||||
merge_tool_path="$1"
|
||||
;;
|
||||
esac
|
||||
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 merge tool was not specified then use the diff.tool
|
||||
# configuration variable. If that's invalid then reset merge_tool.
|
||||
# Fallback to merge.tool.
|
||||
if test -z "$merge_tool"; then
|
||||
merge_tool=$(git config diff.tool)
|
||||
test -z "$merge_tool" &&
|
||||
merge_tool=$(git config merge.tool)
|
||||
if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
|
||||
echo >&2 "git config option diff.tool set to unknown tool: $merge_tool"
|
||||
echo >&2 "Resetting to default..."
|
||||
unset merge_tool
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try to guess an appropriate merge tool if no tool has been set.
|
||||
if test -z "$merge_tool"; then
|
||||
# We have a $DISPLAY so try some common UNIX merge tools
|
||||
if test -n "$DISPLAY"; then
|
||||
# If gnome then prefer meld, otherwise, prefer kdiff3 or kompare
|
||||
if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
|
||||
merge_tool_candidates="meld kdiff3 kompare tkdiff xxdiff gvimdiff"
|
||||
else
|
||||
merge_tool_candidates="kdiff3 kompare tkdiff xxdiff meld gvimdiff"
|
||||
fi
|
||||
fi
|
||||
if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
|
||||
# $EDITOR is emacs so add emerge as a candidate
|
||||
merge_tool_candidates="$merge_tool_candidates emerge opendiff vimdiff"
|
||||
elif echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then
|
||||
# $EDITOR is vim so add vimdiff as a candidate
|
||||
merge_tool_candidates="$merge_tool_candidates vimdiff opendiff emerge"
|
||||
else
|
||||
merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff"
|
||||
fi
|
||||
echo "merge tool candidates: $merge_tool_candidates"
|
||||
|
||||
# Loop over each candidate and stop when a valid merge tool is found.
|
||||
for i in $merge_tool_candidates
|
||||
do
|
||||
init_merge_tool_path $i
|
||||
if type "$merge_tool_path" > /dev/null 2>&1; then
|
||||
merge_tool=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if test -z "$merge_tool" ; then
|
||||
echo "No known merge resolution program available."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
else
|
||||
# A merge tool has been set, so verify that it's valid.
|
||||
if ! valid_tool "$merge_tool"; then
|
||||
echo >&2 "Unknown merge tool $merge_tool"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
init_merge_tool_path "$merge_tool"
|
||||
|
||||
if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
|
||||
echo "The merge tool $merge_tool is not available as '$merge_tool_path'"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# Launch the merge tool on each path provided by 'git diff'
|
||||
while test $# -gt 6
|
||||
do
|
||||
launch_merge_tool "$1" "$2" "$5"
|
||||
shift 7
|
||||
done
|
@ -1,105 +0,0 @@
|
||||
git-difftool(1)
|
||||
===============
|
||||
|
||||
NAME
|
||||
----
|
||||
git-difftool - compare changes using common merge tools
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git difftool' [--tool=<tool>] [--no-prompt] ['git diff' options]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
'git-difftool' is a git command that allows you to compare and edit files
|
||||
between revisions using common merge tools. At its most basic level,
|
||||
'git-difftool' does what 'git-mergetool' does but its use is for non-merge
|
||||
situations such as when preparing commits or comparing changes against
|
||||
the index.
|
||||
|
||||
'git difftool' is a frontend to 'git diff' and accepts the same
|
||||
arguments and options.
|
||||
|
||||
See linkgit:git-diff[1] for the full list of supported options.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
-t <tool>::
|
||||
--tool=<tool>::
|
||||
Use the merge resolution program specified by <tool>.
|
||||
Valid merge tools are:
|
||||
kdiff3, kompare, tkdiff, meld, xxdiff, emerge,
|
||||
vimdiff, gvimdiff, ecmerge, and opendiff
|
||||
+
|
||||
If a merge resolution program is not specified, 'git-difftool'
|
||||
will use the configuration variable `diff.tool`. If the
|
||||
configuration variable `diff.tool` is not set, 'git-difftool'
|
||||
will pick a suitable default.
|
||||
+
|
||||
You can explicitly provide a full path to the tool by setting the
|
||||
configuration variable `difftool.<tool>.path`. For example, you
|
||||
can configure the absolute path to kdiff3 by setting
|
||||
`difftool.kdiff3.path`. Otherwise, 'git-difftool' assumes the
|
||||
tool is available in PATH.
|
||||
+
|
||||
Instead of running one of the known merge tool programs,
|
||||
'git-difftool' can be customized to run an alternative program
|
||||
by specifying the command line to invoke in a configuration
|
||||
variable `difftool.<tool>.cmd`.
|
||||
+
|
||||
When 'git-difftool' is invoked with this tool (either through the
|
||||
`-t` or `--tool` option or the `diff.tool` configuration variable)
|
||||
the configured command line will be invoked with the following
|
||||
variables available: `$LOCAL` is set to the name of the temporary
|
||||
file containing the contents of the diff pre-image and `$REMOTE`
|
||||
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`.
|
||||
|
||||
--no-prompt::
|
||||
Do not prompt before launching a diff tool.
|
||||
|
||||
CONFIG VARIABLES
|
||||
----------------
|
||||
'git-difftool' falls back to 'git-mergetool' config variables when the
|
||||
difftool equivalents have not been defined.
|
||||
|
||||
diff.tool::
|
||||
The default merge tool to use.
|
||||
|
||||
difftool.<tool>.path::
|
||||
Override the path for the given tool. This is useful in case
|
||||
your tool is not in the PATH.
|
||||
|
||||
difftool.<tool>.cmd::
|
||||
Specify the command to invoke the specified merge tool.
|
||||
+
|
||||
See the `--tool=<tool>` option above for more details.
|
||||
|
||||
merge.keepBackup::
|
||||
The original, unedited file content can be saved to a file with
|
||||
a `.orig` extension. Defaults to `true` (i.e. keep the backup files).
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:git-diff[1]::
|
||||
Show changes between commits, commit and working tree, etc
|
||||
|
||||
linkgit:git-mergetool[1]::
|
||||
Run merge conflict resolution tools to resolve merge conflicts
|
||||
|
||||
linkgit:git-config[1]::
|
||||
Get and set repository or global options
|
||||
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
Written by David Aguilar <davvid@gmail.com>.
|
||||
|
||||
Documentation
|
||||
--------------
|
||||
Documentation by David Aguilar and the git-list <git@vger.kernel.org>.
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
Reference in New Issue
Block a user