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:
commit
bd15ef078a
3
.gitignore
vendored
3
.gitignore
vendored
@ -36,6 +36,8 @@ git-diff
|
|||||||
git-diff-files
|
git-diff-files
|
||||||
git-diff-index
|
git-diff-index
|
||||||
git-diff-tree
|
git-diff-tree
|
||||||
|
git-difftool
|
||||||
|
git-difftool--helper
|
||||||
git-describe
|
git-describe
|
||||||
git-fast-export
|
git-fast-export
|
||||||
git-fast-import
|
git-fast-import
|
||||||
@ -79,6 +81,7 @@ git-merge-recursive
|
|||||||
git-merge-resolve
|
git-merge-resolve
|
||||||
git-merge-subtree
|
git-merge-subtree
|
||||||
git-mergetool
|
git-mergetool
|
||||||
|
git-mergetool--lib
|
||||||
git-mktag
|
git-mktag
|
||||||
git-mktree
|
git-mktree
|
||||||
git-name-rev
|
git-name-rev
|
||||||
|
@ -667,6 +667,27 @@ diff.suppressBlankEmpty::
|
|||||||
A boolean to inhibit the standard behavior of printing a space
|
A boolean to inhibit the standard behavior of printing a space
|
||||||
before each empty output line. Defaults to false.
|
before each empty output line. Defaults to false.
|
||||||
|
|
||||||
|
diff.tool::
|
||||||
|
Controls which diff tool is used. `diff.tool` overrides
|
||||||
|
`merge.tool` when used by linkgit:git-difftool[1] and has
|
||||||
|
the same valid values as `merge.tool` minus "tortoisemerge"
|
||||||
|
and plus "kompare".
|
||||||
|
|
||||||
|
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 diff tool.
|
||||||
|
The specified command is evaluated in shell 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.
|
||||||
|
|
||||||
|
difftool.prompt::
|
||||||
|
Prompt before each invocation of the diff tool.
|
||||||
|
|
||||||
diff.wordRegex::
|
diff.wordRegex::
|
||||||
A POSIX Extended Regular Expression used to determine what is a "word"
|
A POSIX Extended Regular Expression used to determine what is a "word"
|
||||||
when performing word-by-word difference calculations. Character
|
when performing word-by-word difference calculations. Character
|
||||||
|
@ -3,35 +3,37 @@ git-difftool(1)
|
|||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
git-difftool - compare changes using common merge tools
|
git-difftool - Show changes using common diff tools
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
'git difftool' [--tool=<tool>] [--no-prompt] ['git diff' options]
|
'git difftool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<'git diff' options>]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
'git-difftool' is a git command that allows you to compare and edit files
|
'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,
|
between revisions using common diff tools. 'git difftool' is a frontend
|
||||||
'git-difftool' does what 'git-mergetool' does but its use is for non-merge
|
to 'git-diff' and accepts the same options and arguments.
|
||||||
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
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
|
-y::
|
||||||
|
--no-prompt::
|
||||||
|
Do not prompt before launching a diff tool.
|
||||||
|
|
||||||
|
--prompt::
|
||||||
|
Prompt before each invocation of the diff tool.
|
||||||
|
This is the default behaviour; the option is provided to
|
||||||
|
override any configuration settings.
|
||||||
|
|
||||||
-t <tool>::
|
-t <tool>::
|
||||||
--tool=<tool>::
|
--tool=<tool>::
|
||||||
Use the merge resolution program specified by <tool>.
|
Use the diff tool specified by <tool>.
|
||||||
Valid merge tools are:
|
Valid merge tools are:
|
||||||
kdiff3, kompare, tkdiff, meld, xxdiff, emerge,
|
kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff,
|
||||||
vimdiff, gvimdiff, ecmerge, and opendiff
|
ecmerge, diffuse and opendiff
|
||||||
+
|
+
|
||||||
If a merge resolution program is not specified, 'git-difftool'
|
If a diff tool is not specified, 'git-difftool'
|
||||||
will use the configuration variable `diff.tool`. If the
|
will use the configuration variable `diff.tool`. If the
|
||||||
configuration variable `diff.tool` is not set, 'git-difftool'
|
configuration variable `diff.tool` is not set, 'git-difftool'
|
||||||
will pick a suitable default.
|
will pick a suitable default.
|
||||||
@ -42,7 +44,7 @@ can configure the absolute path to kdiff3 by setting
|
|||||||
`difftool.kdiff3.path`. Otherwise, 'git-difftool' assumes the
|
`difftool.kdiff3.path`. Otherwise, 'git-difftool' assumes the
|
||||||
tool is available in PATH.
|
tool is available in PATH.
|
||||||
+
|
+
|
||||||
Instead of running one of the known merge tool programs,
|
Instead of running one of the known diff tools,
|
||||||
'git-difftool' can be customized to run an alternative program
|
'git-difftool' can be customized to run an alternative program
|
||||||
by specifying the command line to invoke in a configuration
|
by specifying the command line to invoke in a configuration
|
||||||
variable `difftool.<tool>.cmd`.
|
variable `difftool.<tool>.cmd`.
|
||||||
@ -56,8 +58,7 @@ is set to the name of the temporary file containing the contents
|
|||||||
of the diff post-image. `$BASE` is provided for compatibility
|
of the diff post-image. `$BASE` is provided for compatibility
|
||||||
with custom merge tool commands and has the same value as `$LOCAL`.
|
with custom merge tool commands and has the same value as `$LOCAL`.
|
||||||
|
|
||||||
--no-prompt::
|
See linkgit:git-diff[1] for the full list of supported options.
|
||||||
Do not prompt before launching a diff tool.
|
|
||||||
|
|
||||||
CONFIG VARIABLES
|
CONFIG VARIABLES
|
||||||
----------------
|
----------------
|
||||||
@ -65,20 +66,19 @@ CONFIG VARIABLES
|
|||||||
difftool equivalents have not been defined.
|
difftool equivalents have not been defined.
|
||||||
|
|
||||||
diff.tool::
|
diff.tool::
|
||||||
The default merge tool to use.
|
The default diff tool to use.
|
||||||
|
|
||||||
difftool.<tool>.path::
|
difftool.<tool>.path::
|
||||||
Override the path for the given tool. This is useful in case
|
Override the path for the given tool. This is useful in case
|
||||||
your tool is not in the PATH.
|
your tool is not in the PATH.
|
||||||
|
|
||||||
difftool.<tool>.cmd::
|
difftool.<tool>.cmd::
|
||||||
Specify the command to invoke the specified merge tool.
|
Specify the command to invoke the specified diff tool.
|
||||||
+
|
+
|
||||||
See the `--tool=<tool>` option above for more details.
|
See the `--tool=<tool>` option above for more details.
|
||||||
|
|
||||||
merge.keepBackup::
|
difftool.prompt::
|
||||||
The original, unedited file content can be saved to a file with
|
Prompt before each invocation of the diff tool.
|
||||||
a `.orig` extension. Defaults to `true` (i.e. keep the backup files).
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
54
Documentation/git-mergetool--lib.txt
Normal file
54
Documentation/git-mergetool--lib.txt
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
git-mergetool--lib(1)
|
||||||
|
=====================
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
git-mergetool--lib - Common git merge tool shell scriptlets
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
'TOOL_MODE=(diff|merge) . "$(git --exec-path)/git-mergetool--lib"'
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This is not a command the end user would want to run. Ever.
|
||||||
|
This documentation is meant for people who are studying the
|
||||||
|
Porcelain-ish scripts and/or are writing new ones.
|
||||||
|
|
||||||
|
The 'git-mergetool--lib' scriptlet is designed to be sourced (using
|
||||||
|
`.`) by other shell scripts to set up functions for working
|
||||||
|
with git merge tools.
|
||||||
|
|
||||||
|
Before sourcing 'git-mergetool--lib', your script must set `TOOL_MODE`
|
||||||
|
to define the operation mode for the functions listed below.
|
||||||
|
'diff' and 'merge' are valid values.
|
||||||
|
|
||||||
|
FUNCTIONS
|
||||||
|
---------
|
||||||
|
get_merge_tool::
|
||||||
|
returns a merge tool.
|
||||||
|
|
||||||
|
get_merge_tool_cmd::
|
||||||
|
returns the custom command for a merge tool.
|
||||||
|
|
||||||
|
get_merge_tool_path::
|
||||||
|
returns the custom path for a merge tool.
|
||||||
|
|
||||||
|
run_merge_tool::
|
||||||
|
launches a merge tool given the tool name and a true/false
|
||||||
|
flag to indicate whether a merge base is present.
|
||||||
|
'$MERGED', '$LOCAL', '$REMOTE', and '$BASE' must be defined
|
||||||
|
for use by the merge tool.
|
||||||
|
|
||||||
|
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
|
@ -26,7 +26,8 @@ OPTIONS
|
|||||||
--tool=<tool>::
|
--tool=<tool>::
|
||||||
Use the merge resolution program specified by <tool>.
|
Use the merge resolution program specified by <tool>.
|
||||||
Valid merge tools are:
|
Valid merge tools are:
|
||||||
kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, and opendiff
|
kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge,
|
||||||
|
diffuse, tortoisemerge and opendiff
|
||||||
+
|
+
|
||||||
If a merge resolution program is not specified, 'git-mergetool'
|
If a merge resolution program is not specified, 'git-mergetool'
|
||||||
will use the configuration variable `merge.tool`. If the
|
will use the configuration variable `merge.tool`. If the
|
||||||
|
@ -22,7 +22,8 @@ merge.stat::
|
|||||||
merge.tool::
|
merge.tool::
|
||||||
Controls which merge resolution program is used by
|
Controls which merge resolution program is used by
|
||||||
linkgit:git-mergetool[1]. Valid built-in values are: "kdiff3",
|
linkgit:git-mergetool[1]. Valid built-in values are: "kdiff3",
|
||||||
"tkdiff", "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff", and
|
"tkdiff", "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff",
|
||||||
|
"diffuse", "ecmerge", "tortoisemerge", and
|
||||||
"opendiff". Any other value is treated is custom merge tool
|
"opendiff". Any other value is treated is custom merge tool
|
||||||
and there must be a corresponding mergetool.<tool>.cmd option.
|
and there must be a corresponding mergetool.<tool>.cmd option.
|
||||||
|
|
||||||
|
3
Makefile
3
Makefile
@ -279,12 +279,14 @@ TEST_PROGRAMS =
|
|||||||
|
|
||||||
SCRIPT_SH += git-am.sh
|
SCRIPT_SH += git-am.sh
|
||||||
SCRIPT_SH += git-bisect.sh
|
SCRIPT_SH += git-bisect.sh
|
||||||
|
SCRIPT_SH += git-difftool--helper.sh
|
||||||
SCRIPT_SH += git-filter-branch.sh
|
SCRIPT_SH += git-filter-branch.sh
|
||||||
SCRIPT_SH += git-lost-found.sh
|
SCRIPT_SH += git-lost-found.sh
|
||||||
SCRIPT_SH += git-merge-octopus.sh
|
SCRIPT_SH += git-merge-octopus.sh
|
||||||
SCRIPT_SH += git-merge-one-file.sh
|
SCRIPT_SH += git-merge-one-file.sh
|
||||||
SCRIPT_SH += git-merge-resolve.sh
|
SCRIPT_SH += git-merge-resolve.sh
|
||||||
SCRIPT_SH += git-mergetool.sh
|
SCRIPT_SH += git-mergetool.sh
|
||||||
|
SCRIPT_SH += git-mergetool--lib.sh
|
||||||
SCRIPT_SH += git-parse-remote.sh
|
SCRIPT_SH += git-parse-remote.sh
|
||||||
SCRIPT_SH += git-pull.sh
|
SCRIPT_SH += git-pull.sh
|
||||||
SCRIPT_SH += git-quiltimport.sh
|
SCRIPT_SH += git-quiltimport.sh
|
||||||
@ -298,6 +300,7 @@ SCRIPT_SH += git-submodule.sh
|
|||||||
SCRIPT_SH += git-web--browse.sh
|
SCRIPT_SH += git-web--browse.sh
|
||||||
|
|
||||||
SCRIPT_PERL += git-add--interactive.perl
|
SCRIPT_PERL += git-add--interactive.perl
|
||||||
|
SCRIPT_PERL += git-difftool.perl
|
||||||
SCRIPT_PERL += git-archimport.perl
|
SCRIPT_PERL += git-archimport.perl
|
||||||
SCRIPT_PERL += git-cvsexportcommit.perl
|
SCRIPT_PERL += git-cvsexportcommit.perl
|
||||||
SCRIPT_PERL += git-cvsimport.perl
|
SCRIPT_PERL += git-cvsimport.perl
|
||||||
|
@ -33,6 +33,7 @@ git-diff mainporcelain common
|
|||||||
git-diff-files plumbinginterrogators
|
git-diff-files plumbinginterrogators
|
||||||
git-diff-index plumbinginterrogators
|
git-diff-index plumbinginterrogators
|
||||||
git-diff-tree plumbinginterrogators
|
git-diff-tree plumbinginterrogators
|
||||||
|
git-difftool ancillaryinterrogators
|
||||||
git-fast-export ancillarymanipulators
|
git-fast-export ancillarymanipulators
|
||||||
git-fast-import ancillarymanipulators
|
git-fast-import ancillarymanipulators
|
||||||
git-fetch mainporcelain common
|
git-fetch mainporcelain common
|
||||||
|
@ -910,6 +910,26 @@ _git_diff ()
|
|||||||
__git_complete_file
|
__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="
|
__git_fetch_options="
|
||||||
--quiet --verbose --append --upload-pack --force --keep --depth=
|
--quiet --verbose --append --upload-pack --force --keep --depth=
|
||||||
--tags --no-tags
|
--tags --no-tags
|
||||||
@ -1172,10 +1192,7 @@ _git_mergetool ()
|
|||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
--tool=*)
|
--tool=*)
|
||||||
__gitcomp "
|
__gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
|
||||||
kdiff3 tkdiff meld xxdiff emerge
|
|
||||||
vimdiff gvimdiff ecmerge opendiff
|
|
||||||
" "" "${cur##--tool=}"
|
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--*)
|
--*)
|
||||||
@ -1901,6 +1918,7 @@ _git ()
|
|||||||
config) _git_config ;;
|
config) _git_config ;;
|
||||||
describe) _git_describe ;;
|
describe) _git_describe ;;
|
||||||
diff) _git_diff ;;
|
diff) _git_diff ;;
|
||||||
|
difftool) _git_difftool ;;
|
||||||
fetch) _git_fetch ;;
|
fetch) _git_fetch ;;
|
||||||
format-patch) _git_format_patch ;;
|
format-patch) _git_format_patch ;;
|
||||||
fsck) _git_fsck ;;
|
fsck) _git_fsck ;;
|
||||||
|
@ -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
|
|
59
git-difftool--helper.sh
Executable file
59
git-difftool--helper.sh
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# git-difftool--helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher.
|
||||||
|
# This script is typically launched by using the 'git difftool'
|
||||||
|
# convenience command.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009 David Aguilar
|
||||||
|
|
||||||
|
# Load common functions from git-mergetool--lib
|
||||||
|
TOOL_MODE=diff
|
||||||
|
. git-mergetool--lib
|
||||||
|
|
||||||
|
# difftool.prompt controls the default prompt/no-prompt behavior
|
||||||
|
# and is overridden with $GIT_DIFFTOOL*_PROMPT.
|
||||||
|
should_prompt () {
|
||||||
|
prompt=$(git config --bool difftool.prompt || echo true)
|
||||||
|
if test "$prompt" = true; then
|
||||||
|
test -z "$GIT_DIFFTOOL_NO_PROMPT"
|
||||||
|
else
|
||||||
|
test -n "$GIT_DIFFTOOL_PROMPT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sets up shell variables and runs a 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"
|
||||||
|
|
||||||
|
# $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
|
||||||
|
run_merge_tool "$merge_tool"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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 test -z "$merge_tool"; then
|
||||||
|
merge_tool="$(get_merge_tool)" || exit
|
||||||
|
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
|
@ -2,9 +2,12 @@
|
|||||||
# Copyright (c) 2009 David Aguilar
|
# Copyright (c) 2009 David Aguilar
|
||||||
#
|
#
|
||||||
# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
|
# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
|
||||||
# git-difftool-helper script. This script exports
|
# git-difftool--helper script.
|
||||||
# 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.
|
# This script exports GIT_EXTERNAL_DIFF and GIT_PAGER for use by git.
|
||||||
|
# GIT_DIFFTOOL_NO_PROMPT, GIT_DIFFTOOL_PROMPT, and GIT_DIFF_TOOL
|
||||||
|
# are exported for use by git-difftool--helper.
|
||||||
|
#
|
||||||
# Any arguments that are unknown to this script are forwarded to 'git diff'.
|
# Any arguments that are unknown to this script are forwarded to 'git diff'.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
@ -18,7 +21,7 @@ my $DIR = abs_path(dirname($0));
|
|||||||
sub usage
|
sub usage
|
||||||
{
|
{
|
||||||
print << 'USAGE';
|
print << 'USAGE';
|
||||||
usage: git difftool [--tool=<tool>] [--no-prompt] ["git diff" options]
|
usage: git difftool [--tool=<tool>] [-y|--no-prompt] ["git diff" options]
|
||||||
USAGE
|
USAGE
|
||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
@ -27,13 +30,16 @@ sub setup_environment
|
|||||||
{
|
{
|
||||||
$ENV{PATH} = "$DIR:$ENV{PATH}";
|
$ENV{PATH} = "$DIR:$ENV{PATH}";
|
||||||
$ENV{GIT_PAGER} = '';
|
$ENV{GIT_PAGER} = '';
|
||||||
$ENV{GIT_EXTERNAL_DIFF} = 'git-difftool-helper';
|
$ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper';
|
||||||
}
|
}
|
||||||
|
|
||||||
sub exe
|
sub exe
|
||||||
{
|
{
|
||||||
my $exe = shift;
|
my $exe = shift;
|
||||||
return defined $ENV{COMSPEC} ? "$exe.exe" : $exe;
|
if ($^O eq 'MSWin32' || $^O eq 'msys') {
|
||||||
|
return "$exe.exe";
|
||||||
|
}
|
||||||
|
return $exe;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub generate_command
|
sub generate_command
|
||||||
@ -47,7 +53,7 @@ sub generate_command
|
|||||||
$skip_next = 0;
|
$skip_next = 0;
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
if ($arg eq '-t' or $arg eq '--tool') {
|
if ($arg eq '-t' || $arg eq '--tool') {
|
||||||
usage() if $#ARGV <= $idx;
|
usage() if $#ARGV <= $idx;
|
||||||
$ENV{GIT_DIFF_TOOL} = $ARGV[$idx + 1];
|
$ENV{GIT_DIFF_TOOL} = $ARGV[$idx + 1];
|
||||||
$skip_next = 1;
|
$skip_next = 1;
|
||||||
@ -57,11 +63,17 @@ sub generate_command
|
|||||||
$ENV{GIT_DIFF_TOOL} = substr($arg, 7);
|
$ENV{GIT_DIFF_TOOL} = substr($arg, 7);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
if ($arg eq '--no-prompt') {
|
if ($arg eq '-y' || $arg eq '--no-prompt') {
|
||||||
$ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
|
$ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
|
||||||
|
delete $ENV{GIT_DIFFTOOL_PROMPT};
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
if ($arg eq '-h' or $arg eq '--help') {
|
if ($arg eq '--prompt') {
|
||||||
|
$ENV{GIT_DIFFTOOL_PROMPT} = 'true';
|
||||||
|
delete $ENV{GIT_DIFFTOOL_NO_PROMPT};
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if ($arg eq '-h' || $arg eq '--help') {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
push @command, $arg;
|
push @command, $arg;
|
385
git-mergetool--lib.sh
Normal file
385
git-mergetool--lib.sh
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
# git-mergetool--lib is a library for common merge tool functions
|
||||||
|
diff_mode() {
|
||||||
|
test "$TOOL_MODE" = diff
|
||||||
|
}
|
||||||
|
|
||||||
|
merge_mode() {
|
||||||
|
test "$TOOL_MODE" = merge
|
||||||
|
}
|
||||||
|
|
||||||
|
translate_merge_tool_path () {
|
||||||
|
case "$1" in
|
||||||
|
vimdiff)
|
||||||
|
echo vim
|
||||||
|
;;
|
||||||
|
gvimdiff)
|
||||||
|
echo gvim
|
||||||
|
;;
|
||||||
|
emerge)
|
||||||
|
echo emacs
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "$1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
check_unchanged () {
|
||||||
|
if test "$MERGED" -nt "$BACKUP"; then
|
||||||
|
status=0
|
||||||
|
else
|
||||||
|
while true; do
|
||||||
|
echo "$MERGED seems unchanged."
|
||||||
|
printf "Was the merge successful? [y/n] "
|
||||||
|
read answer < /dev/tty
|
||||||
|
case "$answer" in
|
||||||
|
y*|Y*) status=0; break ;;
|
||||||
|
n*|N*) status=1; break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_tool () {
|
||||||
|
case "$1" in
|
||||||
|
kdiff3 | tkdiff | xxdiff | meld | opendiff | \
|
||||||
|
emerge | vimdiff | gvimdiff | ecmerge | diffuse)
|
||||||
|
;; # happy
|
||||||
|
tortoisemerge)
|
||||||
|
if ! merge_mode; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
kompare)
|
||||||
|
if ! diff_mode; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test -z "$(get_merge_tool_cmd "$1")"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
get_merge_tool_cmd () {
|
||||||
|
# Prints the custom command for a merge tool
|
||||||
|
if test -n "$1"; then
|
||||||
|
merge_tool="$1"
|
||||||
|
else
|
||||||
|
merge_tool="$(get_merge_tool)"
|
||||||
|
fi
|
||||||
|
if diff_mode; then
|
||||||
|
echo "$(git config difftool.$merge_tool.cmd ||
|
||||||
|
git config mergetool.$merge_tool.cmd)"
|
||||||
|
else
|
||||||
|
echo "$(git config mergetool.$merge_tool.cmd)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_merge_tool () {
|
||||||
|
merge_tool_path="$(get_merge_tool_path "$1")" || exit
|
||||||
|
base_present="$2"
|
||||||
|
status=0
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
kdiff3)
|
||||||
|
if merge_mode; then
|
||||||
|
if $base_present; then
|
||||||
|
("$merge_tool_path" --auto \
|
||||||
|
--L1 "$MERGED (Base)" \
|
||||||
|
--L2 "$MERGED (Local)" \
|
||||||
|
--L3 "$MERGED (Remote)" \
|
||||||
|
-o "$MERGED" \
|
||||||
|
"$BASE" "$LOCAL" "$REMOTE" \
|
||||||
|
> /dev/null 2>&1)
|
||||||
|
else
|
||||||
|
("$merge_tool_path" --auto \
|
||||||
|
--L1 "$MERGED (Local)" \
|
||||||
|
--L2 "$MERGED (Remote)" \
|
||||||
|
-o "$MERGED" \
|
||||||
|
"$LOCAL" "$REMOTE" \
|
||||||
|
> /dev/null 2>&1)
|
||||||
|
fi
|
||||||
|
status=$?
|
||||||
|
else
|
||||||
|
("$merge_tool_path" --auto \
|
||||||
|
--L1 "$MERGED (A)" \
|
||||||
|
--L2 "$MERGED (B)" "$LOCAL" "$REMOTE" \
|
||||||
|
> /dev/null 2>&1)
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
kompare)
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE"
|
||||||
|
;;
|
||||||
|
tkdiff)
|
||||||
|
if merge_mode; then
|
||||||
|
if $base_present; then
|
||||||
|
"$merge_tool_path" -a "$BASE" \
|
||||||
|
-o "$MERGED" "$LOCAL" "$REMOTE"
|
||||||
|
else
|
||||||
|
"$merge_tool_path" \
|
||||||
|
-o "$MERGED" "$LOCAL" "$REMOTE"
|
||||||
|
fi
|
||||||
|
status=$?
|
||||||
|
else
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
meld)
|
||||||
|
if merge_mode; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
diffuse)
|
||||||
|
if merge_mode; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
if $base_present; then
|
||||||
|
"$merge_tool_path" \
|
||||||
|
"$LOCAL" "$MERGED" "$REMOTE" \
|
||||||
|
"$BASE" | cat
|
||||||
|
else
|
||||||
|
"$merge_tool_path" \
|
||||||
|
"$LOCAL" "$MERGED" "$REMOTE" | cat
|
||||||
|
fi
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE" | cat
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
vimdiff)
|
||||||
|
if merge_mode; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
"$merge_tool_path" -d -c "wincmd l" \
|
||||||
|
"$LOCAL" "$MERGED" "$REMOTE"
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
"$merge_tool_path" -d -c "wincmd l" \
|
||||||
|
"$LOCAL" "$REMOTE"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
gvimdiff)
|
||||||
|
if merge_mode; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
"$merge_tool_path" -d -c "wincmd l" -f \
|
||||||
|
"$LOCAL" "$MERGED" "$REMOTE"
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
"$merge_tool_path" -d -c "wincmd l" -f \
|
||||||
|
"$LOCAL" "$REMOTE"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
xxdiff)
|
||||||
|
if merge_mode; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
if $base_present; then
|
||||||
|
"$merge_tool_path" -X --show-merged-pane \
|
||||||
|
-R 'Accel.SaveAsMerged: "Ctrl-S"' \
|
||||||
|
-R 'Accel.Search: "Ctrl+F"' \
|
||||||
|
-R 'Accel.SearchForward: "Ctrl-G"' \
|
||||||
|
--merged-file "$MERGED" \
|
||||||
|
"$LOCAL" "$BASE" "$REMOTE"
|
||||||
|
else
|
||||||
|
"$merge_tool_path" -X $extra \
|
||||||
|
-R 'Accel.SaveAsMerged: "Ctrl-S"' \
|
||||||
|
-R 'Accel.Search: "Ctrl+F"' \
|
||||||
|
-R 'Accel.SearchForward: "Ctrl-G"' \
|
||||||
|
--merged-file "$MERGED" \
|
||||||
|
"$LOCAL" "$REMOTE"
|
||||||
|
fi
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
"$merge_tool_path" \
|
||||||
|
-R 'Accel.Search: "Ctrl+F"' \
|
||||||
|
-R 'Accel.SearchForward: "Ctrl-G"' \
|
||||||
|
"$LOCAL" "$REMOTE"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
opendiff)
|
||||||
|
if merge_mode; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
if $base_present; then
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE" \
|
||||||
|
-ancestor "$BASE" \
|
||||||
|
-merge "$MERGED" | cat
|
||||||
|
else
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE" \
|
||||||
|
-merge "$MERGED" | cat
|
||||||
|
fi
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE" | cat
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
ecmerge)
|
||||||
|
if merge_mode; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
if $base_present; then
|
||||||
|
"$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" \
|
||||||
|
--default --mode=merge3 --to="$MERGED"
|
||||||
|
else
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE" \
|
||||||
|
--default --mode=merge2 --to="$MERGED"
|
||||||
|
fi
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
"$merge_tool_path" "$LOCAL" "$REMOTE" \
|
||||||
|
--default --mode=merge2 --to="$MERGED"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
emerge)
|
||||||
|
if merge_mode; then
|
||||||
|
if $base_present; then
|
||||||
|
"$merge_tool_path" \
|
||||||
|
-f emerge-files-with-ancestor-command \
|
||||||
|
"$LOCAL" "$REMOTE" "$BASE" \
|
||||||
|
"$(basename "$MERGED")"
|
||||||
|
else
|
||||||
|
"$merge_tool_path" \
|
||||||
|
-f emerge-files-command \
|
||||||
|
"$LOCAL" "$REMOTE" \
|
||||||
|
"$(basename "$MERGED")"
|
||||||
|
fi
|
||||||
|
status=$?
|
||||||
|
else
|
||||||
|
"$merge_tool_path" -f emerge-files-command \
|
||||||
|
"$LOCAL" "$REMOTE" "$(basename "$MERGED")"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
tortoisemerge)
|
||||||
|
if $base_present; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
"$merge_tool_path" \
|
||||||
|
-base:"$BASE" -mine:"$LOCAL" \
|
||||||
|
-theirs:"$REMOTE" -merged:"$MERGED"
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
echo "TortoiseMerge cannot be used without a base" 1>&2
|
||||||
|
status=1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
merge_tool_cmd="$(get_merge_tool_cmd "$1")"
|
||||||
|
if test -z "$merge_tool_cmd"; then
|
||||||
|
if merge_mode; then
|
||||||
|
status=1
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if merge_mode; then
|
||||||
|
trust_exit_code="$(git config --bool \
|
||||||
|
mergetool."$1".trustExitCode || echo false)"
|
||||||
|
if test "$trust_exit_code" = "false"; then
|
||||||
|
touch "$BACKUP"
|
||||||
|
( eval $merge_tool_cmd )
|
||||||
|
check_unchanged
|
||||||
|
else
|
||||||
|
( eval $merge_tool_cmd )
|
||||||
|
status=$?
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
( eval $merge_tool_cmd )
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
|
||||||
|
guess_merge_tool () {
|
||||||
|
if merge_mode; then
|
||||||
|
tools="tortoisemerge"
|
||||||
|
else
|
||||||
|
tools="kompare"
|
||||||
|
fi
|
||||||
|
if test -n "$DISPLAY"; then
|
||||||
|
if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
|
||||||
|
tools="meld opendiff kdiff3 tkdiff xxdiff $tools"
|
||||||
|
else
|
||||||
|
tools="opendiff kdiff3 tkdiff xxdiff meld $tools"
|
||||||
|
fi
|
||||||
|
tools="$tools gvimdiff diffuse ecmerge"
|
||||||
|
fi
|
||||||
|
if echo "${VISUAL:-$EDITOR}" | grep emacs > /dev/null 2>&1; then
|
||||||
|
# $EDITOR is emacs so add emerge as a candidate
|
||||||
|
tools="$tools emerge vimdiff"
|
||||||
|
elif echo "${VISUAL:-$EDITOR}" | grep vim > /dev/null 2>&1; then
|
||||||
|
# $EDITOR is vim so add vimdiff as a candidate
|
||||||
|
tools="$tools vimdiff emerge"
|
||||||
|
else
|
||||||
|
tools="$tools emerge vimdiff"
|
||||||
|
fi
|
||||||
|
echo >&2 "merge tool candidates: $tools"
|
||||||
|
|
||||||
|
# Loop over each candidate and stop when a valid merge tool is found.
|
||||||
|
for i in $tools
|
||||||
|
do
|
||||||
|
merge_tool_path="$(translate_merge_tool_path "$i")"
|
||||||
|
if type "$merge_tool_path" > /dev/null 2>&1; then
|
||||||
|
echo "$i"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo >&2 "No known merge resolution program available."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get_configured_merge_tool () {
|
||||||
|
# Diff mode first tries diff.tool and falls back to merge.tool.
|
||||||
|
# Merge mode only checks merge.tool
|
||||||
|
if diff_mode; then
|
||||||
|
merge_tool=$(git config diff.tool || git config merge.tool)
|
||||||
|
else
|
||||||
|
merge_tool=$(git config merge.tool)
|
||||||
|
fi
|
||||||
|
if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
|
||||||
|
echo >&2 "git config option $TOOL_MODE.tool set to unknown tool: $merge_tool"
|
||||||
|
echo >&2 "Resetting to default..."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "$merge_tool"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_merge_tool_path () {
|
||||||
|
# A merge tool has been set, so verify that it's valid.
|
||||||
|
if test -n "$1"; then
|
||||||
|
merge_tool="$1"
|
||||||
|
else
|
||||||
|
merge_tool="$(get_merge_tool)"
|
||||||
|
fi
|
||||||
|
if ! valid_tool "$merge_tool"; then
|
||||||
|
echo >&2 "Unknown merge tool $merge_tool"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if diff_mode; then
|
||||||
|
merge_tool_path=$(git config difftool."$merge_tool".path ||
|
||||||
|
git config mergetool."$merge_tool".path)
|
||||||
|
else
|
||||||
|
merge_tool_path=$(git config mergetool."$merge_tool".path)
|
||||||
|
fi
|
||||||
|
if test -z "$merge_tool_path"; then
|
||||||
|
merge_tool_path="$(translate_merge_tool_path "$merge_tool")"
|
||||||
|
fi
|
||||||
|
if test -z "$(get_merge_tool_cmd "$merge_tool")" &&
|
||||||
|
! type "$merge_tool_path" > /dev/null 2>&1; then
|
||||||
|
echo >&2 "The $TOOL_MODE tool $merge_tool is not available as"\
|
||||||
|
"'$merge_tool_path'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$merge_tool_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_merge_tool () {
|
||||||
|
# Check if a merge tool has been configured
|
||||||
|
merge_tool=$(get_configured_merge_tool)
|
||||||
|
# Try to guess an appropriate merge tool if no tool has been set.
|
||||||
|
if test -z "$merge_tool"; then
|
||||||
|
merge_tool="$(guess_merge_tool)" || exit
|
||||||
|
fi
|
||||||
|
echo "$merge_tool"
|
||||||
|
}
|
211
git-mergetool.sh
211
git-mergetool.sh
@ -11,7 +11,9 @@
|
|||||||
USAGE='[--tool=tool] [-y|--no-prompt|--prompt] [file to merge] ...'
|
USAGE='[--tool=tool] [-y|--no-prompt|--prompt] [file to merge] ...'
|
||||||
SUBDIRECTORY_OK=Yes
|
SUBDIRECTORY_OK=Yes
|
||||||
OPTIONS_SPEC=
|
OPTIONS_SPEC=
|
||||||
|
TOOL_MODE=merge
|
||||||
. git-sh-setup
|
. git-sh-setup
|
||||||
|
. git-mergetool--lib
|
||||||
require_work_tree
|
require_work_tree
|
||||||
|
|
||||||
# Returns true if the mode reflects a symlink
|
# Returns true if the mode reflects a symlink
|
||||||
@ -110,22 +112,6 @@ resolve_deleted_merge () {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
check_unchanged () {
|
|
||||||
if test "$MERGED" -nt "$BACKUP" ; then
|
|
||||||
status=0;
|
|
||||||
else
|
|
||||||
while true; do
|
|
||||||
echo "$MERGED seems unchanged."
|
|
||||||
printf "Was the merge successful? [y/n] "
|
|
||||||
read answer < /dev/tty
|
|
||||||
case "$answer" in
|
|
||||||
y*|Y*) status=0; break ;;
|
|
||||||
n*|N*) status=1; break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
checkout_staged_file () {
|
checkout_staged_file () {
|
||||||
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ')
|
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ')
|
||||||
|
|
||||||
@ -137,7 +123,7 @@ checkout_staged_file () {
|
|||||||
merge_file () {
|
merge_file () {
|
||||||
MERGED="$1"
|
MERGED="$1"
|
||||||
|
|
||||||
f=`git ls-files -u -- "$MERGED"`
|
f=$(git ls-files -u -- "$MERGED")
|
||||||
if test -z "$f" ; then
|
if test -z "$f" ; then
|
||||||
if test ! -f "$MERGED" ; then
|
if test ! -f "$MERGED" ; then
|
||||||
echo "$MERGED: file not found"
|
echo "$MERGED: file not found"
|
||||||
@ -156,9 +142,9 @@ merge_file () {
|
|||||||
mv -- "$MERGED" "$BACKUP"
|
mv -- "$MERGED" "$BACKUP"
|
||||||
cp -- "$BACKUP" "$MERGED"
|
cp -- "$BACKUP" "$MERGED"
|
||||||
|
|
||||||
base_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}'`
|
base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}')
|
||||||
local_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}'`
|
local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')
|
||||||
remote_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}'`
|
remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}')
|
||||||
|
|
||||||
base_present && checkout_staged_file 1 "$MERGED" "$BASE"
|
base_present && checkout_staged_file 1 "$MERGED" "$BASE"
|
||||||
local_present && checkout_staged_file 2 "$MERGED" "$LOCAL"
|
local_present && checkout_staged_file 2 "$MERGED" "$LOCAL"
|
||||||
@ -188,97 +174,13 @@ merge_file () {
|
|||||||
read ans
|
read ans
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case "$merge_tool" in
|
|
||||||
kdiff3)
|
|
||||||
if base_present ; then
|
|
||||||
("$merge_tool_path" --auto --L1 "$MERGED (Base)" --L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" \
|
|
||||||
-o "$MERGED" "$BASE" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
|
|
||||||
else
|
|
||||||
("$merge_tool_path" --auto --L1 "$MERGED (Local)" --L2 "$MERGED (Remote)" \
|
|
||||||
-o "$MERGED" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
|
|
||||||
fi
|
|
||||||
status=$?
|
|
||||||
;;
|
|
||||||
tkdiff)
|
|
||||||
if base_present ; then
|
|
||||||
"$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"
|
|
||||||
else
|
|
||||||
"$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"
|
|
||||||
fi
|
|
||||||
status=$?
|
|
||||||
;;
|
|
||||||
meld)
|
|
||||||
touch "$BACKUP"
|
|
||||||
"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
|
|
||||||
check_unchanged
|
|
||||||
;;
|
|
||||||
vimdiff)
|
|
||||||
touch "$BACKUP"
|
|
||||||
"$merge_tool_path" -c "wincmd l" "$LOCAL" "$MERGED" "$REMOTE"
|
|
||||||
check_unchanged
|
|
||||||
;;
|
|
||||||
gvimdiff)
|
|
||||||
touch "$BACKUP"
|
|
||||||
"$merge_tool_path" -c "wincmd l" -f "$LOCAL" "$MERGED" "$REMOTE"
|
|
||||||
check_unchanged
|
|
||||||
;;
|
|
||||||
xxdiff)
|
|
||||||
touch "$BACKUP"
|
|
||||||
if base_present ; then
|
|
||||||
"$merge_tool_path" -X --show-merged-pane \
|
|
||||||
-R 'Accel.SaveAsMerged: "Ctrl-S"' \
|
|
||||||
-R 'Accel.Search: "Ctrl+F"' \
|
|
||||||
-R 'Accel.SearchForward: "Ctrl-G"' \
|
|
||||||
--merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
|
|
||||||
else
|
|
||||||
"$merge_tool_path" -X --show-merged-pane \
|
|
||||||
-R 'Accel.SaveAsMerged: "Ctrl-S"' \
|
|
||||||
-R 'Accel.Search: "Ctrl+F"' \
|
|
||||||
-R 'Accel.SearchForward: "Ctrl-G"' \
|
|
||||||
--merged-file "$MERGED" "$LOCAL" "$REMOTE"
|
|
||||||
fi
|
|
||||||
check_unchanged
|
|
||||||
;;
|
|
||||||
opendiff)
|
|
||||||
touch "$BACKUP"
|
|
||||||
if base_present; then
|
if base_present; then
|
||||||
"$merge_tool_path" "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED" | cat
|
present=true
|
||||||
else
|
else
|
||||||
"$merge_tool_path" "$LOCAL" "$REMOTE" -merge "$MERGED" | cat
|
present=false
|
||||||
fi
|
fi
|
||||||
check_unchanged
|
|
||||||
;;
|
if ! run_merge_tool "$merge_tool" "$present"; then
|
||||||
ecmerge)
|
|
||||||
touch "$BACKUP"
|
|
||||||
if base_present; then
|
|
||||||
"$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --default --mode=merge3 --to="$MERGED"
|
|
||||||
else
|
|
||||||
"$merge_tool_path" "$LOCAL" "$REMOTE" --default --mode=merge2 --to="$MERGED"
|
|
||||||
fi
|
|
||||||
check_unchanged
|
|
||||||
;;
|
|
||||||
emerge)
|
|
||||||
if base_present ; then
|
|
||||||
"$merge_tool_path" -f emerge-files-with-ancestor-command "$LOCAL" "$REMOTE" "$BASE" "$(basename "$MERGED")"
|
|
||||||
else
|
|
||||||
"$merge_tool_path" -f emerge-files-command "$LOCAL" "$REMOTE" "$(basename "$MERGED")"
|
|
||||||
fi
|
|
||||||
status=$?
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if test -n "$merge_tool_cmd"; then
|
|
||||||
if test "$merge_tool_trust_exit_code" = "false"; then
|
|
||||||
touch "$BACKUP"
|
|
||||||
( eval $merge_tool_cmd )
|
|
||||||
check_unchanged
|
|
||||||
else
|
|
||||||
( eval $merge_tool_cmd )
|
|
||||||
status=$?
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
if test "$status" -ne 0; then
|
|
||||||
echo "merge of $MERGED failed" 1>&2
|
echo "merge of $MERGED failed" 1>&2
|
||||||
mv -- "$BACKUP" "$MERGED"
|
mv -- "$BACKUP" "$MERGED"
|
||||||
|
|
||||||
@ -308,7 +210,7 @@ do
|
|||||||
-t|--tool*)
|
-t|--tool*)
|
||||||
case "$#,$1" in
|
case "$#,$1" in
|
||||||
*,*=*)
|
*,*=*)
|
||||||
merge_tool=`expr "z$1" : 'z-[^=]*=\(.*\)'`
|
merge_tool=$(expr "z$1" : 'z-[^=]*=\(.*\)')
|
||||||
;;
|
;;
|
||||||
1,*)
|
1,*)
|
||||||
usage ;;
|
usage ;;
|
||||||
@ -337,38 +239,6 @@ do
|
|||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
valid_custom_tool()
|
|
||||||
{
|
|
||||||
merge_tool_cmd="$(git config mergetool.$1.cmd)"
|
|
||||||
test -n "$merge_tool_cmd"
|
|
||||||
}
|
|
||||||
|
|
||||||
valid_tool() {
|
|
||||||
case "$1" in
|
|
||||||
kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)
|
|
||||||
;; # happy
|
|
||||||
*)
|
|
||||||
if ! valid_custom_tool "$1"; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
init_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
|
|
||||||
}
|
|
||||||
|
|
||||||
prompt_after_failed_merge() {
|
prompt_after_failed_merge() {
|
||||||
while true; do
|
while true; do
|
||||||
printf "Continue merging other unresolved paths (y/n) ? "
|
printf "Continue merging other unresolved paths (y/n) ? "
|
||||||
@ -387,67 +257,16 @@ prompt_after_failed_merge() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if test -z "$merge_tool"; then
|
if test -z "$merge_tool"; then
|
||||||
merge_tool=`git config merge.tool`
|
merge_tool=$(get_merge_tool "$merge_tool") || exit
|
||||||
if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
|
|
||||||
echo >&2 "git config option merge.tool set to unknown tool: $merge_tool"
|
|
||||||
echo >&2 "Resetting to default..."
|
|
||||||
unset merge_tool
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$merge_tool" ; then
|
|
||||||
if test -n "$DISPLAY"; then
|
|
||||||
if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
|
|
||||||
merge_tool_candidates="meld kdiff3 tkdiff xxdiff gvimdiff"
|
|
||||||
else
|
|
||||||
merge_tool_candidates="kdiff3 tkdiff xxdiff meld gvimdiff"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
|
|
||||||
merge_tool_candidates="$merge_tool_candidates emerge opendiff vimdiff"
|
|
||||||
elif echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then
|
|
||||||
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"
|
|
||||||
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
|
|
||||||
if ! valid_tool "$merge_tool"; then
|
|
||||||
echo >&2 "Unknown merge_tool $merge_tool"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
init_merge_tool_path "$merge_tool"
|
|
||||||
|
|
||||||
merge_keep_backup="$(git config --bool merge.keepBackup || echo true)"
|
|
||||||
merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
if ! test -z "$merge_tool_cmd"; then
|
|
||||||
merge_tool_trust_exit_code="$(git config --bool mergetool.$merge_tool.trustExitCode || echo false)"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)"
|
||||||
|
merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
|
||||||
|
|
||||||
last_status=0
|
last_status=0
|
||||||
rollup_status=0
|
rollup_status=0
|
||||||
|
|
||||||
if test $# -eq 0 ; then
|
if test $# -eq 0 ; then
|
||||||
files=`git ls-files -u | sed -e 's/^[^ ]* //' | sort -u`
|
files=$(git ls-files -u | sed -e 's/^[^ ]* //' | sort -u)
|
||||||
if test -z "$files" ; then
|
if test -z "$files" ; then
|
||||||
echo "No files need merging"
|
echo "No files need merging"
|
||||||
exit 0
|
exit 0
|
||||||
|
211
t/t7800-difftool.sh
Executable file
211
t/t7800-difftool.sh
Executable file
@ -0,0 +1,211 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009 David Aguilar
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='git-difftool
|
||||||
|
|
||||||
|
Testing basic diff tool invocation
|
||||||
|
'
|
||||||
|
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
remove_config_vars()
|
||||||
|
{
|
||||||
|
# Unset all config variables used by git-difftool
|
||||||
|
git config --unset diff.tool
|
||||||
|
git config --unset difftool.test-tool.cmd
|
||||||
|
git config --unset difftool.prompt
|
||||||
|
git config --unset merge.tool
|
||||||
|
git config --unset mergetool.test-tool.cmd
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_test_defaults()
|
||||||
|
{
|
||||||
|
# Restores the test defaults used by several tests
|
||||||
|
remove_config_vars
|
||||||
|
unset GIT_DIFF_TOOL
|
||||||
|
unset GIT_MERGE_TOOL
|
||||||
|
unset GIT_DIFFTOOL_PROMPT
|
||||||
|
unset GIT_DIFFTOOL_NO_PROMPT
|
||||||
|
git config diff.tool test-tool &&
|
||||||
|
git config difftool.test-tool.cmd 'cat $LOCAL'
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_given()
|
||||||
|
{
|
||||||
|
prompt="$1"
|
||||||
|
test "$prompt" = "Hit return to launch 'test-tool': branch"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a file on master and change it on branch
|
||||||
|
test_expect_success 'setup' '
|
||||||
|
echo master >file &&
|
||||||
|
git add file &&
|
||||||
|
git commit -m "added file" &&
|
||||||
|
|
||||||
|
git checkout -b branch master &&
|
||||||
|
echo branch >file &&
|
||||||
|
git commit -a -m "branch changed file" &&
|
||||||
|
git checkout master
|
||||||
|
'
|
||||||
|
|
||||||
|
# Configure a custom difftool.<tool>.cmd and use it
|
||||||
|
test_expect_success 'custom commands' '
|
||||||
|
restore_test_defaults &&
|
||||||
|
git config difftool.test-tool.cmd "cat \$REMOTE" &&
|
||||||
|
|
||||||
|
diff=$(git difftool --no-prompt branch) &&
|
||||||
|
test "$diff" = "master" &&
|
||||||
|
|
||||||
|
restore_test_defaults &&
|
||||||
|
diff=$(git difftool --no-prompt branch) &&
|
||||||
|
test "$diff" = "branch"
|
||||||
|
'
|
||||||
|
|
||||||
|
# Ensures that git-difftool ignores bogus --tool values
|
||||||
|
test_expect_success 'difftool ignores bad --tool values' '
|
||||||
|
diff=$(git difftool --no-prompt --tool=bogus-tool branch)
|
||||||
|
test "$?" = 1 &&
|
||||||
|
test "$diff" = ""
|
||||||
|
'
|
||||||
|
|
||||||
|
# Specify the diff tool using $GIT_DIFF_TOOL
|
||||||
|
test_expect_success 'GIT_DIFF_TOOL variable' '
|
||||||
|
git config --unset diff.tool
|
||||||
|
GIT_DIFF_TOOL=test-tool &&
|
||||||
|
export GIT_DIFF_TOOL &&
|
||||||
|
|
||||||
|
diff=$(git difftool --no-prompt branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
# Test the $GIT_*_TOOL variables and ensure
|
||||||
|
# that $GIT_DIFF_TOOL always wins unless --tool is specified
|
||||||
|
test_expect_success 'GIT_DIFF_TOOL overrides' '
|
||||||
|
git config diff.tool bogus-tool &&
|
||||||
|
git config merge.tool bogus-tool &&
|
||||||
|
|
||||||
|
GIT_MERGE_TOOL=test-tool &&
|
||||||
|
export GIT_MERGE_TOOL &&
|
||||||
|
diff=$(git difftool --no-prompt branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
unset GIT_MERGE_TOOL &&
|
||||||
|
|
||||||
|
GIT_MERGE_TOOL=bogus-tool &&
|
||||||
|
GIT_DIFF_TOOL=test-tool &&
|
||||||
|
export GIT_MERGE_TOOL &&
|
||||||
|
export GIT_DIFF_TOOL &&
|
||||||
|
|
||||||
|
diff=$(git difftool --no-prompt branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
GIT_DIFF_TOOL=bogus-tool &&
|
||||||
|
export GIT_DIFF_TOOL &&
|
||||||
|
|
||||||
|
diff=$(git difftool --no-prompt --tool=test-tool branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
# Test that we don't have to pass --no-prompt to difftool
|
||||||
|
# when $GIT_DIFFTOOL_NO_PROMPT is true
|
||||||
|
test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' '
|
||||||
|
GIT_DIFFTOOL_NO_PROMPT=true &&
|
||||||
|
export GIT_DIFFTOOL_NO_PROMPT &&
|
||||||
|
|
||||||
|
diff=$(git difftool branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
# git-difftool supports the difftool.prompt variable.
|
||||||
|
# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
|
||||||
|
test_expect_success 'GIT_DIFFTOOL_PROMPT variable' '
|
||||||
|
git config difftool.prompt false &&
|
||||||
|
GIT_DIFFTOOL_PROMPT=true &&
|
||||||
|
export GIT_DIFFTOOL_PROMPT &&
|
||||||
|
|
||||||
|
prompt=$(echo | git difftool --prompt branch | tail -1) &&
|
||||||
|
prompt_given "$prompt" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
# Test that we don't have to pass --no-prompt when difftool.prompt is false
|
||||||
|
test_expect_success 'difftool.prompt config variable is false' '
|
||||||
|
git config difftool.prompt false &&
|
||||||
|
|
||||||
|
diff=$(git difftool branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
# Test that the -y flag can override difftool.prompt = true
|
||||||
|
test_expect_success 'difftool.prompt can overridden with -y' '
|
||||||
|
git config difftool.prompt true &&
|
||||||
|
|
||||||
|
diff=$(git difftool -y branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
# Test that the --prompt flag can override difftool.prompt = false
|
||||||
|
test_expect_success 'difftool.prompt can overridden with --prompt' '
|
||||||
|
git config difftool.prompt false &&
|
||||||
|
|
||||||
|
prompt=$(echo | git difftool --prompt branch | tail -1) &&
|
||||||
|
prompt_given "$prompt" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
# Test that the last flag passed on the command-line wins
|
||||||
|
test_expect_success 'difftool last flag wins' '
|
||||||
|
diff=$(git difftool --prompt --no-prompt branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
restore_test_defaults &&
|
||||||
|
|
||||||
|
prompt=$(echo | git difftool --no-prompt --prompt branch | tail -1) &&
|
||||||
|
prompt_given "$prompt" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
# git-difftool falls back to git-mergetool config variables
|
||||||
|
# so test that behavior here
|
||||||
|
test_expect_success 'difftool + mergetool config variables' '
|
||||||
|
remove_config_vars
|
||||||
|
git config merge.tool test-tool &&
|
||||||
|
git config mergetool.test-tool.cmd "cat \$LOCAL" &&
|
||||||
|
|
||||||
|
diff=$(git difftool --no-prompt branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
# set merge.tool to something bogus, diff.tool to test-tool
|
||||||
|
git config merge.tool bogus-tool &&
|
||||||
|
git config diff.tool test-tool &&
|
||||||
|
|
||||||
|
diff=$(git difftool --no-prompt branch) &&
|
||||||
|
test "$diff" = "branch" &&
|
||||||
|
|
||||||
|
restore_test_defaults
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'difftool.<tool>.path' '
|
||||||
|
git config difftool.tkdiff.path echo &&
|
||||||
|
diff=$(git difftool --tool=tkdiff --no-prompt branch) &&
|
||||||
|
git config --unset difftool.tkdiff.path &&
|
||||||
|
lines=$(echo "$diff" | grep file | wc -l) &&
|
||||||
|
test "$lines" -eq 1
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
Loading…
x
Reference in New Issue
Block a user