2013-11-26 05:03:52 +08:00
|
|
|
# git-mergetool--lib is a shell library for common merge tool functions
|
2013-01-28 08:52:26 +08:00
|
|
|
|
|
|
|
: ${MERGE_TOOLS_DIR=$(git --exec-path)/mergetools}
|
2013-01-27 08:46:12 +08:00
|
|
|
|
2015-05-20 17:07:22 +08:00
|
|
|
IFS='
|
|
|
|
'
|
|
|
|
|
2013-01-28 08:52:25 +08:00
|
|
|
mode_ok () {
|
|
|
|
if diff_mode
|
|
|
|
then
|
|
|
|
can_diff
|
|
|
|
elif merge_mode
|
|
|
|
then
|
|
|
|
can_merge
|
|
|
|
else
|
|
|
|
false
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
is_available () {
|
|
|
|
merge_tool_path=$(translate_merge_tool_path "$1") &&
|
|
|
|
type "$merge_tool_path" >/dev/null 2>&1
|
|
|
|
}
|
|
|
|
|
2013-01-31 03:55:46 +08:00
|
|
|
list_config_tools () {
|
|
|
|
section=$1
|
|
|
|
line_prefix=${2:-}
|
|
|
|
|
|
|
|
git config --get-regexp $section'\..*\.cmd' |
|
|
|
|
while read -r key value
|
|
|
|
do
|
|
|
|
toolname=${key#$section.}
|
|
|
|
toolname=${toolname%.cmd}
|
|
|
|
|
|
|
|
printf "%s%s\n" "$line_prefix" "$toolname"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2013-01-28 08:52:25 +08:00
|
|
|
show_tool_names () {
|
|
|
|
condition=${1:-true} per_line_prefix=${2:-} preamble=${3:-}
|
|
|
|
not_found_msg=${4:-}
|
2013-01-31 03:55:46 +08:00
|
|
|
extra_content=${5:-}
|
2013-01-28 08:52:25 +08:00
|
|
|
|
|
|
|
shown_any=
|
|
|
|
( cd "$MERGE_TOOLS_DIR" && ls ) | {
|
2020-07-30 05:31:12 +08:00
|
|
|
while read scriptname
|
|
|
|
do
|
|
|
|
setup_tool "$scriptname" 2>/dev/null
|
mergetool--lib: fix '--tool-help' to correctly show available tools
Commit 83bbf9b92e (mergetool--lib: improve support for vimdiff-style tool
variants, 2020-07-29) introduced a regression in the output of `git mergetool
--tool-help` and `git difftool --tool-help` [1].
In function 'show_tool_names' in git-mergetool--lib.sh, we loop over the
supported mergetools and their variants and accumulate them in the variable
'variants', separating them with a literal '\n'.
The code then uses 'echo $variants' to turn these '\n' into newlines, but this
behaviour is not portable, it just happens to work in some shells, like
dash(1)'s 'echo' builtin.
For shells in which 'echo' does not turn '\n' into newlines, the end
result is that the only tools that are shown are the existing variants
(except the last variant alphabetically), since the variants are
separated by actual newlines in '$variants' because of the several
'echo' calls in mergetools/{bc,vimdiff}::list_tool_variants.
Fix this bug by embedding an actual line feed into `variants` in
show_tool_names(). While at it, replace `sort | uniq` by `sort -u`.
To prevent future regressions, add a simple test that checks that a few
known tools are correctly shown (let's avoid counting the total number
of tools to lessen the maintenance burden when new tools are added or if
'--tool-help' learns additional logic, like hiding tools depending on
the current platform).
[1] https://lore.kernel.org/git/CADtb9DyozjgAsdFYL8fFBEWmq7iz4=prZYVUdH9W-J5CKVS4OA@mail.gmail.com/
Reported-by: Philippe Blain <levraiphilippeblain@gmail.com>
Based-on-patch-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-07 09:09:05 +08:00
|
|
|
# We need an actual line feed here
|
|
|
|
variants="$variants
|
|
|
|
$(list_tool_variants)"
|
2020-07-30 05:31:12 +08:00
|
|
|
done
|
mergetool--lib: fix '--tool-help' to correctly show available tools
Commit 83bbf9b92e (mergetool--lib: improve support for vimdiff-style tool
variants, 2020-07-29) introduced a regression in the output of `git mergetool
--tool-help` and `git difftool --tool-help` [1].
In function 'show_tool_names' in git-mergetool--lib.sh, we loop over the
supported mergetools and their variants and accumulate them in the variable
'variants', separating them with a literal '\n'.
The code then uses 'echo $variants' to turn these '\n' into newlines, but this
behaviour is not portable, it just happens to work in some shells, like
dash(1)'s 'echo' builtin.
For shells in which 'echo' does not turn '\n' into newlines, the end
result is that the only tools that are shown are the existing variants
(except the last variant alphabetically), since the variants are
separated by actual newlines in '$variants' because of the several
'echo' calls in mergetools/{bc,vimdiff}::list_tool_variants.
Fix this bug by embedding an actual line feed into `variants` in
show_tool_names(). While at it, replace `sort | uniq` by `sort -u`.
To prevent future regressions, add a simple test that checks that a few
known tools are correctly shown (let's avoid counting the total number
of tools to lessen the maintenance burden when new tools are added or if
'--tool-help' learns additional logic, like hiding tools depending on
the current platform).
[1] https://lore.kernel.org/git/CADtb9DyozjgAsdFYL8fFBEWmq7iz4=prZYVUdH9W-J5CKVS4OA@mail.gmail.com/
Reported-by: Philippe Blain <levraiphilippeblain@gmail.com>
Based-on-patch-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-07 09:09:05 +08:00
|
|
|
variants="$(echo "$variants" | sort -u)"
|
2020-07-30 05:31:12 +08:00
|
|
|
|
|
|
|
for toolname in $variants
|
2013-01-28 08:52:25 +08:00
|
|
|
do
|
|
|
|
if setup_tool "$toolname" 2>/dev/null &&
|
|
|
|
(eval "$condition" "$toolname")
|
|
|
|
then
|
|
|
|
if test -n "$preamble"
|
|
|
|
then
|
|
|
|
printf "%s\n" "$preamble"
|
|
|
|
preamble=
|
|
|
|
fi
|
|
|
|
shown_any=yes
|
vimdiff: add tool documentation
Running 'git {merge,diff}tool --tool-help' now also prints usage
information about the vimdiff tool (and its variants) instead of just
its name.
Two new functions ('diff_cmd_help()' and 'merge_cmd_help()') have been
added to the set of functions that each merge tool (ie. scripts found
inside "mergetools/") can overwrite to provided tool specific
information.
Right now, only 'mergetools/vimdiff' implements these functions, but
other tools are encouraged to do so in the future, specially if they
take configuration options not explained anywhere else (as it is the
case with the 'vimdiff' tool and the new 'layout' option)
Note that the function 'show_tool_names', used in the implementation of
'git mergetool --tool-help', is also used in Documentation/Makefile to
generate the list of allowed values for the configuration variables
'{diff,merge}.{gui,}tool'. Adjust the rule so its output is an Asciidoc
"description list" instead of a plain list, with the tool name as the
item and the newly added tool description as the description.
In addition, a section has been added to
"Documentation/git-mergetool.txt" to explain the new "layout"
configuration option with examples.
Helped-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-31 03:19:08 +08:00
|
|
|
printf "%s%-15s %s\n" "$per_line_prefix" "$toolname" $(diff_mode && diff_cmd_help "$toolname" || merge_cmd_help "$toolname")
|
2013-01-28 08:52:25 +08:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2013-01-31 03:55:46 +08:00
|
|
|
if test -n "$extra_content"
|
|
|
|
then
|
|
|
|
if test -n "$preamble"
|
|
|
|
then
|
|
|
|
# Note: no '\n' here since we don't want a
|
|
|
|
# blank line if there is no initial content.
|
|
|
|
printf "%s" "$preamble"
|
|
|
|
preamble=
|
|
|
|
fi
|
|
|
|
shown_any=yes
|
|
|
|
printf "\n%s\n" "$extra_content"
|
|
|
|
fi
|
|
|
|
|
2013-01-28 08:52:25 +08:00
|
|
|
if test -n "$preamble" && test -n "$not_found_msg"
|
|
|
|
then
|
|
|
|
printf "%s\n" "$not_found_msg"
|
|
|
|
fi
|
|
|
|
|
|
|
|
test -n "$shown_any"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-29 14:21:11 +08:00
|
|
|
diff_mode () {
|
2009-04-08 15:17:20 +08:00
|
|
|
test "$TOOL_MODE" = diff
|
|
|
|
}
|
|
|
|
|
2019-04-29 14:21:11 +08:00
|
|
|
merge_mode () {
|
2009-04-08 15:17:20 +08:00
|
|
|
test "$TOOL_MODE" = merge
|
|
|
|
}
|
|
|
|
|
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 23:27:43 +08:00
|
|
|
get_gui_default () {
|
|
|
|
if diff_mode
|
|
|
|
then
|
|
|
|
GUI_DEFAULT_KEY="difftool.guiDefault"
|
|
|
|
else
|
|
|
|
GUI_DEFAULT_KEY="mergetool.guiDefault"
|
|
|
|
fi
|
|
|
|
GUI_DEFAULT_CONFIG_LCASE=$(git config --default false --get "$GUI_DEFAULT_KEY" | tr 'A-Z' 'a-z')
|
|
|
|
if test "$GUI_DEFAULT_CONFIG_LCASE" = "auto"
|
|
|
|
then
|
|
|
|
if test -n "$DISPLAY"
|
|
|
|
then
|
|
|
|
GUI_DEFAULT=true
|
|
|
|
else
|
|
|
|
GUI_DEFAULT=false
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
GUI_DEFAULT=$(git config --default false --bool --get "$GUI_DEFAULT_KEY")
|
|
|
|
subshell_exit_status=$?
|
|
|
|
if test $subshell_exit_status -ne 0
|
|
|
|
then
|
|
|
|
exit $subshell_exit_status
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
echo $GUI_DEFAULT
|
|
|
|
}
|
|
|
|
|
2019-04-29 14:21:11 +08:00
|
|
|
gui_mode () {
|
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 23:27:43 +08:00
|
|
|
if test -z "$GIT_MERGETOOL_GUI"
|
|
|
|
then
|
|
|
|
GIT_MERGETOOL_GUI=$(get_gui_default)
|
|
|
|
if test $? -ne 0
|
|
|
|
then
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
fi
|
2019-04-29 14:21:11 +08:00
|
|
|
test "$GIT_MERGETOOL_GUI" = true
|
|
|
|
}
|
|
|
|
|
2009-04-08 15:17:20 +08:00
|
|
|
translate_merge_tool_path () {
|
2011-08-18 15:23:46 +08:00
|
|
|
echo "$1"
|
2009-04-08 15:17:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
check_unchanged () {
|
2011-08-18 15:23:45 +08:00
|
|
|
if test "$MERGED" -nt "$BACKUP"
|
|
|
|
then
|
2014-11-21 09:20:27 +08:00
|
|
|
return 0
|
2009-04-08 15:17:20 +08:00
|
|
|
else
|
2011-08-18 15:23:45 +08:00
|
|
|
while true
|
|
|
|
do
|
2009-04-08 15:17:20 +08:00
|
|
|
echo "$MERGED seems unchanged."
|
2016-04-12 22:44:20 +08:00
|
|
|
printf "Was the merge successful [y/n]? "
|
2011-09-20 07:40:52 +08:00
|
|
|
read answer || return 1
|
2009-04-08 15:17:20 +08:00
|
|
|
case "$answer" in
|
2014-11-21 09:20:27 +08:00
|
|
|
y*|Y*) return 0 ;;
|
|
|
|
n*|N*) return 1 ;;
|
2009-04-08 15:17:20 +08:00
|
|
|
esac
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
valid_tool () {
|
2013-01-28 08:52:23 +08:00
|
|
|
setup_tool "$1" && return 0
|
|
|
|
cmd=$(get_merge_tool_cmd "$1")
|
|
|
|
test -n "$cmd"
|
2011-08-18 15:23:46 +08:00
|
|
|
}
|
|
|
|
|
2013-06-17 01:51:22 +08:00
|
|
|
setup_user_tool () {
|
|
|
|
merge_tool_cmd=$(get_merge_tool_cmd "$tool")
|
|
|
|
test -n "$merge_tool_cmd" || return 1
|
|
|
|
|
|
|
|
diff_cmd () {
|
|
|
|
( eval $merge_tool_cmd )
|
|
|
|
}
|
|
|
|
|
|
|
|
merge_cmd () {
|
2016-11-29 17:38:07 +08:00
|
|
|
( eval $merge_tool_cmd )
|
2013-06-17 01:51:22 +08:00
|
|
|
}
|
2020-11-12 04:33:18 +08:00
|
|
|
|
|
|
|
list_tool_variants () {
|
|
|
|
echo "$tool"
|
|
|
|
}
|
2013-06-17 01:51:22 +08:00
|
|
|
}
|
|
|
|
|
2011-08-18 15:23:46 +08:00
|
|
|
setup_tool () {
|
2013-01-27 08:46:12 +08:00
|
|
|
tool="$1"
|
|
|
|
|
2013-07-29 16:18:21 +08:00
|
|
|
# Fallback definitions, to be overridden by tools.
|
2013-01-27 08:46:12 +08:00
|
|
|
can_merge () {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
can_diff () {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
diff_cmd () {
|
2014-11-21 09:20:27 +08:00
|
|
|
return 1
|
2013-01-27 08:46:12 +08:00
|
|
|
}
|
|
|
|
|
vimdiff: add tool documentation
Running 'git {merge,diff}tool --tool-help' now also prints usage
information about the vimdiff tool (and its variants) instead of just
its name.
Two new functions ('diff_cmd_help()' and 'merge_cmd_help()') have been
added to the set of functions that each merge tool (ie. scripts found
inside "mergetools/") can overwrite to provided tool specific
information.
Right now, only 'mergetools/vimdiff' implements these functions, but
other tools are encouraged to do so in the future, specially if they
take configuration options not explained anywhere else (as it is the
case with the 'vimdiff' tool and the new 'layout' option)
Note that the function 'show_tool_names', used in the implementation of
'git mergetool --tool-help', is also used in Documentation/Makefile to
generate the list of allowed values for the configuration variables
'{diff,merge}.{gui,}tool'. Adjust the rule so its output is an Asciidoc
"description list" instead of a plain list, with the tool name as the
item and the newly added tool description as the description.
In addition, a section has been added to
"Documentation/git-mergetool.txt" to explain the new "layout"
configuration option with examples.
Helped-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-31 03:19:08 +08:00
|
|
|
diff_cmd_help () {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2013-01-27 08:46:12 +08:00
|
|
|
merge_cmd () {
|
2014-11-21 09:20:27 +08:00
|
|
|
return 1
|
2013-01-27 08:46:12 +08:00
|
|
|
}
|
2011-08-18 15:23:46 +08:00
|
|
|
|
vimdiff: add tool documentation
Running 'git {merge,diff}tool --tool-help' now also prints usage
information about the vimdiff tool (and its variants) instead of just
its name.
Two new functions ('diff_cmd_help()' and 'merge_cmd_help()') have been
added to the set of functions that each merge tool (ie. scripts found
inside "mergetools/") can overwrite to provided tool specific
information.
Right now, only 'mergetools/vimdiff' implements these functions, but
other tools are encouraged to do so in the future, specially if they
take configuration options not explained anywhere else (as it is the
case with the 'vimdiff' tool and the new 'layout' option)
Note that the function 'show_tool_names', used in the implementation of
'git mergetool --tool-help', is also used in Documentation/Makefile to
generate the list of allowed values for the configuration variables
'{diff,merge}.{gui,}tool'. Adjust the rule so its output is an Asciidoc
"description list" instead of a plain list, with the tool name as the
item and the newly added tool description as the description.
In addition, a section has been added to
"Documentation/git-mergetool.txt" to explain the new "layout"
configuration option with examples.
Helped-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-31 03:19:08 +08:00
|
|
|
merge_cmd_help () {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2021-02-10 04:07:12 +08:00
|
|
|
hide_resolved_enabled () {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2013-01-27 08:46:12 +08:00
|
|
|
translate_merge_tool_path () {
|
|
|
|
echo "$1"
|
|
|
|
}
|
|
|
|
|
2020-07-30 05:31:12 +08:00
|
|
|
list_tool_variants () {
|
|
|
|
echo "$tool"
|
|
|
|
}
|
|
|
|
|
2016-11-29 17:38:07 +08:00
|
|
|
# Most tools' exit codes cannot be trusted, so By default we ignore
|
|
|
|
# their exit code and check the merged file's modification time in
|
|
|
|
# check_unchanged() to determine whether or not the merge was
|
|
|
|
# successful. The return value from run_merge_cmd, by default, is
|
|
|
|
# determined by check_unchanged().
|
|
|
|
#
|
|
|
|
# When a tool's exit code can be trusted then the return value from
|
|
|
|
# run_merge_cmd is simply the tool's exit code, and check_unchanged()
|
|
|
|
# is not called.
|
|
|
|
#
|
|
|
|
# The return value of exit_code_trustable() tells us whether or not we
|
|
|
|
# can trust the tool's exit code.
|
|
|
|
#
|
|
|
|
# User-defined and built-in tools default to false.
|
|
|
|
# Built-in tools advertise that their exit code is trustable by
|
|
|
|
# redefining exit_code_trustable() to true.
|
|
|
|
|
|
|
|
exit_code_trustable () {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2020-07-30 05:31:12 +08:00
|
|
|
if test -f "$MERGE_TOOLS_DIR/$tool"
|
2011-08-18 15:23:46 +08:00
|
|
|
then
|
2020-07-30 05:31:12 +08:00
|
|
|
. "$MERGE_TOOLS_DIR/$tool"
|
|
|
|
elif test -f "$MERGE_TOOLS_DIR/${tool%[0-9]}"
|
|
|
|
then
|
|
|
|
. "$MERGE_TOOLS_DIR/${tool%[0-9]}"
|
|
|
|
else
|
2013-06-17 01:51:22 +08:00
|
|
|
setup_user_tool
|
|
|
|
return $?
|
2011-08-18 15:23:46 +08:00
|
|
|
fi
|
|
|
|
|
2013-06-17 01:51:22 +08:00
|
|
|
# Now let the user override the default command for the tool. If
|
|
|
|
# they have not done so then this will return 1 which we ignore.
|
|
|
|
setup_user_tool
|
2011-08-18 15:23:46 +08:00
|
|
|
|
2020-07-30 05:31:12 +08:00
|
|
|
if ! list_tool_variants | grep -q "^$tool$"
|
|
|
|
then
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
2011-08-18 15:23:46 +08:00
|
|
|
if merge_mode && ! can_merge
|
|
|
|
then
|
|
|
|
echo "error: '$tool' can not be used to resolve merges" >&2
|
2013-01-27 08:40:06 +08:00
|
|
|
return 1
|
2011-08-18 15:23:46 +08:00
|
|
|
elif diff_mode && ! can_diff
|
|
|
|
then
|
|
|
|
echo "error: '$tool' can only be used to resolve merges" >&2
|
2013-01-27 08:40:06 +08:00
|
|
|
return 1
|
2011-08-18 15:23:46 +08:00
|
|
|
fi
|
|
|
|
return 0
|
2009-04-08 15:17:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
get_merge_tool_cmd () {
|
2011-08-18 15:23:46 +08:00
|
|
|
merge_tool="$1"
|
2011-08-18 15:23:45 +08:00
|
|
|
if diff_mode
|
|
|
|
then
|
2013-01-28 08:52:23 +08:00
|
|
|
git config "difftool.$merge_tool.cmd" ||
|
|
|
|
git config "mergetool.$merge_tool.cmd"
|
2009-04-12 11:41:56 +08:00
|
|
|
else
|
2013-01-28 08:52:23 +08:00
|
|
|
git config "mergetool.$merge_tool.cmd"
|
2009-04-12 11:41:56 +08:00
|
|
|
fi
|
2009-04-08 15:17:20 +08:00
|
|
|
}
|
|
|
|
|
2016-11-29 17:38:07 +08:00
|
|
|
trust_exit_code () {
|
|
|
|
if git config --bool "mergetool.$1.trustExitCode"
|
|
|
|
then
|
|
|
|
:; # OK
|
|
|
|
elif exit_code_trustable
|
|
|
|
then
|
|
|
|
echo true
|
|
|
|
else
|
|
|
|
echo false
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-02-10 04:07:11 +08:00
|
|
|
initialize_merge_tool () {
|
|
|
|
# Bring tool-specific functions into scope
|
|
|
|
setup_tool "$1" || return 1
|
|
|
|
}
|
2016-11-29 17:38:07 +08:00
|
|
|
|
2011-08-18 15:23:46 +08:00
|
|
|
# Entry point for running tools
|
2009-04-08 15:17:20 +08:00
|
|
|
run_merge_tool () {
|
2011-05-26 14:21:01 +08:00
|
|
|
# If GIT_PREFIX is empty then we cannot use it in tools
|
|
|
|
# that expect to be able to chdir() to its value.
|
|
|
|
GIT_PREFIX=${GIT_PREFIX:-.}
|
|
|
|
export GIT_PREFIX
|
|
|
|
|
2013-01-28 08:52:23 +08:00
|
|
|
merge_tool_path=$(get_merge_tool_path "$1") || exit
|
2009-04-08 15:17:20 +08:00
|
|
|
base_present="$2"
|
|
|
|
|
2011-08-18 15:23:46 +08:00
|
|
|
if merge_mode
|
|
|
|
then
|
2012-09-25 15:48:11 +08:00
|
|
|
run_merge_cmd "$1"
|
2011-08-18 15:23:46 +08:00
|
|
|
else
|
2012-09-25 15:48:11 +08:00
|
|
|
run_diff_cmd "$1"
|
2011-08-18 15:23:46 +08:00
|
|
|
fi
|
2009-04-08 15:17:20 +08:00
|
|
|
}
|
|
|
|
|
2012-09-25 15:48:11 +08:00
|
|
|
# Run a either a configured or built-in diff tool
|
|
|
|
run_diff_cmd () {
|
2013-06-17 01:51:22 +08:00
|
|
|
diff_cmd "$1"
|
2012-09-25 15:48:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
# Run a either a configured or built-in merge tool
|
|
|
|
run_merge_cmd () {
|
2016-11-29 17:38:07 +08:00
|
|
|
mergetool_trust_exit_code=$(trust_exit_code "$1")
|
|
|
|
if test "$mergetool_trust_exit_code" = "true"
|
|
|
|
then
|
|
|
|
merge_cmd "$1"
|
|
|
|
else
|
|
|
|
touch "$BACKUP"
|
|
|
|
merge_cmd "$1"
|
|
|
|
check_unchanged
|
|
|
|
fi
|
2012-09-25 15:48:11 +08:00
|
|
|
}
|
|
|
|
|
2012-07-24 05:16:12 +08:00
|
|
|
list_merge_tool_candidates () {
|
2011-08-18 15:23:45 +08:00
|
|
|
if merge_mode
|
|
|
|
then
|
2009-04-08 15:17:20 +08:00
|
|
|
tools="tortoisemerge"
|
|
|
|
else
|
|
|
|
tools="kompare"
|
|
|
|
fi
|
2011-08-18 15:23:45 +08:00
|
|
|
if test -n "$DISPLAY"
|
|
|
|
then
|
|
|
|
if test -n "$GNOME_DESKTOP_SESSION_ID"
|
|
|
|
then
|
2009-04-08 15:17:20 +08:00
|
|
|
tools="meld opendiff kdiff3 tkdiff xxdiff $tools"
|
|
|
|
else
|
|
|
|
tools="opendiff kdiff3 tkdiff xxdiff meld $tools"
|
|
|
|
fi
|
2013-10-13 06:29:35 +08:00
|
|
|
tools="$tools gvimdiff diffuse diffmerge ecmerge"
|
2014-10-21 06:49:36 +08:00
|
|
|
tools="$tools p4merge araxis bc codecompare"
|
2019-04-04 15:34:38 +08:00
|
|
|
tools="$tools smerge"
|
2009-04-08 15:17:20 +08:00
|
|
|
fi
|
2009-11-24 07:29:17 +08:00
|
|
|
case "${VISUAL:-$EDITOR}" in
|
2020-07-30 05:31:13 +08:00
|
|
|
*nvim*)
|
|
|
|
tools="$tools nvimdiff vimdiff emerge"
|
|
|
|
;;
|
2009-11-24 07:29:17 +08:00
|
|
|
*vim*)
|
2020-07-30 05:31:13 +08:00
|
|
|
tools="$tools vimdiff nvimdiff emerge"
|
2009-11-24 07:29:17 +08:00
|
|
|
;;
|
|
|
|
*)
|
2020-07-30 05:31:13 +08:00
|
|
|
tools="$tools emerge vimdiff nvimdiff"
|
2009-11-24 07:29:17 +08:00
|
|
|
;;
|
|
|
|
esac
|
2012-07-24 05:16:12 +08:00
|
|
|
}
|
|
|
|
|
2013-01-25 17:43:48 +08:00
|
|
|
show_tool_help () {
|
2013-10-04 22:34:53 +08:00
|
|
|
tool_opt="'git ${TOOL_MODE}tool --tool=<tool>'"
|
2013-01-25 17:43:54 +08:00
|
|
|
|
2013-01-28 08:52:25 +08:00
|
|
|
tab=' '
|
|
|
|
LF='
|
|
|
|
'
|
|
|
|
any_shown=no
|
2013-01-25 17:43:50 +08:00
|
|
|
|
|
|
|
cmd_name=${TOOL_MODE}tool
|
2013-01-31 03:55:46 +08:00
|
|
|
config_tools=$({
|
|
|
|
diff_mode && list_config_tools difftool "$tab$tab"
|
|
|
|
list_config_tools mergetool "$tab$tab"
|
|
|
|
} | sort)
|
|
|
|
extra_content=
|
|
|
|
if test -n "$config_tools"
|
|
|
|
then
|
|
|
|
extra_content="${tab}user-defined:${LF}$config_tools"
|
|
|
|
fi
|
|
|
|
|
2013-01-28 08:52:25 +08:00
|
|
|
show_tool_names 'mode_ok && is_available' "$tab$tab" \
|
|
|
|
"$tool_opt may be set to one of the following:" \
|
2013-01-31 03:55:46 +08:00
|
|
|
"No suitable tool for 'git $cmd_name --tool=<tool>' found." \
|
|
|
|
"$extra_content" &&
|
2013-01-28 08:52:25 +08:00
|
|
|
any_shown=yes
|
|
|
|
|
|
|
|
show_tool_names 'mode_ok && ! is_available' "$tab$tab" \
|
|
|
|
"${LF}The following tools are valid, but not currently available:" &&
|
|
|
|
any_shown=yes
|
|
|
|
|
|
|
|
if test "$any_shown" = yes
|
2013-01-25 17:43:48 +08:00
|
|
|
then
|
|
|
|
echo
|
|
|
|
echo "Some of the tools listed above only work in a windowed"
|
|
|
|
echo "environment. If run in a terminal-only session, they will fail."
|
|
|
|
fi
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
2012-07-24 05:16:12 +08:00
|
|
|
guess_merge_tool () {
|
|
|
|
list_merge_tool_candidates
|
2013-01-28 08:52:24 +08:00
|
|
|
cat >&2 <<-EOF
|
|
|
|
|
|
|
|
This message is displayed because '$TOOL_MODE.tool' is not configured.
|
|
|
|
See 'git ${TOOL_MODE}tool --tool-help' or 'git help config' for more details.
|
|
|
|
'git ${TOOL_MODE}tool' will now attempt to use one of the following tools:
|
|
|
|
$tools
|
|
|
|
EOF
|
2009-04-08 15:17:20 +08:00
|
|
|
|
|
|
|
# Loop over each candidate and stop when a valid merge tool is found.
|
2015-06-19 17:30:55 +08:00
|
|
|
IFS=' '
|
2013-01-28 08:52:25 +08:00
|
|
|
for tool in $tools
|
2009-04-08 15:17:20 +08:00
|
|
|
do
|
2013-01-28 08:52:25 +08:00
|
|
|
is_available "$tool" && echo "$tool" && return 0
|
2009-04-08 15:17:20 +08:00
|
|
|
done
|
|
|
|
|
2013-01-28 08:52:25 +08:00
|
|
|
echo >&2 "No known ${TOOL_MODE} tool is available."
|
2009-04-12 11:41:56 +08:00
|
|
|
return 1
|
2009-04-08 15:17:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
get_configured_merge_tool () {
|
2019-04-29 14:21:14 +08:00
|
|
|
keys=
|
2011-08-18 15:23:45 +08:00
|
|
|
if diff_mode
|
|
|
|
then
|
2019-04-29 14:21:14 +08:00
|
|
|
if gui_mode
|
|
|
|
then
|
|
|
|
keys="diff.guitool merge.guitool diff.tool merge.tool"
|
|
|
|
else
|
|
|
|
keys="diff.tool merge.tool"
|
|
|
|
fi
|
2009-04-12 11:41:56 +08:00
|
|
|
else
|
2019-04-29 14:21:14 +08:00
|
|
|
if gui_mode
|
|
|
|
then
|
|
|
|
keys="merge.guitool merge.tool"
|
|
|
|
else
|
|
|
|
keys="merge.tool"
|
|
|
|
fi
|
2009-04-08 15:17:20 +08:00
|
|
|
fi
|
2019-04-29 14:21:14 +08:00
|
|
|
|
|
|
|
merge_tool=$(
|
|
|
|
IFS=' '
|
|
|
|
for key in $keys
|
|
|
|
do
|
|
|
|
selected=$(git config $key)
|
|
|
|
if test -n "$selected"
|
|
|
|
then
|
|
|
|
echo "$selected"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
done)
|
|
|
|
|
2011-08-18 15:23:45 +08:00
|
|
|
if test -n "$merge_tool" && ! valid_tool "$merge_tool"
|
|
|
|
then
|
2018-10-25 00:25:31 +08:00
|
|
|
echo >&2 "git config option $TOOL_MODE.${gui_prefix}tool set to unknown tool: $merge_tool"
|
2009-04-08 15:17:20 +08:00
|
|
|
echo >&2 "Resetting to default..."
|
|
|
|
return 1
|
|
|
|
fi
|
2009-04-12 11:41:56 +08:00
|
|
|
echo "$merge_tool"
|
2009-04-08 15:17:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
get_merge_tool_path () {
|
|
|
|
# A merge tool has been set, so verify that it's valid.
|
2011-08-18 15:23:46 +08:00
|
|
|
merge_tool="$1"
|
2011-08-18 15:23:45 +08:00
|
|
|
if ! valid_tool "$merge_tool"
|
|
|
|
then
|
2009-04-08 15:17:20 +08:00
|
|
|
echo >&2 "Unknown merge tool $merge_tool"
|
|
|
|
exit 1
|
|
|
|
fi
|
2011-08-18 15:23:45 +08:00
|
|
|
if diff_mode
|
|
|
|
then
|
2009-04-12 11:41:56 +08:00
|
|
|
merge_tool_path=$(git config difftool."$merge_tool".path ||
|
2011-08-05 21:31:29 +08:00
|
|
|
git config mergetool."$merge_tool".path)
|
2009-04-12 11:41:56 +08:00
|
|
|
else
|
|
|
|
merge_tool_path=$(git config mergetool."$merge_tool".path)
|
2009-04-08 15:17:20 +08:00
|
|
|
fi
|
2011-08-18 15:23:45 +08:00
|
|
|
if test -z "$merge_tool_path"
|
|
|
|
then
|
2013-01-28 08:52:23 +08:00
|
|
|
merge_tool_path=$(translate_merge_tool_path "$merge_tool")
|
2009-04-08 15:17:20 +08:00
|
|
|
fi
|
2009-04-12 11:41:56 +08:00
|
|
|
if test -z "$(get_merge_tool_cmd "$merge_tool")" &&
|
2011-08-18 15:23:45 +08:00
|
|
|
! type "$merge_tool_path" >/dev/null 2>&1
|
|
|
|
then
|
2009-04-12 11:41:56 +08:00
|
|
|
echo >&2 "The $TOOL_MODE tool $merge_tool is not available as"\
|
2011-08-05 21:31:29 +08:00
|
|
|
"'$merge_tool_path'"
|
2009-04-08 15:17:20 +08:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
echo "$merge_tool_path"
|
|
|
|
}
|
|
|
|
|
|
|
|
get_merge_tool () {
|
2019-04-29 14:21:08 +08:00
|
|
|
is_guessed=false
|
2009-04-08 15:17:20 +08:00
|
|
|
# Check if a merge tool has been configured
|
2013-01-28 08:52:23 +08:00
|
|
|
merge_tool=$(get_configured_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 23:27:43 +08:00
|
|
|
subshell_exit_status=$?
|
|
|
|
if test $subshell_exit_status -gt "1"
|
|
|
|
then
|
|
|
|
exit $subshell_exit_status
|
|
|
|
fi
|
2009-04-08 15:17:20 +08:00
|
|
|
# Try to guess an appropriate merge tool if no tool has been set.
|
2011-08-18 15:23:45 +08:00
|
|
|
if test -z "$merge_tool"
|
|
|
|
then
|
2013-01-28 08:52:23 +08:00
|
|
|
merge_tool=$(guess_merge_tool) || exit
|
2019-04-29 14:21:08 +08:00
|
|
|
is_guessed=true
|
2009-04-08 15:17:20 +08:00
|
|
|
fi
|
|
|
|
echo "$merge_tool"
|
2019-04-29 14:21:08 +08:00
|
|
|
test "$is_guessed" = false
|
2009-04-08 15:17:20 +08:00
|
|
|
}
|
2016-03-26 07:17:56 +08:00
|
|
|
|
|
|
|
mergetool_find_win32_cmd () {
|
|
|
|
executable=$1
|
|
|
|
sub_directory=$2
|
|
|
|
|
|
|
|
# Use $executable if it exists in $PATH
|
|
|
|
if type -p "$executable" >/dev/null 2>&1
|
|
|
|
then
|
|
|
|
printf '%s' "$executable"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Look for executable in the typical locations
|
|
|
|
for directory in $(env | grep -Ei '^PROGRAM(FILES(\(X86\))?|W6432)=' |
|
|
|
|
cut -d '=' -f 2- | sort -u)
|
|
|
|
do
|
|
|
|
if test -n "$directory" && test -x "$directory/$sub_directory/$executable"
|
|
|
|
then
|
|
|
|
printf '%s' "$directory/$sub_directory/$executable"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
printf '%s' "$executable"
|
|
|
|
}
|