Jonathan Nieder | 11d6214 | 2013-11-25 13:03:52 -0800 | [diff] [blame] | 1 | # git-mergetool--lib is a shell library for common merge tool functions |
David Aguilar | f35ec54 | 2013-01-27 16:52:26 -0800 | [diff] [blame] | 2 | |
| 3 | : ${MERGE_TOOLS_DIR=$(git --exec-path)/mergetools} |
David Aguilar | 073678b | 2013-01-26 16:46:12 -0800 | [diff] [blame] | 4 | |
David Aguilar | 719518f | 2015-05-20 02:07:22 -0700 | [diff] [blame] | 5 | IFS=' |
| 6 | ' |
| 7 | |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 8 | mode_ok () { |
| 9 | if diff_mode |
| 10 | then |
| 11 | can_diff |
| 12 | elif merge_mode |
| 13 | then |
| 14 | can_merge |
| 15 | else |
| 16 | false |
| 17 | fi |
| 18 | } |
| 19 | |
| 20 | is_available () { |
| 21 | merge_tool_path=$(translate_merge_tool_path "$1") && |
| 22 | type "$merge_tool_path" >/dev/null 2>&1 |
| 23 | } |
| 24 | |
John Keeping | 665682c | 2013-01-30 19:55:46 +0000 | [diff] [blame] | 25 | list_config_tools () { |
| 26 | section=$1 |
| 27 | line_prefix=${2:-} |
| 28 | |
| 29 | git config --get-regexp $section'\..*\.cmd' | |
| 30 | while read -r key value |
| 31 | do |
| 32 | toolname=${key#$section.} |
| 33 | toolname=${toolname%.cmd} |
| 34 | |
| 35 | printf "%s%s\n" "$line_prefix" "$toolname" |
| 36 | done |
| 37 | } |
| 38 | |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 39 | show_tool_names () { |
| 40 | condition=${1:-true} per_line_prefix=${2:-} preamble=${3:-} |
| 41 | not_found_msg=${4:-} |
John Keeping | 665682c | 2013-01-30 19:55:46 +0000 | [diff] [blame] | 42 | extra_content=${5:-} |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 43 | |
| 44 | shown_any= |
| 45 | ( cd "$MERGE_TOOLS_DIR" && ls ) | { |
| 46 | while read toolname |
| 47 | do |
| 48 | if setup_tool "$toolname" 2>/dev/null && |
| 49 | (eval "$condition" "$toolname") |
| 50 | then |
| 51 | if test -n "$preamble" |
| 52 | then |
| 53 | printf "%s\n" "$preamble" |
| 54 | preamble= |
| 55 | fi |
| 56 | shown_any=yes |
| 57 | printf "%s%s\n" "$per_line_prefix" "$toolname" |
| 58 | fi |
| 59 | done |
| 60 | |
John Keeping | 665682c | 2013-01-30 19:55:46 +0000 | [diff] [blame] | 61 | if test -n "$extra_content" |
| 62 | then |
| 63 | if test -n "$preamble" |
| 64 | then |
| 65 | # Note: no '\n' here since we don't want a |
| 66 | # blank line if there is no initial content. |
| 67 | printf "%s" "$preamble" |
| 68 | preamble= |
| 69 | fi |
| 70 | shown_any=yes |
| 71 | printf "\n%s\n" "$extra_content" |
| 72 | fi |
| 73 | |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 74 | if test -n "$preamble" && test -n "$not_found_msg" |
| 75 | then |
| 76 | printf "%s\n" "$not_found_msg" |
| 77 | fi |
| 78 | |
| 79 | test -n "$shown_any" |
| 80 | } |
| 81 | } |
| 82 | |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 83 | diff_mode() { |
| 84 | test "$TOOL_MODE" = diff |
| 85 | } |
| 86 | |
| 87 | merge_mode() { |
| 88 | test "$TOOL_MODE" = merge |
| 89 | } |
| 90 | |
| 91 | translate_merge_tool_path () { |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 92 | echo "$1" |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | check_unchanged () { |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 96 | if test "$MERGED" -nt "$BACKUP" |
| 97 | then |
David Aguilar | 1b6a534 | 2014-11-20 17:20:27 -0800 | [diff] [blame] | 98 | return 0 |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 99 | else |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 100 | while true |
| 101 | do |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 102 | echo "$MERGED seems unchanged." |
Nikola Forró | cce076e | 2016-04-12 16:44:20 +0200 | [diff] [blame] | 103 | printf "Was the merge successful [y/n]? " |
Jay Soffian | e622f41 | 2011-09-19 19:40:52 -0400 | [diff] [blame] | 104 | read answer || return 1 |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 105 | case "$answer" in |
David Aguilar | 1b6a534 | 2014-11-20 17:20:27 -0800 | [diff] [blame] | 106 | y*|Y*) return 0 ;; |
| 107 | n*|N*) return 1 ;; |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 108 | esac |
| 109 | done |
| 110 | fi |
| 111 | } |
| 112 | |
| 113 | valid_tool () { |
David Aguilar | 80ff2b6 | 2013-01-27 16:52:23 -0800 | [diff] [blame] | 114 | setup_tool "$1" && return 0 |
| 115 | cmd=$(get_merge_tool_cmd "$1") |
| 116 | test -n "$cmd" |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 117 | } |
| 118 | |
John Keeping | d2512fc | 2013-06-16 18:51:22 +0100 | [diff] [blame] | 119 | setup_user_tool () { |
| 120 | merge_tool_cmd=$(get_merge_tool_cmd "$tool") |
| 121 | test -n "$merge_tool_cmd" || return 1 |
| 122 | |
| 123 | diff_cmd () { |
| 124 | ( eval $merge_tool_cmd ) |
John Keeping | d2512fc | 2013-06-16 18:51:22 +0100 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | merge_cmd () { |
David Aguilar | 7c10605 | 2016-11-29 01:38:07 -0800 | [diff] [blame] | 128 | ( eval $merge_tool_cmd ) |
John Keeping | d2512fc | 2013-06-16 18:51:22 +0100 | [diff] [blame] | 129 | } |
| 130 | } |
| 131 | |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 132 | setup_tool () { |
David Aguilar | 073678b | 2013-01-26 16:46:12 -0800 | [diff] [blame] | 133 | tool="$1" |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 134 | |
Ondřej Bílka | 98e023d | 2013-07-29 10:18:21 +0200 | [diff] [blame] | 135 | # Fallback definitions, to be overridden by tools. |
David Aguilar | 073678b | 2013-01-26 16:46:12 -0800 | [diff] [blame] | 136 | can_merge () { |
| 137 | return 0 |
| 138 | } |
| 139 | |
| 140 | can_diff () { |
| 141 | return 0 |
| 142 | } |
| 143 | |
| 144 | diff_cmd () { |
David Aguilar | 1b6a534 | 2014-11-20 17:20:27 -0800 | [diff] [blame] | 145 | return 1 |
David Aguilar | 073678b | 2013-01-26 16:46:12 -0800 | [diff] [blame] | 146 | } |
| 147 | |
| 148 | merge_cmd () { |
David Aguilar | 1b6a534 | 2014-11-20 17:20:27 -0800 | [diff] [blame] | 149 | return 1 |
David Aguilar | 073678b | 2013-01-26 16:46:12 -0800 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | translate_merge_tool_path () { |
| 153 | echo "$1" |
| 154 | } |
| 155 | |
David Aguilar | 7c10605 | 2016-11-29 01:38:07 -0800 | [diff] [blame] | 156 | # Most tools' exit codes cannot be trusted, so By default we ignore |
| 157 | # their exit code and check the merged file's modification time in |
| 158 | # check_unchanged() to determine whether or not the merge was |
| 159 | # successful. The return value from run_merge_cmd, by default, is |
| 160 | # determined by check_unchanged(). |
| 161 | # |
| 162 | # When a tool's exit code can be trusted then the return value from |
| 163 | # run_merge_cmd is simply the tool's exit code, and check_unchanged() |
| 164 | # is not called. |
| 165 | # |
| 166 | # The return value of exit_code_trustable() tells us whether or not we |
| 167 | # can trust the tool's exit code. |
| 168 | # |
| 169 | # User-defined and built-in tools default to false. |
| 170 | # Built-in tools advertise that their exit code is trustable by |
| 171 | # redefining exit_code_trustable() to true. |
| 172 | |
| 173 | exit_code_trustable () { |
| 174 | false |
| 175 | } |
| 176 | |
| 177 | |
David Aguilar | 073678b | 2013-01-26 16:46:12 -0800 | [diff] [blame] | 178 | if ! test -f "$MERGE_TOOLS_DIR/$tool" |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 179 | then |
John Keeping | d2512fc | 2013-06-16 18:51:22 +0100 | [diff] [blame] | 180 | setup_user_tool |
| 181 | return $? |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 182 | fi |
| 183 | |
| 184 | # Load the redefined functions |
David Aguilar | 073678b | 2013-01-26 16:46:12 -0800 | [diff] [blame] | 185 | . "$MERGE_TOOLS_DIR/$tool" |
John Keeping | d2512fc | 2013-06-16 18:51:22 +0100 | [diff] [blame] | 186 | # Now let the user override the default command for the tool. If |
| 187 | # they have not done so then this will return 1 which we ignore. |
| 188 | setup_user_tool |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 189 | |
| 190 | if merge_mode && ! can_merge |
| 191 | then |
| 192 | echo "error: '$tool' can not be used to resolve merges" >&2 |
John Keeping | 62957be | 2013-01-26 16:40:06 -0800 | [diff] [blame] | 193 | return 1 |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 194 | elif diff_mode && ! can_diff |
| 195 | then |
| 196 | echo "error: '$tool' can only be used to resolve merges" >&2 |
John Keeping | 62957be | 2013-01-26 16:40:06 -0800 | [diff] [blame] | 197 | return 1 |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 198 | fi |
| 199 | return 0 |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 200 | } |
| 201 | |
| 202 | get_merge_tool_cmd () { |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 203 | merge_tool="$1" |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 204 | if diff_mode |
| 205 | then |
David Aguilar | 80ff2b6 | 2013-01-27 16:52:23 -0800 | [diff] [blame] | 206 | git config "difftool.$merge_tool.cmd" || |
| 207 | git config "mergetool.$merge_tool.cmd" |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 208 | else |
David Aguilar | 80ff2b6 | 2013-01-27 16:52:23 -0800 | [diff] [blame] | 209 | git config "mergetool.$merge_tool.cmd" |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 210 | fi |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 211 | } |
| 212 | |
David Aguilar | 7c10605 | 2016-11-29 01:38:07 -0800 | [diff] [blame] | 213 | trust_exit_code () { |
| 214 | if git config --bool "mergetool.$1.trustExitCode" |
| 215 | then |
| 216 | :; # OK |
| 217 | elif exit_code_trustable |
| 218 | then |
| 219 | echo true |
| 220 | else |
| 221 | echo false |
| 222 | fi |
| 223 | } |
| 224 | |
| 225 | |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 226 | # Entry point for running tools |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 227 | run_merge_tool () { |
David Aguilar | f9ad901 | 2011-05-25 23:21:01 -0700 | [diff] [blame] | 228 | # If GIT_PREFIX is empty then we cannot use it in tools |
| 229 | # that expect to be able to chdir() to its value. |
| 230 | GIT_PREFIX=${GIT_PREFIX:-.} |
| 231 | export GIT_PREFIX |
| 232 | |
David Aguilar | 80ff2b6 | 2013-01-27 16:52:23 -0800 | [diff] [blame] | 233 | merge_tool_path=$(get_merge_tool_path "$1") || exit |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 234 | base_present="$2" |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 235 | |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 236 | # Bring tool-specific functions into scope |
John Keeping | d2512fc | 2013-06-16 18:51:22 +0100 | [diff] [blame] | 237 | setup_tool "$1" || return 1 |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 238 | |
| 239 | if merge_mode |
| 240 | then |
David Aguilar | a427ef7 | 2012-09-25 00:48:11 -0700 | [diff] [blame] | 241 | run_merge_cmd "$1" |
| 242 | else |
| 243 | run_diff_cmd "$1" |
| 244 | fi |
David Aguilar | a427ef7 | 2012-09-25 00:48:11 -0700 | [diff] [blame] | 245 | } |
| 246 | |
| 247 | # Run a either a configured or built-in diff tool |
| 248 | run_diff_cmd () { |
John Keeping | d2512fc | 2013-06-16 18:51:22 +0100 | [diff] [blame] | 249 | diff_cmd "$1" |
David Aguilar | a427ef7 | 2012-09-25 00:48:11 -0700 | [diff] [blame] | 250 | } |
| 251 | |
| 252 | # Run a either a configured or built-in merge tool |
| 253 | run_merge_cmd () { |
David Aguilar | 7c10605 | 2016-11-29 01:38:07 -0800 | [diff] [blame] | 254 | mergetool_trust_exit_code=$(trust_exit_code "$1") |
| 255 | if test "$mergetool_trust_exit_code" = "true" |
| 256 | then |
| 257 | merge_cmd "$1" |
| 258 | else |
| 259 | touch "$BACKUP" |
| 260 | merge_cmd "$1" |
| 261 | check_unchanged |
| 262 | fi |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 263 | } |
| 264 | |
Junio C Hamano | 109859e | 2012-07-23 14:16:12 -0700 | [diff] [blame] | 265 | list_merge_tool_candidates () { |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 266 | if merge_mode |
| 267 | then |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 268 | tools="tortoisemerge" |
| 269 | else |
| 270 | tools="kompare" |
| 271 | fi |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 272 | if test -n "$DISPLAY" |
| 273 | then |
| 274 | if test -n "$GNOME_DESKTOP_SESSION_ID" |
| 275 | then |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 276 | tools="meld opendiff kdiff3 tkdiff xxdiff $tools" |
| 277 | else |
| 278 | tools="opendiff kdiff3 tkdiff xxdiff meld $tools" |
| 279 | fi |
Stefan Saasen | c5f424f | 2013-10-13 09:29:35 +1100 | [diff] [blame] | 280 | tools="$tools gvimdiff diffuse diffmerge ecmerge" |
Junio C Hamano | f13f9b0 | 2014-10-20 15:49:36 -0700 | [diff] [blame] | 281 | tools="$tools p4merge araxis bc codecompare" |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 282 | fi |
René Scharfe | 7b10422 | 2009-11-24 00:29:17 +0100 | [diff] [blame] | 283 | case "${VISUAL:-$EDITOR}" in |
| 284 | *vim*) |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 285 | tools="$tools vimdiff emerge" |
René Scharfe | 7b10422 | 2009-11-24 00:29:17 +0100 | [diff] [blame] | 286 | ;; |
| 287 | *) |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 288 | tools="$tools emerge vimdiff" |
René Scharfe | 7b10422 | 2009-11-24 00:29:17 +0100 | [diff] [blame] | 289 | ;; |
| 290 | esac |
Junio C Hamano | 109859e | 2012-07-23 14:16:12 -0700 | [diff] [blame] | 291 | } |
| 292 | |
John Keeping | 4a8273a | 2013-01-25 01:43:48 -0800 | [diff] [blame] | 293 | show_tool_help () { |
Stefan Saasen | 2b7ca91 | 2013-10-04 07:34:53 -0700 | [diff] [blame] | 294 | tool_opt="'git ${TOOL_MODE}tool --tool=<tool>'" |
David Aguilar | 88d3406 | 2013-01-25 01:43:54 -0800 | [diff] [blame] | 295 | |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 296 | tab=' ' |
| 297 | LF=' |
| 298 | ' |
| 299 | any_shown=no |
John Keeping | 62b6f7e | 2013-01-25 01:43:50 -0800 | [diff] [blame] | 300 | |
| 301 | cmd_name=${TOOL_MODE}tool |
John Keeping | 665682c | 2013-01-30 19:55:46 +0000 | [diff] [blame] | 302 | config_tools=$({ |
| 303 | diff_mode && list_config_tools difftool "$tab$tab" |
| 304 | list_config_tools mergetool "$tab$tab" |
| 305 | } | sort) |
| 306 | extra_content= |
| 307 | if test -n "$config_tools" |
| 308 | then |
| 309 | extra_content="${tab}user-defined:${LF}$config_tools" |
| 310 | fi |
| 311 | |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 312 | show_tool_names 'mode_ok && is_available' "$tab$tab" \ |
| 313 | "$tool_opt may be set to one of the following:" \ |
John Keeping | 665682c | 2013-01-30 19:55:46 +0000 | [diff] [blame] | 314 | "No suitable tool for 'git $cmd_name --tool=<tool>' found." \ |
| 315 | "$extra_content" && |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 316 | any_shown=yes |
| 317 | |
| 318 | show_tool_names 'mode_ok && ! is_available' "$tab$tab" \ |
| 319 | "${LF}The following tools are valid, but not currently available:" && |
| 320 | any_shown=yes |
| 321 | |
| 322 | if test "$any_shown" = yes |
John Keeping | 4a8273a | 2013-01-25 01:43:48 -0800 | [diff] [blame] | 323 | then |
| 324 | echo |
| 325 | echo "Some of the tools listed above only work in a windowed" |
| 326 | echo "environment. If run in a terminal-only session, they will fail." |
| 327 | fi |
| 328 | exit 0 |
| 329 | } |
| 330 | |
Junio C Hamano | 109859e | 2012-07-23 14:16:12 -0700 | [diff] [blame] | 331 | guess_merge_tool () { |
| 332 | list_merge_tool_candidates |
David Aguilar | 5338a6a | 2013-01-27 16:52:24 -0800 | [diff] [blame] | 333 | cat >&2 <<-EOF |
| 334 | |
| 335 | This message is displayed because '$TOOL_MODE.tool' is not configured. |
| 336 | See 'git ${TOOL_MODE}tool --tool-help' or 'git help config' for more details. |
| 337 | 'git ${TOOL_MODE}tool' will now attempt to use one of the following tools: |
| 338 | $tools |
| 339 | EOF |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 340 | |
| 341 | # Loop over each candidate and stop when a valid merge tool is found. |
Michael J Gruber | f67986b | 2015-06-19 11:30:55 +0200 | [diff] [blame] | 342 | IFS=' ' |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 343 | for tool in $tools |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 344 | do |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 345 | is_available "$tool" && echo "$tool" && return 0 |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 346 | done |
| 347 | |
David Aguilar | 17a1f1c | 2013-01-27 16:52:25 -0800 | [diff] [blame] | 348 | echo >&2 "No known ${TOOL_MODE} tool is available." |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 349 | return 1 |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 350 | } |
| 351 | |
| 352 | get_configured_merge_tool () { |
| 353 | # Diff mode first tries diff.tool and falls back to merge.tool. |
| 354 | # Merge mode only checks merge.tool |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 355 | if diff_mode |
| 356 | then |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 357 | merge_tool=$(git config diff.tool || git config merge.tool) |
| 358 | else |
| 359 | merge_tool=$(git config merge.tool) |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 360 | fi |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 361 | if test -n "$merge_tool" && ! valid_tool "$merge_tool" |
| 362 | then |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 363 | echo >&2 "git config option $TOOL_MODE.tool set to unknown tool: $merge_tool" |
| 364 | echo >&2 "Resetting to default..." |
| 365 | return 1 |
| 366 | fi |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 367 | echo "$merge_tool" |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 368 | } |
| 369 | |
| 370 | get_merge_tool_path () { |
| 371 | # A merge tool has been set, so verify that it's valid. |
David Aguilar | bc7a96a | 2011-08-18 00:23:46 -0700 | [diff] [blame] | 372 | merge_tool="$1" |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 373 | if ! valid_tool "$merge_tool" |
| 374 | then |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 375 | echo >&2 "Unknown merge tool $merge_tool" |
| 376 | exit 1 |
| 377 | fi |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 378 | if diff_mode |
| 379 | then |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 380 | merge_tool_path=$(git config difftool."$merge_tool".path || |
Jon Seymour | 285c6cb | 2011-08-05 23:31:29 +1000 | [diff] [blame] | 381 | git config mergetool."$merge_tool".path) |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 382 | else |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 383 | merge_tool_path=$(git config mergetool."$merge_tool".path) |
| 384 | fi |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 385 | if test -z "$merge_tool_path" |
| 386 | then |
David Aguilar | 80ff2b6 | 2013-01-27 16:52:23 -0800 | [diff] [blame] | 387 | merge_tool_path=$(translate_merge_tool_path "$merge_tool") |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 388 | fi |
| 389 | if test -z "$(get_merge_tool_cmd "$merge_tool")" && |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 390 | ! type "$merge_tool_path" >/dev/null 2>&1 |
| 391 | then |
David Aguilar | 47d6592 | 2009-04-11 20:41:56 -0700 | [diff] [blame] | 392 | echo >&2 "The $TOOL_MODE tool $merge_tool is not available as"\ |
Jon Seymour | 285c6cb | 2011-08-05 23:31:29 +1000 | [diff] [blame] | 393 | "'$merge_tool_path'" |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 394 | exit 1 |
| 395 | fi |
| 396 | echo "$merge_tool_path" |
| 397 | } |
| 398 | |
| 399 | get_merge_tool () { |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 400 | # Check if a merge tool has been configured |
David Aguilar | 80ff2b6 | 2013-01-27 16:52:23 -0800 | [diff] [blame] | 401 | merge_tool=$(get_configured_merge_tool) |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 402 | # Try to guess an appropriate merge tool if no tool has been set. |
David Aguilar | 240dc3e | 2011-08-18 00:23:45 -0700 | [diff] [blame] | 403 | if test -z "$merge_tool" |
| 404 | then |
David Aguilar | 80ff2b6 | 2013-01-27 16:52:23 -0800 | [diff] [blame] | 405 | merge_tool=$(guess_merge_tool) || exit |
David Aguilar | 21d0ba7 | 2009-04-08 00:17:20 -0700 | [diff] [blame] | 406 | fi |
| 407 | echo "$merge_tool" |
| 408 | } |
Jacob Nisnevich | e36d716 | 2016-03-25 16:17:56 -0700 | [diff] [blame] | 409 | |
| 410 | mergetool_find_win32_cmd () { |
| 411 | executable=$1 |
| 412 | sub_directory=$2 |
| 413 | |
| 414 | # Use $executable if it exists in $PATH |
| 415 | if type -p "$executable" >/dev/null 2>&1 |
| 416 | then |
| 417 | printf '%s' "$executable" |
| 418 | return |
| 419 | fi |
| 420 | |
| 421 | # Look for executable in the typical locations |
| 422 | for directory in $(env | grep -Ei '^PROGRAM(FILES(\(X86\))?|W6432)=' | |
| 423 | cut -d '=' -f 2- | sort -u) |
| 424 | do |
| 425 | if test -n "$directory" && test -x "$directory/$sub_directory/$executable" |
| 426 | then |
| 427 | printf '%s' "$directory/$sub_directory/$executable" |
| 428 | return |
| 429 | fi |
| 430 | done |
| 431 | |
| 432 | printf '%s' "$executable" |
| 433 | } |