git/git-difftool--helper.sh

130 lines
2.8 KiB
Bash
Raw Normal View History

#!/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, 2010 David Aguilar
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_merge=$(git config --bool mergetool.prompt || echo true)
prompt=$(git config --bool difftool.prompt || echo $prompt_merge)
if test "$prompt" = true
then
test -z "$GIT_DIFFTOOL_NO_PROMPT"
else
test -n "$GIT_DIFFTOOL_PROMPT"
fi
}
# Indicates that --extcmd=... was specified
use_ext_cmd () {
test -n "$GIT_DIFFTOOL_EXTCMD"
}
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 (%s/%s): '%s'\n" "$GIT_DIFF_PATH_COUNTER" \
"$GIT_DIFF_PATH_TOTAL" "$MERGED"
if use_ext_cmd
then
printf "Launch '%s' [Y/n]? " \
"$GIT_DIFFTOOL_EXTCMD"
else
printf "Launch '%s' [Y/n]? " "$merge_tool"
fi
read ans || return
if test "$ans" = n
then
return
fi
fi
if use_ext_cmd
then
export BASE
eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
else
initialize_merge_tool "$merge_tool"
# ignore the error from the above --- run_merge_tool
# will diagnose unusable tool by itself
run_merge_tool "$merge_tool"
fi
}
if ! use_ext_cmd
then
if test -n "$GIT_DIFF_TOOL"
then
merge_tool="$GIT_DIFF_TOOL"
else
merge_tool="$(get_merge_tool)"
mergetool: new config guiDefault supports auto-toggling gui by DISPLAY When no merge.tool or diff.tool is configured or manually selected, the selection of a default tool is sensitive to the DISPLAY variable; in a GUI session a gui-specific tool will be proposed if found, and otherwise a terminal-based one. This "GUI-optimizing" behavior is important because a GUI can make a huge difference to a user's ability to understand and correctly complete a non-trivial conflicting merge. Some time ago the merge.guitool and diff.guitool config options were introduced to enable users to configure both a GUI tool, and a non-GUI tool (with fallback if no GUI tool configured), in the same environment. Unfortunately, the --gui argument introduced to support the selection of the guitool is still explicit. When using configured tools, there is no equivalent of the no-tool-configured "propose a GUI tool if we are in a GUI environment" behavior. As proposed in <xmqqmtb8jsej.fsf@gitster.g>, introduce new configuration options, difftool.guiDefault and mergetool.guiDefault, supporting a special value "auto" which causes the corresponding tool or guitool to be selected depending on the presence of a non-empty DISPLAY value. Also support "true" to say "default to the guitool (unless --no-gui is passed on the commandline)", and "false" as the previous default behavior when these new configuration options are not specified. Signed-off-by: Tao Klerks <tao@klerks.biz> Acked-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-18 15:27:43 +00:00
subshell_exit_status=$?
if test $subshell_exit_status -gt 1
then
exit $subshell_exit_status
fi
fi
fi
if test -n "$GIT_DIFFTOOL_DIRDIFF"
then
LOCAL="$1"
REMOTE="$2"
initialize_merge_tool "$merge_tool"
# ignore the error from the above --- run_merge_tool
# will diagnose unusable tool by itself
run_merge_tool "$merge_tool" false
git-difftool--helper: honor `--trust-exit-code` with `--dir-diff` The `--trust-exit-code` option for git-diff-tool(1) was introduced via 2b52123fcf (difftool: add support for --trust-exit-code, 2014-10-26). When set, it makes us return the exit code of the invoked diff tool when diffing multiple files. This patch didn't change the code path where `--dir-diff` was passed because we already returned the exit code of the diff tool unconditionally in that case. This was changed a month later via c41d3fedd8 (difftool--helper: add explicit exit statement, 2014-11-20), where an explicit `exit 0` was added to the end of git-difftool--helper.sh. While the stated intent of that commit was merely a cleanup, it had the consequence that we now to ignore the exit code of the diff tool when `--dir-diff` was set. This change in behaviour is thus very likely an unintended side effect of this patch. Now there are two ways to fix this: - We can either restore the original behaviour, which unconditionally returned the exit code of the diffing tool when `--dir-diff` is passed. - Or we can make the `--dir-diff` case respect the `--trust-exit-code` flag. The fact that we have been ignoring exit codes for 7 years by now makes me rather lean towards the latter option. Furthermore, respecting the flag in one case but not the other would needlessly make the user interface more complex. Fix the bug so that we also honor `--trust-exit-code` for dir diffs and adjust the documentation accordingly. Reported-by: Jean-Rémy Falleri <jr.falleri@gmail.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-02-20 10:08:25 +00:00
status=$?
if test $status -ge 126
then
# Command not found (127), not executable (126) or
# exited via a signal (>= 128).
exit $status
fi
if test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true
then
exit $status
fi
else
# Launch the merge tool on each path provided by 'git diff'
while test $# -gt 6
do
launch_merge_tool "$1" "$2" "$5"
status=$?
if test $status -ge 126
then
# Command not found (127), not executable (126) or
# exited via a signal (>= 128).
exit $status
fi
if test "$status" != 0 &&
test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true
then
exit $status
fi
shift 7
done
fi
exit 0