#!/bin/sh # git-mergetool--lib is a library for common merge tool functions diff_mode() { test "$TOOL_MODE" = diff } merge_mode() { test "$TOOL_MODE" = merge } translate_merge_tool_path () { echo "$1" } check_unchanged () { if test "$MERGED" -nt "$BACKUP" then status=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*) status=0; break ;; n*|N*) status=1; break ;; esac done fi } valid_tool_config () { if test -n "$(get_merge_tool_cmd "$1")" then return 0 else return 1 fi } valid_tool () { setup_tool "$1" || valid_tool_config "$1" } setup_tool () { case "$1" in vim*|gvim*) tool=vim ;; *) tool="$1" ;; esac mergetools="$(git --exec-path)/mergetools" # Load the default definitions . "$mergetools/defaults" if ! test -f "$mergetools/$tool" then return 1 fi # Load the redefined functions . "$mergetools/$tool" if merge_mode && ! can_merge then echo "error: '$tool' can not be used to resolve merges" >&2 exit 1 elif diff_mode && ! can_diff then echo "error: '$tool' can only be used to resolve merges" >&2 exit 1 fi return 0 } get_merge_tool_cmd () { # Prints the custom command for a merge tool merge_tool="$1" 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 } # 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" status=0 # Bring tool-specific functions into scope setup_tool "$1" if merge_mode then merge_cmd "$1" else diff_cmd "$1" fi return $status } 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 ecmerge p4merge araxis bc3" fi case "${VISUAL:-$EDITOR}" in *vim*) tools="$tools vimdiff emerge" ;; *) tools="$tools emerge vimdiff" ;; esac } guess_merge_tool () { list_merge_tool_candidates echo >&2 "merge tool candidates: $tools" # Loop over each candidate and stop when a valid merge tool is found. for i in $tools do merge_tool_path="$(translate_merge_tool_path "$i")" if type "$merge_tool_path" >/dev/null 2>&1 then echo "$i" return 0 fi done echo >&2 "No known merge resolution program available." return 1 } get_configured_merge_tool () { # Diff mode first tries diff.tool and falls back to merge.tool. # Merge mode only checks merge.tool if diff_mode then merge_tool=$(git config diff.tool || git config merge.tool) else merge_tool=$(git config merge.tool) fi 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 "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 () { # Check if a merge tool has been configured merge_tool="$(get_configured_merge_tool)" # 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 fi echo "$merge_tool" }