mergetool: use path to mergetool in config var mergetool.<tool>.path

This commit adds a mechanism to provide absolute paths to the
external programs called by 'git mergetool'. A path can be
specified in the configuation variable mergetool.<tool>.path.
The configuration variable is similar to how we name branches
and remotes. It is extensible if we need to specify more details
about a tool.

The mechanism is especially useful on Windows, where external
programs are unlikely to be in PATH.

[sp: Fixed a few minor issues prior to applying]

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Steffen Prohaska 2007-10-17 19:16:11 +02:00 committed by Shawn O. Pearce
parent de61e42b53
commit e3fa2c761f
2 changed files with 60 additions and 43 deletions

View File

@ -31,6 +31,12 @@ 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
configuration variable merge.tool is not set, 'git mergetool' configuration variable merge.tool is not set, 'git mergetool'
will pick a suitable default. will pick a suitable default.
+
You can explicitly provide a full path to the tool by setting the
configuration variable mergetool.<tool>.path. For example, you
can configure the absolute path to kdiff3 by setting
mergetool.kdiff3.path. Otherwise, 'git mergetool' assumes the tool
is available in PATH.
Author Author
------ ------

View File

@ -192,10 +192,10 @@ merge_file () {
case "$merge_tool" in case "$merge_tool" in
kdiff3) kdiff3)
if base_present ; then if base_present ; then
(kdiff3 --auto --L1 "$path (Base)" --L2 "$path (Local)" --L3 "$path (Remote)" \ ("$merge_tool_path" --auto --L1 "$path (Base)" --L2 "$path (Local)" --L3 "$path (Remote)" \
-o "$path" -- "$BASE" "$LOCAL" "$REMOTE" > /dev/null 2>&1) -o "$path" -- "$BASE" "$LOCAL" "$REMOTE" > /dev/null 2>&1)
else else
(kdiff3 --auto --L1 "$path (Local)" --L2 "$path (Remote)" \ ("$merge_tool_path" --auto --L1 "$path (Local)" --L2 "$path (Remote)" \
-o "$path" -- "$LOCAL" "$REMOTE" > /dev/null 2>&1) -o "$path" -- "$LOCAL" "$REMOTE" > /dev/null 2>&1)
fi fi
status=$? status=$?
@ -203,35 +203,35 @@ merge_file () {
;; ;;
tkdiff) tkdiff)
if base_present ; then if base_present ; then
tkdiff -a "$BASE" -o "$path" -- "$LOCAL" "$REMOTE" "$merge_tool_path" -a "$BASE" -o "$path" -- "$LOCAL" "$REMOTE"
else else
tkdiff -o "$path" -- "$LOCAL" "$REMOTE" "$merge_tool_path" -o "$path" -- "$LOCAL" "$REMOTE"
fi fi
status=$? status=$?
save_backup save_backup
;; ;;
meld|vimdiff) meld|vimdiff)
touch "$BACKUP" touch "$BACKUP"
$merge_tool -- "$LOCAL" "$path" "$REMOTE" "$merge_tool_path" -- "$LOCAL" "$path" "$REMOTE"
check_unchanged check_unchanged
save_backup save_backup
;; ;;
gvimdiff) gvimdiff)
touch "$BACKUP" touch "$BACKUP"
gvimdiff -f -- "$LOCAL" "$path" "$REMOTE" "$merge_tool_path" -f -- "$LOCAL" "$path" "$REMOTE"
check_unchanged check_unchanged
save_backup save_backup
;; ;;
xxdiff) xxdiff)
touch "$BACKUP" touch "$BACKUP"
if base_present ; then if base_present ; then
xxdiff -X --show-merged-pane \ "$merge_tool_path" -X --show-merged-pane \
-R 'Accel.SaveAsMerged: "Ctrl-S"' \ -R 'Accel.SaveAsMerged: "Ctrl-S"' \
-R 'Accel.Search: "Ctrl+F"' \ -R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \ -R 'Accel.SearchForward: "Ctrl-G"' \
--merged-file "$path" -- "$LOCAL" "$BASE" "$REMOTE" --merged-file "$path" -- "$LOCAL" "$BASE" "$REMOTE"
else else
xxdiff -X --show-merged-pane \ "$merge_tool_path" -X --show-merged-pane \
-R 'Accel.SaveAsMerged: "Ctrl-S"' \ -R 'Accel.SaveAsMerged: "Ctrl-S"' \
-R 'Accel.Search: "Ctrl+F"' \ -R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \ -R 'Accel.SearchForward: "Ctrl-G"' \
@ -243,18 +243,18 @@ merge_file () {
opendiff) opendiff)
touch "$BACKUP" touch "$BACKUP"
if base_present; then if base_present; then
opendiff "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$path" | cat "$merge_tool_path" "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$path" | cat
else else
opendiff "$LOCAL" "$REMOTE" -merge "$path" | cat "$merge_tool_path" "$LOCAL" "$REMOTE" -merge "$path" | cat
fi fi
check_unchanged check_unchanged
save_backup save_backup
;; ;;
emerge) emerge)
if base_present ; then if base_present ; then
emacs -f emerge-files-with-ancestor-command "$LOCAL" "$REMOTE" "$BASE" "$(basename "$path")" "$merge_tool_path" -f emerge-files-with-ancestor-command "$LOCAL" "$REMOTE" "$BASE" "$(basename "$path")"
else else
emacs -f emerge-files-command "$LOCAL" "$REMOTE" "$(basename "$path")" "$merge_tool_path" -f emerge-files-command "$LOCAL" "$REMOTE" "$(basename "$path")"
fi fi
status=$? status=$?
save_backup save_backup
@ -297,17 +297,38 @@ do
shift shift
done done
valid_tool() {
case "$1" in
kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff)
;; # happy
*)
return 1
;;
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
}
if test -z "$merge_tool"; then if test -z "$merge_tool"; then
merge_tool=`git config merge.tool` merge_tool=`git config merge.tool`
case "$merge_tool" in if ! valid_tool "$merge_tool"; then
kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | "")
;; # happy
*)
echo >&2 "git config option merge.tool set to unknown tool: $merge_tool" echo >&2 "git config option merge.tool set to unknown tool: $merge_tool"
echo >&2 "Resetting to default..." echo >&2 "Resetting to default..."
unset merge_tool unset merge_tool
;; fi
esac
fi fi
if test -z "$merge_tool" ; then if test -z "$merge_tool" ; then
@ -329,40 +350,30 @@ if test -z "$merge_tool" ; then
merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff" merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff"
echo "merge tool candidates: $merge_tool_candidates" echo "merge tool candidates: $merge_tool_candidates"
for i in $merge_tool_candidates; do for i in $merge_tool_candidates; do
if test $i = emerge ; then init_merge_tool_path $i
cmd=emacs if type "$merge_tool_path" > /dev/null 2>&1; then
else
cmd=$i
fi
if type $cmd > /dev/null 2>&1; then
merge_tool=$i merge_tool=$i
break break
fi fi
done done
if test -z "$merge_tool" ; then if test -z "$merge_tool" ; then
echo "No available merge resolution programs available." echo "No known merge resolution program available."
exit 1 exit 1
fi fi
else
if ! valid_tool "$merge_tool"; then
echo >&2 "Unknown merge_tool $merge_tool"
exit 1
fi
init_merge_tool_path "$merge_tool"
if ! 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 fi
case "$merge_tool" in
kdiff3|tkdiff|meld|xxdiff|vimdiff|gvimdiff|opendiff)
if ! type "$merge_tool" > /dev/null 2>&1; then
echo "The merge tool $merge_tool is not available"
exit 1
fi
;;
emerge)
if ! type "emacs" > /dev/null 2>&1; then
echo "Emacs is not available"
exit 1
fi
;;
*)
echo "Unknown merge tool: $merge_tool"
exit 1
;;
esac
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`