mergetool--lib: simplify API usage by removing more global variables

The mergetool--lib scriplet was tricky to use because it relied upon
the existance of several global shell variables.  This removes more
global variables so that things are simpler for callers.

A side effect is that some variables are recomputed each time
run_merge_tool() is called, but the overhead for recomputing
them is justified by the simpler implementation.

Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
David Aguilar 2009-04-11 20:41:56 -07:00 committed by Junio C Hamano
parent 70af4e9bef
commit 47d65924a6
4 changed files with 77 additions and 71 deletions

View File

@ -7,7 +7,7 @@ git-mergetool--lib - Common git merge tool shell scriptlets
SYNOPSIS SYNOPSIS
-------- --------
'. "$(git --exec-path)/git-mergetool--lib"' 'TOOL_MODE=(diff|merge) . "$(git --exec-path)/git-mergetool--lib"'
DESCRIPTION DESCRIPTION
----------- -----------
@ -20,14 +20,14 @@ The 'git-mergetool--lib' scriptlet is designed to be sourced (using
`.`) by other shell scripts to set up functions for working `.`) by other shell scripts to set up functions for working
with git merge tools. with git merge tools.
Before sourcing it, your script should set up a few variables; Before sourcing 'git-mergetool--lib', your script must set `TOOL_MODE`
`TOOL_MODE` is used to define the operation mode for various to define the operation mode for the functions listed below.
functions. 'diff' and 'merge' are valid values. 'diff' and 'merge' are valid values.
FUNCTIONS FUNCTIONS
--------- ---------
get_merge_tool:: get_merge_tool::
returns a merge tool returns a merge tool.
get_merge_tool_cmd:: get_merge_tool_cmd::
returns the custom command for a merge tool. returns the custom command for a merge tool.
@ -38,10 +38,8 @@ get_merge_tool_path::
run_merge_tool:: run_merge_tool::
launches a merge tool given the tool name and a true/false launches a merge tool given the tool name and a true/false
flag to indicate whether a merge base is present. flag to indicate whether a merge base is present.
'$merge_tool', '$merge_tool_path', and for custom commands, '$MERGED', '$LOCAL', '$REMOTE', and '$BASE' must be defined
'$merge_tool_cmd', must be defined prior to calling for use by the merge tool.
run_merge_tool. Additionally, '$MERGED', '$LOCAL', '$REMOTE',
and '$BASE' must be defined for use by the merge tool.
Author Author
------ ------

View File

