@matheusbsbs / matheus-bagliano / commits / 964473a042
Fork 0

Teach git mergetool to use custom commands defined at config time

Currently git mergetool is restricted to a set of commands defined in the script. You can subvert the mergetool.<tool>.path to force git mergetool to use a different command, but if you have a command whose invocation syntax does not match one of the current tools then you would have to write a wrapper script for it. This patch adds two git config variable patterns which allow a more flexible choice of merge tool. If you run git mergetool with -t/--tool or the merge.tool config variable set to an unrecognized tool then git mergetool will query the mergetool.<tool>.cmd config variable. If this variable exists, then git mergetool will treat the specified tool as a custom command and will use a shell eval to run the command with the documented shell variables set. mergetool.<tool>.trustExitCode can be used to indicate that the exit code of the custom command can be used to determine the success of the merge. Signed-off-by: Charles Bailey <charles@hashpling.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Charles Bailey committed Feb 21, 2008 at 23:31 UTC 964473a0429f625d019c69ab55644540174acf85
2 files changed +49 -4
Documentation/config.txt
+23 -2
@@ -749,8 +749,10 @@ merge.summary::
749
750 merge.tool::
751 Controls which merge resolution program is used by
752 - linkgit:git-mergetool[1]. Valid values are: "kdiff3", "tkdiff",
753 - "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff", and "opendiff".
752 + linkgit:git-mergetool[1]. Valid built-in values are: "kdiff3",
753 + "tkdiff", "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff", and
754 + "opendiff". Any other value is treated is custom merge tool
755 + and there must be a corresponing mergetool.<tool>.cmd option.
756
757 merge.verbosity::
758 Controls the amount of output shown by the recursive merge
@@ -777,6 +779,25 @@ mergetool.<tool>.path::
779 Override the path for the given tool. This is useful in case
780 your tool is not in the PATH.
781
782 +mergetool.<tool>.cmd::
783 + Specify the command to invoke the specified merge tool. The
784 + specified command is evaluated in shell with the following
785 + variables available: 'BASE' is the name of a temporary file
786 + containing the common base of the files to be merged, if available;
787 + 'LOCAL' is the name of a temporary file containing the contents of
788 + the file on the current branch; 'REMOTE' is the name of a temporary
789 + file containing the contents of the file from the branch being
790 + merged; 'MERGED' contains the name of the file to which the merge
791 + tool should write the results of a successful merge.
792 +
793 +mergetool.<tool>.trustExitCode::
794 + For a custom merge command, specify whether the exit code of
795 + the merge command can be used to determine whether the merge was
796 + successful. If this is not set to true then the merge target file
797 + timestamp is checked and the merge assumed to have been successful
798 + if the file has been updated, otherwise the user is prompted to
799 + indicate the success of the merge.
800 +
801 mergetool.keepBackup::
802 After performing a merge, the original file with conflict markers
803 can be saved as a file with a `.orig` extension. If this variable
git-mergetool.sh
+26 -2
@@ -251,6 +251,18 @@ merge_file () {
251 fi
252 status=$?
253 ;;
254 + *)
255 + if test -n "$merge_tool_cmd"; then
256 + if test "$merge_tool_trust_exit_code" = "false"; then
257 + touch "$BACKUP"
258 + ( eval $merge_tool_cmd )
259 + check_unchanged
260 + else
261 + ( eval $merge_tool_cmd )
262 + status=$?
263 + fi
264 + fi
265 + ;;
266 esac
267 if test "$status" -ne 0; then
268 echo "merge of $MERGED failed" 1>&2
@@ -296,12 +308,20 @@ do
308 shift
309 done
310
311 +valid_custom_tool()
312 +{
313 + merge_tool_cmd="$(git config mergetool.$1.cmd)"
314 + test -n "$merge_tool_cmd"
315 +}
316 +
317 valid_tool() {
318 case "$1" in
319 kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)
320 ;; # happy
321 *)
304 - return 1
322 + if ! valid_custom_tool "$1"; then
323 + return 1
324 + fi
325 ;;
326 esac
327 }
@@ -369,10 +389,14 @@ else
389
390 merge_keep_backup="$(git config --bool merge.keepBackup || echo true)"
391
372 - if ! type "$merge_tool_path" > /dev/null 2>&1; then
392 + if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
393 echo "The merge tool $merge_tool is not available as '$merge_tool_path'"
394 exit 1
395 fi
396 +
397 + if ! test -z "$merge_tool_cmd"; then
398 + merge_tool_trust_exit_code="$(git config --bool mergetool.$merge_tool.trustExitCode || echo false)"
399 + fi
400 fi
401
402