15 Star 85 Fork 0

Gitee 极速下载 / Git

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/git/git
克隆/下载
git-mergetool--lib.sh 10.48 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
# git-mergetool--lib is a shell library for common merge tool functions
: ${MERGE_TOOLS_DIR=$(git --exec-path)/mergetools}
IFS='
'
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
}
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
}
show_tool_names () {
condition=${1:-true} per_line_prefix=${2:-} preamble=${3:-}
not_found_msg=${4:-}
extra_content=${5:-}
shown_any=
( cd "$MERGE_TOOLS_DIR" && ls ) | {
while read scriptname
do
setup_tool "$scriptname" 2>/dev/null
# We need an actual line feed here
variants="$variants
$(list_tool_variants)"
done
variants="$(echo "$variants" | sort -u)"
for toolname in $variants
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
printf "%s%-15s %s\n" "$per_line_prefix" "$toolname" $(diff_mode && diff_cmd_help "$toolname" || merge_cmd_help "$toolname")
fi
done
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
if test -n "$preamble" && test -n "$not_found_msg"
then
printf "%s\n" "$not_found_msg"
fi
test -n "$shown_any"
}
}
diff_mode () {
test "$TOOL_MODE" = diff
}
merge_mode () {
test "$TOOL_MODE" = merge
}
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
}
gui_mode () {
if test -z "$GIT_MERGETOOL_GUI"
then
GIT_MERGETOOL_GUI=$(get_gui_default)
if test $? -ne 0
then
exit 2
fi
fi
test "$GIT_MERGETOOL_GUI" = true
}
translate_merge_tool_path () {
echo "$1"
}
check_unchanged () {
if test "$MERGED" -nt "$BACKUP"
then
return 0
else
while true
do
echo "$MERGED seems unchanged."
printf "Was the merge successful [y/n]? "
read answer || return 1
case "$answer" in
y*|Y*) return 0 ;;
n*|N*) return 1 ;;
esac
done
fi
}
valid_tool () {
setup_tool "$1" && return 0
cmd=$(get_merge_tool_cmd "$1")
test -n "$cmd"
}
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 () {
( eval $merge_tool_cmd )
}
list_tool_variants () {
echo "$tool"
}
}
setup_tool () {
tool="$1"
# Fallback definitions, to be overridden by tools.
can_merge () {
return 0
}
can_diff () {
return 0
}
diff_cmd () {
return 1
}
diff_cmd_help () {
return 0
}
merge_cmd () {
return 1
}
merge_cmd_help () {
return 0
}
hide_resolved_enabled () {
return 0
}
translate_merge_tool_path () {
echo "$1"
}
list_tool_variants () {
echo "$tool"
}
# 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
}
if test -f "$MERGE_TOOLS_DIR/$tool"
then
. "$MERGE_TOOLS_DIR/$tool"
elif test -f "$MERGE_TOOLS_DIR/${tool%[0-9]}"
then
. "$MERGE_TOOLS_DIR/${tool%[0-9]}"
else
setup_user_tool
return $?
fi
# 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
if ! list_tool_variants | grep -q "^$tool$"
then
return 1
fi
if merge_mode && ! can_merge
then
echo "error: '$tool' can not be used to resolve merges" >&2
return 1
elif diff_mode && ! can_diff
then
echo "error: '$tool' can only be used to resolve merges" >&2
return 1
fi
return 0
}
get_merge_tool_cmd () {
merge_tool="$1"
if diff_mode
then
git config "difftool.$merge_tool.cmd" ||
git config "mergetool.$merge_tool.cmd"
else
git config "mergetool.$merge_tool.cmd"
fi
}
trust_exit_code () {
if git config --bool "mergetool.$1.trustExitCode"
then
:; # OK
elif exit_code_trustable
then
echo true
else
echo false
fi
}
initialize_merge_tool () {
# Bring tool-specific functions into scope
setup_tool "$1" || return 1
}
# Entry point for running tools
run_merge_tool () {
# 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
merge_tool_path=$(get_merge_tool_path "$1") || exit
base_present="$2"
if merge_mode
then
run_merge_cmd "$1"
else
run_diff_cmd "$1"
fi
}
# Run a either a configured or built-in diff tool
run_diff_cmd () {
diff_cmd "$1"
}
# Run a either a configured or built-in merge tool
run_merge_cmd () {
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
}
list_merge_tool_candidates () {
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 diffmerge ecmerge"
tools="$tools p4merge araxis bc codecompare"
tools="$tools smerge"
fi
case "${VISUAL:-$EDITOR}" in
*nvim*)
tools="$tools nvimdiff vimdiff emerge"
;;
*vim*)
tools="$tools vimdiff nvimdiff emerge"
;;
*)
tools="$tools emerge vimdiff nvimdiff"
;;
esac
}
show_tool_help () {
tool_opt="'git ${TOOL_MODE}tool --tool=<tool>'"
tab=' '
LF='
'
any_shown=no
cmd_name=${TOOL_MODE}tool
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
show_tool_names 'mode_ok && is_available' "$tab$tab" \
"$tool_opt may be set to one of the following:" \
"No suitable tool for 'git $cmd_name --tool=<tool>' found." \
"$extra_content" &&
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
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
}
guess_merge_tool () {
list_merge_tool_candidates
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
# Loop over each candidate and stop when a valid merge tool is found.
IFS=' '
for tool in $tools
do
is_available "$tool" && echo "$tool" && return 0
done
echo >&2 "No known ${TOOL_MODE} tool is available."
return 1
}
get_configured_merge_tool () {
keys=
if diff_mode
then
if gui_mode
then
keys="diff.guitool merge.guitool diff.tool merge.tool"
else
keys="diff.tool merge.tool"
fi
else
if gui_mode
then
keys="merge.guitool merge.tool"
else
keys="merge.tool"
fi
fi
merge_tool=$(
IFS=' '
for key in $keys
do
selected=$(git config $key)
if test -n "$selected"
then
echo "$selected"
return
fi
done)
if test -n "$merge_tool" && ! valid_tool "$merge_tool"
then
echo >&2 "git config option $TOOL_MODE.${gui_prefix}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.
merge_tool="$1"
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 () {
is_guessed=false
# Check if a merge tool has been configured
merge_tool=$(get_configured_merge_tool)
subshell_exit_status=$?
if test $subshell_exit_status -gt "1"
then
exit $subshell_exit_status
fi
# 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
is_guessed=true
fi
echo "$merge_tool"
test "$is_guessed" = false
}
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"
}
C
1
https://gitee.com/mirrors/git.git
git@gitee.com:mirrors/git.git
mirrors
git
Git
master

搜索帮助