@ -47,9 +47,9 @@ launch_merge_tool () {
test -n "$GIT_MERGE_TOOL" && merge_tool="$GIT_MERGE_TOOL" test -n "$GIT_MERGE_TOOL" && merge_tool="$GIT_MERGE_TOOL"
test -n "$GIT_DIFF_TOOL" && merge_tool="$GIT_DIFF_TOOL" test -n "$GIT_DIFF_TOOL" && merge_tool="$GIT_DIFF_TOOL"
merge_tool=$(get_merge_tool "$merge_tool") || exit if test -z "$merge_tool"; then
merge_tool_cmd="$(get_merge_tool_cmd "$merge_tool")" merge_tool="$(get_merge_tool)" || exit
merge_tool_path="$(get_merge_tool_path "$merge_tool")" || exit fi
# Launch the merge tool on each path provided by 'git diff' # Launch the merge tool on each path provided by 'git diff'
while test $# -gt 6 while test $# -gt 6

View File

@ -8,25 +8,20 @@ merge_mode() {
} }
translate_merge_tool_path () { translate_merge_tool_path () {
if test -n "$2"; then case "$1" in
echo "$2" vimdiff)
else echo vim
case "$1" in ;;
vimdiff) gvimdiff)
path=vim echo gvim
;; ;;
gvimdiff) emerge)
path=gvim echo emacs
;; ;;
emerge) *)
path=emacs echo "$1"
;; ;;
*) esac
path="$1"
;;
esac
echo "$path"
fi
} }
check_unchanged () { check_unchanged () {
@ -69,15 +64,22 @@ valid_tool () {
} }
get_merge_tool_cmd () { get_merge_tool_cmd () {
diff_mode && # Prints the custom command for a merge tool
custom_cmd="$(git config difftool.$1.cmd)" if test -n "$1"; then
test -z "$custom_cmd" && merge_tool="$1"
custom_cmd="$(git config mergetool.$1.cmd)" else
test -n "$custom_cmd" && merge_tool="$(get_merge_tool)"
echo "$custom_cmd" 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 () { run_merge_tool () {
merge_tool_path="$(get_merge_tool_path "$1")" || exit
base_present="$2" base_present="$2"
status=0 status=0
@ -103,9 +105,9 @@ run_merge_tool () {
status=$? status=$?
else else
("$merge_tool_path" --auto \ ("$merge_tool_path" --auto \
--L1 "$MERGED (A)" \ --L1 "$MERGED (A)" \
--L2 "$MERGED (B)" "$LOCAL" "$REMOTE" \ --L2 "$MERGED (B)" "$LOCAL" "$REMOTE" \
> /dev/null 2>&1) > /dev/null 2>&1)
fi fi
;; ;;
kompare) kompare)
@ -262,6 +264,7 @@ run_merge_tool () {
fi fi
;; ;;
*) *)
merge_tool_cmd="$(get_merge_tool_cmd "$1")"
if test -z "$merge_tool_cmd"; then if test -z "$merge_tool_cmd"; then
if merge_mode; then if merge_mode; then
status=1 status=1
@ -269,7 +272,9 @@ run_merge_tool () {
break break
fi fi
if merge_mode; then if merge_mode; then
if test "$merge_tool_trust_exit_code" = "false"; then trust_exit_code="$(git config --bool \
mergetool."$1".trustExitCode || echo false)"
if test "$trust_exit_code" = "false"; then
touch "$BACKUP" touch "$BACKUP"
( eval $merge_tool_cmd ) ( eval $merge_tool_cmd )
check_unchanged check_unchanged
@ -315,64 +320,66 @@ guess_merge_tool () {
do do
merge_tool_path="$(translate_merge_tool_path "$i")" merge_tool_path="$(translate_merge_tool_path "$i")"
if type "$merge_tool_path" > /dev/null 2>&1; then if type "$merge_tool_path" > /dev/null 2>&1; then
merge_tool="$i" echo "$i"
break return 0
fi fi
done done
if test -z "$merge_tool" ; then echo >&2 "No known merge resolution program available."
echo >&2 "No known merge resolution program available." return 1
return 1
fi
echo "$merge_tool"
} }
get_configured_merge_tool () { get_configured_merge_tool () {
# Diff mode first tries diff.tool and falls back to merge.tool. # Diff mode first tries diff.tool and falls back to merge.tool.
# Merge mode only checks merge.tool # Merge mode only checks merge.tool
if diff_mode; then if diff_mode; then
tool=$(git config diff.tool) merge_tool=$(git config diff.tool || git config merge.tool)
fi else
if test -z "$tool"; then merge_tool=$(git config merge.tool)
tool=$(git config merge.tool)
fi fi
if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then 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 "git config option $TOOL_MODE.tool set to unknown tool: $merge_tool"
echo >&2 "Resetting to default..." echo >&2 "Resetting to default..."
return 1 return 1
fi fi
echo "$tool" echo "$merge_tool"
} }
get_merge_tool_path () { get_merge_tool_path () {
# A merge tool has been set, so verify that it's valid. # 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 if ! valid_tool "$merge_tool"; then
echo >&2 "Unknown merge tool $merge_tool" echo >&2 "Unknown merge tool $merge_tool"
exit 1 exit 1
fi fi
if diff_mode; then if diff_mode; then
merge_tool_path=$(git config difftool."$merge_tool".path) merge_tool_path=$(git config difftool."$merge_tool".path ||
fi git config mergetool."$merge_tool".path)
if test -z "$merge_tool_path"; then else
merge_tool_path=$(git config mergetool."$merge_tool".path) merge_tool_path=$(git config mergetool."$merge_tool".path)
fi fi
merge_tool_path="$(translate_merge_tool_path "$merge_tool" "$merge_tool_path")" if test -z "$merge_tool_path"; then
if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then merge_tool_path="$(translate_merge_tool_path "$merge_tool")"
echo >&2 "The $TOOL_MODE tool $merge_tool is not available as '$merge_tool_path'" 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 exit 1
fi fi
echo "$merge_tool_path" echo "$merge_tool_path"
} }
get_merge_tool () { get_merge_tool () {
merge_tool="$1"
# Check if a merge tool has been configured # Check if a merge tool has been configured
if test -z "$merge_tool"; then merge_tool=$(get_configured_merge_tool)
merge_tool=$(get_configured_merge_tool)
fi
# Try to guess an appropriate merge tool if no tool has been set. # Try to guess an appropriate merge tool if no tool has been set.
if test -z "$merge_tool"; then if test -z "$merge_tool"; then
merge_tool=$(guess_merge_tool) || exit merge_tool="$(guess_merge_tool)" || exit
fi fi
echo "$merge_tool" echo "$merge_tool"
} }

View File

@ -174,9 +174,11 @@ merge_file () {
read ans read ans
fi fi
present=false if base_present; then
base_present && present=true
present=true else
present=false
fi
if ! run_merge_tool "$merge_tool" "$present"; then if ! run_merge_tool "$merge_tool" "$present"; then
echo "merge of $MERGED failed" 1>&2 echo "merge of $MERGED failed" 1>&2
@ -254,12 +256,11 @@ prompt_after_failed_merge() {
done done
} }
merge_tool=$(get_merge_tool "$merge_tool") || exit if test -z "$merge_tool"; then
merge_tool_cmd="$(get_merge_tool_cmd "$merge_tool")" merge_tool=$(get_merge_tool "$merge_tool") || exit
merge_tool_path="$(get_merge_tool_path "$merge_tool")" || exit fi
merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)" merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)"
merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)" merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
merge_tool_trust_exit_code="$(git config --bool mergetool."$merge_tool".trustExitCode || echo false)"
last_status=0 last_status=0
rollup_status=0 rollup_status=0