From a427ef7acc9d932d1c203dd2fae67f51c4b1d1e8 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Tue, 25 Sep 2012 00:48:11 -0700 Subject: [PATCH] mergetool--lib: Allow custom commands to override built-ins Allow users to override the default commands provided by the mergetools/* scriptlets. Users occasionally run into problems where they expect to be able to override the built-in tool names. The documentation does not explicitly mention that built-ins cannot be overridden, so it's easy to assume that it should work. Lift this restriction so that built-in tools are handled the same way as user-configured tools. Add tests to guarantee this behavior. A nice benefit of this change is that it protects users from having future versions of git trump their custom configuration with a new built-in tool. C.f.: http://stackoverflow.com/questions/7435002/mergetool-from-gitconfig-being-ignored http://thread.gmane.org/gmane.comp.version-control.msysgit/13188 http://thread.gmane.org/gmane.comp.version-control.git/148267 Signed-off-by: David Aguilar Signed-off-by: Junio C Hamano --- git-mergetool--lib.sh | 40 ++++++++++++++++++++++++++++-- mergetools/defaults | 68 +++++++++++++++++---------------------------------- t/t7610-mergetool.sh | 13 ++++++++++ t/t7800-difftool.sh | 11 +++++++++ 4 files changed, 84 insertions(+), 48 deletions(-) rewrite mergetools/defaults (71%) diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh index f730253c0e..6988f9c0c0 100644 --- a/git-mergetool--lib.sh +++ b/git-mergetool--lib.sh @@ -104,13 +104,49 @@ run_merge_tool () { if merge_mode then - merge_cmd "$1" + run_merge_cmd "$1" else - diff_cmd "$1" + run_diff_cmd "$1" fi return $status } +# Run a either a configured or built-in diff tool +run_diff_cmd () { + merge_tool_cmd="$(get_merge_tool_cmd "$1")" + if test -n "$merge_tool_cmd" + then + ( eval $merge_tool_cmd ) + status=$? + return $status + else + diff_cmd "$1" + fi +} + +# Run a either a configured or built-in merge tool +run_merge_cmd () { + merge_tool_cmd="$(get_merge_tool_cmd "$1")" + if test -n "$merge_tool_cmd" + then + trust_exit_code="$(git config --bool \ + mergetool."$1".trustExitCode || echo false)" + if test "$trust_exit_code" = "false" + then + touch "$BACKUP" + ( eval $merge_tool_cmd ) + status=$? + check_unchanged + else + ( eval $merge_tool_cmd ) + status=$? + fi + return $status + else + merge_cmd "$1" + fi +} + list_merge_tool_candidates () { if merge_mode then diff --git a/mergetools/defaults b/mergetools/defaults dissimilarity index 71% index 1d8f2a3dd3..21e63ecc3e 100644 --- a/mergetools/defaults +++ b/mergetools/defaults @@ -1,46 +1,22 @@ -# Redefined by builtin tools -can_merge () { - return 0 -} - -can_diff () { - return 0 -} - -diff_cmd () { - merge_tool_cmd="$(get_merge_tool_cmd "$1")" - if test -z "$merge_tool_cmd" - then - status=1 - break - fi - ( eval $merge_tool_cmd ) - status=$? - return $status -} - -merge_cmd () { - merge_tool_cmd="$(get_merge_tool_cmd "$1")" - if test -z "$merge_tool_cmd" - then - status=1 - break - fi - trust_exit_code="$(git config --bool \ - mergetool."$1".trustExitCode || echo false)" - if test "$trust_exit_code" = "false" - then - touch "$BACKUP" - ( eval $merge_tool_cmd ) - status=$? - check_unchanged - else - ( eval $merge_tool_cmd ) - status=$? - fi - return $status -} - -translate_merge_tool_path () { - echo "$1" -} +# Redefined by builtin tools +can_merge () { + return 0 +} + +can_diff () { + return 0 +} + +diff_cmd () { + status=1 + return $status +} + +merge_cmd () { + status=1 + return $status +} + +translate_merge_tool_path () { + echo "$1" +} diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index f5e16fc7db..0348ed2fb7 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -471,4 +471,17 @@ test_expect_success 'file with no base' ' git reset --hard master >/dev/null 2>&1 ' +test_expect_success 'custom commands override built-ins' ' + git checkout -b test14 branch1 && + git config mergetool.defaults.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" && + git config mergetool.defaults.trustExitCode true && + test_must_fail git merge master && + git mergetool --no-prompt --tool defaults -- both && + echo master both added >expected && + test_cmp both expected && + git config --unset mergetool.defaults.cmd && + git config --unset mergetool.defaults.trustExitCode && + git reset --hard master >/dev/null 2>&1 +' + test_done diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 9c3e997b9d..eb1d3f85b5 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -76,6 +76,17 @@ test_expect_success PERL 'custom commands' ' test "$diff" = "branch" ' +# Ensures that a custom difftool..cmd overrides built-ins +test_expect_success PERL 'custom commands override built-ins' ' + restore_test_defaults && + git config difftool.defaults.cmd "cat \$REMOTE" && + + diff=$(git difftool --tool defaults --no-prompt branch) && + test "$diff" = "master" && + + git config --unset difftool.defaults.cmd +' + # Ensures that git-difftool ignores bogus --tool values test_expect_success PERL 'difftool ignores bad --tool values' ' diff=$(git difftool --no-prompt --tool=bad-tool branch) -- 2.11.4.GIT