mergetool: fallback to tool when guitool unavailable

In git-difftool, if the tool is called with --gui but `diff.guitool` is not set, it falls back to `diff.tool`. Make git-mergetool also fallback from `merge.guitool` to `merge.tool` if the former is undefined. If git-difftool, when called with `--gui`, were to use `get_configured_mergetool` in a future patch, it would also get the fallback behavior in the following precedence: 1. diff.guitool 2. merge.guitool 3. diff.tool 4. merge.tool The behavior for when difftool or mergetool are called without `--gui` should be identical with or without this patch. Note that the search loop could be written as sections="merge" keys="tool" if diff_mode then sections="diff $sections" fi if gui_mode then keys="guitool $keys" fi merge_tool=$( IFS=' ' for key in $keys do for section in $sections do selected=$(git config $section.$key) if test -n "$selected" then echo "$selected" return fi done done) which would make adding a mode in the future much easier. However, adding a new mode will likely never happen as it is highly discouraged so, as a result, it is written in its current form so that it is more readable for future readers. Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Denton Liu committed Apr 29, 2019 at 02:21 UTC 60aced3dfa68df60952fed28c4ae63a5bbda0275
3 files changed +48 -10
Documentation/git-mergetool.txt
+3 -1
@@ -83,7 +83,9 @@ success of the resolution after the custom tool has exited.
83 --gui::
84 When 'git-mergetool' is invoked with the `-g` or `--gui` option
85 the default merge tool will be read from the configured
86 - `merge.guitool` variable instead of `merge.tool`.
86 + `merge.guitool` variable instead of `merge.tool`. If
87 + `merge.guitool` is not set, we will fallback to the tool
88 + configured under `merge.tool`.
89
90 --no-gui::
91 This overrides a previous `-g` or `--gui` setting and reads the
git-mergetool--lib.sh
+26 -9
@@ -354,19 +354,36 @@ guess_merge_tool () {
354 }
355
356 get_configured_merge_tool () {
357 - if gui_mode
358 - then
359 - gui_prefix=gui
360 - fi
361 -
362 - # Diff mode first tries diff.(gui)tool and falls back to merge.(gui)tool.
363 - # Merge mode only checks merge.(gui)tool
357 + keys=
358 if diff_mode
359 then
366 - merge_tool=$(git config diff.${gui_prefix}tool || git config merge.${gui_prefix}tool)
360 + if gui_mode
361 + then
362 + keys="diff.guitool merge.guitool diff.tool merge.tool"
363 + else
364 + keys="diff.tool merge.tool"
365 + fi
366 else
368 - merge_tool=$(git config merge.${gui_prefix}tool)
367 + if gui_mode
368 + then
369 + keys="merge.guitool merge.tool"
370 + else
371 + keys="merge.tool"
372 + fi
373 fi
374 +
375 + merge_tool=$(
376 + IFS=' '
377 + for key in $keys
378 + do
379 + selected=$(git config $key)
380 + if test -n "$selected"
381 + then
382 + echo "$selected"
383 + return
384 + fi
385 + done)
386 +
387 if test -n "$merge_tool" && ! valid_tool "$merge_tool"
388 then
389 echo >&2 "git config option $TOOL_MODE.${gui_prefix}tool set to unknown tool: $merge_tool"
t/t7610-mergetool.sh
+19
@@ -167,6 +167,25 @@ test_expect_success 'gui mergetool' '
167 git commit -m "branch1 resolved with mergetool"
168 '
169
170 +test_expect_success 'gui mergetool without merge.guitool set falls back to merge.tool' '
171 + test_when_finished "git reset --hard" &&
172 + git checkout -b test$test_count branch1 &&
173 + git submodule update -N &&
174 + test_must_fail git merge master &&
175 + ( yes "" | git mergetool --gui both ) &&
176 + ( yes "" | git mergetool -g file1 file1 ) &&
177 + ( yes "" | git mergetool --gui file2 "spaced name" ) &&
178 + ( yes "" | git mergetool --gui subdir/file3 ) &&
179 + ( yes "d" | git mergetool --gui file11 ) &&
180 + ( yes "d" | git mergetool --gui file12 ) &&
181 + ( yes "l" | git mergetool --gui submod ) &&
182 + test "$(cat file1)" = "master updated" &&
183 + test "$(cat file2)" = "master new" &&
184 + test "$(cat subdir/file3)" = "master new sub" &&
185 + test "$(cat submod/bar)" = "branch1 submodule" &&
186 + git commit -m "branch1 resolved with mergetool"
187 +'
188 +
189 test_expect_success 'mergetool crlf' '
190 test_when_finished "git reset --hard" &&
191 # This test_config line must go after the above reset line so that