{"thread":{"id":"18771","subject":"[PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","startedAt":"2009-04-07T23:00:13Z","lastAt":"2009-04-08T06:56:55Z","messageCount":6,"participants":["David Aguilar","Markus Heidelberg","Junio C Hamano","Charles Bailey"],"isPatch":true,"patchVersion":4,"patchTotal":14},"messages":[{"id":"110755","messageId":"1239145213-76701-1-git-send-email-davvid@gmail.com","threadId":"18771","inReplyTo":null,"subject":"[PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T23:00:13Z","receivedAt":"2009-04-07T23:00:13Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"This consolidates the common functionality from git-mergetool and\ngit-difftool--helper into a single git-mergetool--lib scriptlet.\n\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\n\nIncludes latest suggestions from Markus:\n\n* Modify check_unchanged so that it doesn't check merge_mode\n\n* Modify the way $tools is setup so that we fixup duplicated\nspaces later\n\n* Fix the status capturing for the custom tool in run_merge_tool\n\n .gitignore                           |    1 +\n Documentation/git-mergetool--lib.txt |   56 +++++\n Makefile                             |    1 +\n git-difftool--helper.sh              |  186 +----------------\n git-mergetool--lib.sh                |  381 ++++++++++++++++++++++++++++++++++\n git-mergetool.sh                     |  224 ++-------------------\n 6 files changed, 461 insertions(+), 388 deletions(-)\n create mode 100644 Documentation/git-mergetool--lib.txt\n create mode 100644 git-mergetool--lib.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex a36da9d..757c7f0 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -80,6 +80,7 @@ git-merge-recursive\n git-merge-resolve\n git-merge-subtree\n git-mergetool\n+git-mergetool--lib\n git-mktag\n git-mktree\n git-name-rev\ndiff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt\nnew file mode 100644\nindex 0000000..3d57031\n--- /dev/null\n+++ b/Documentation/git-mergetool--lib.txt\n@@ -0,0 +1,56 @@\n+git-mergetool--lib(1)\n+=====================\n+\n+NAME\n+----\n+git-mergetool--lib - Common git merge tool shell scriptlets\n+\n+SYNOPSIS\n+--------\n+'. \"$(git --exec-path)/git-mergetool--lib\"'\n+\n+DESCRIPTION\n+-----------\n+\n+This is not a command the end user would want to run.  Ever.\n+This documentation is meant for people who are studying the\n+Porcelain-ish scripts and/or are writing new ones.\n+\n+The 'git-mergetool--lib' scriptlet is designed to be sourced (using\n+`.`) by other shell scripts to set up functions for working\n+with git merge tools.\n+\n+Before sourcing it, your script should set up a few variables;\n+`TOOL_MODE` is used to define the operation mode for various\n+functions.  'diff' and 'merge' are valid values.\n+\n+FUNCTIONS\n+---------\n+get_merge_tool::\n+\treturns a merge tool\n+\n+get_merge_tool_cmd::\n+\treturns the custom command for a merge tool.\n+\n+get_merge_tool_path::\n+\treturns the custom path for a merge tool.\n+\n+run_merge_tool::\n+\tlaunches a merge tool given the tool name and a true/false\n+\tflag to indicate whether a merge base is present.\n+\t'$merge_tool', '$merge_tool_path', and for custom commands,\n+\t'$merge_tool_cmd', must be defined prior to calling\n+\trun_merge_tool.  Additionally, '$MERGED', '$LOCAL', '$REMOTE',\n+\tand '$BASE' must be defined for use by the merge tool.\n+\n+Author\n+------\n+Written by David Aguilar <davvid@gmail.com>\n+\n+Documentation\n+--------------\n+Documentation by David Aguilar and the git-list <git@vger.kernel.org>.\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex a80055f..3e56274 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -284,6 +284,7 @@ SCRIPT_SH += git-merge-octopus.sh\n SCRIPT_SH += git-merge-one-file.sh\n SCRIPT_SH += git-merge-resolve.sh\n SCRIPT_SH += git-mergetool.sh\n+SCRIPT_SH += git-mergetool--lib.sh\n SCRIPT_SH += git-parse-remote.sh\n SCRIPT_SH += git-pull.sh\n SCRIPT_SH += git-quiltimport.sh\ndiff --git a/git-difftool--helper.sh b/git-difftool--helper.sh\nindex f3c27d8..b450036 100755\n--- a/git-difftool--helper.sh\n+++ b/git-difftool--helper.sh\n@@ -5,6 +5,10 @@\n #\n # Copyright (c) 2009 David Aguilar\n \n+# Load common functions from git-mergetool--lib\n+TOOL_MODE=diff\n+. git-mergetool--lib\n+\n # difftool.prompt controls the default prompt/no-prompt behavior\n # and is overridden with $GIT_DIFFTOOL*_PROMPT.\n should_prompt () {\n@@ -16,8 +20,7 @@ should_prompt () {\n \tfi\n }\n \n-# This function prepares temporary files and launches the appropriate\n-# merge tool.\n+# Sets up shell variables and runs a merge tool\n launch_merge_tool () {\n \t# Merged is the filename as it appears in the work tree\n \t# Local is the contents of a/filename\n@@ -37,187 +40,16 @@ launch_merge_tool () {\n \tfi\n \n \t# Run the appropriate merge tool command\n-\tcase \"$merge_tool\" in\n-\tkdiff3)\n-\t\tbasename=$(basename \"$MERGED\")\n-\t\t\"$merge_tool_path\" --auto \\\n-\t\t\t--L1 \"$basename (A)\" \\\n-\t\t\t--L2 \"$basename (B)\" \\\n-\t\t\t\"$LOCAL\" \"$REMOTE\" \\\n-\t\t\t> /dev/null 2>&1\n-\t\t;;\n-\n-\tkompare)\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n-\t\t;;\n-\n-\ttkdiff)\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n-\t\t;;\n-\n-\tmeld)\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n-\t\t;;\n-\n-\tdiffuse)\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" | cat\n-\t\t;;\n-\n-\tvimdiff)\n-\t\t\"$merge_tool_path\" -d -c \"wincmd l\" \"$LOCAL\" \"$REMOTE\"\n-\t\t;;\n-\n-\tgvimdiff)\n-\t\t\"$merge_tool_path\" -d -c \"wincmd l\" -f \"$LOCAL\" \"$REMOTE\"\n-\t\t;;\n-\n-\txxdiff)\n-\t\t\"$merge_tool_path\" \\\n-\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n-\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n-\t\t\t\"$LOCAL\" \"$REMOTE\"\n-\t\t;;\n-\n-\topendiff)\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" | cat\n-\t\t;;\n-\n-\tecmerge)\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n-\t\t\t--default --mode=merge2 --to=\"$MERGED\"\n-\t\t;;\n-\n-\temerge)\n-\t\t\"$merge_tool_path\" -f emerge-files-command \\\n-\t\t\t\"$LOCAL\" \"$REMOTE\" \"$(basename \"$MERGED\")\"\n-\t\t;;\n-\n-\t*)\n-\t\tif test -n \"$merge_tool_cmd\"; then\n-\t\t\t( eval $merge_tool_cmd )\n-\t\tfi\n-\t\t;;\n-\tesac\n-}\n-\n-# Verifies that (difftool|mergetool).<tool>.cmd exists\n-valid_custom_tool() {\n-\tmerge_tool_cmd=\"$(git config difftool.$1.cmd)\"\n-\ttest -z \"$merge_tool_cmd\" &&\n-\tmerge_tool_cmd=\"$(git config mergetool.$1.cmd)\"\n-\ttest -n \"$merge_tool_cmd\"\n-}\n-\n-# Verifies that the chosen merge tool is properly setup.\n-# Built-in merge tools are always valid.\n-valid_tool() {\n-\tcase \"$1\" in\n-\tkdiff3 | kompare | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)\n-\t\t;; # happy\n-\t*)\n-\t\tif ! valid_custom_tool \"$1\"\n-\t\tthen\n-\t\t\treturn 1\n-\t\tfi\n-\t\t;;\n-\tesac\n-}\n-\n-# Sets up the merge_tool_path variable.\n-# This handles the difftool.<tool>.path configuration.\n-# This also falls back to mergetool defaults.\n-init_merge_tool_path() {\n-\tmerge_tool_path=$(git config difftool.\"$1\".path)\n-\ttest -z \"$merge_tool_path\" &&\n-\tmerge_tool_path=$(git config mergetool.\"$1\".path)\n-\tif test -z \"$merge_tool_path\"; then\n-\t\tcase \"$1\" in\n-\t\tvimdiff)\n-\t\t\tmerge_tool_path=vim\n-\t\t\t;;\n-\t\tgvimdiff)\n-\t\t\tmerge_tool_path=gvim\n-\t\t\t;;\n-\t\temerge)\n-\t\t\tmerge_tool_path=emacs\n-\t\t\t;;\n-\t\t*)\n-\t\t\tmerge_tool_path=\"$1\"\n-\t\t\t;;\n-\t\tesac\n-\tfi\n+\trun_merge_tool \"$merge_tool\"\n }\n \n # Allow GIT_DIFF_TOOL and GIT_MERGE_TOOL to provide default values\n test -n \"$GIT_MERGE_TOOL\" && merge_tool=\"$GIT_MERGE_TOOL\"\n test -n \"$GIT_DIFF_TOOL\" && merge_tool=\"$GIT_DIFF_TOOL\"\n \n-# If merge tool was not specified then use the diff.tool\n-# configuration variable.  If that's invalid then reset merge_tool.\n-# Fallback to merge.tool.\n-if test -z \"$merge_tool\"; then\n-\tmerge_tool=$(git config diff.tool)\n-\ttest -z \"$merge_tool\" &&\n-\tmerge_tool=$(git config merge.tool)\n-\tif test -n \"$merge_tool\" && ! valid_tool \"$merge_tool\"; then\n-\t\techo >&2 \"git config option diff.tool set to unknown tool: $merge_tool\"\n-\t\techo >&2 \"Resetting to default...\"\n-\t\tunset merge_tool\n-\tfi\n-fi\n-\n-# Try to guess an appropriate merge tool if no tool has been set.\n-if test -z \"$merge_tool\"; then\n-\t# We have a $DISPLAY so try some common UNIX merge tools\n-\tif test -n \"$DISPLAY\"; then\n-\t\t# If gnome then prefer meld, otherwise, prefer kdiff3 or kompare\n-\t\tif test -n \"$GNOME_DESKTOP_SESSION_ID\" ; then\n-\t\t\tmerge_tool_candidates=\"meld kdiff3 kompare tkdiff xxdiff gvimdiff diffuse\"\n-\t\telse\n-\t\t\tmerge_tool_candidates=\"kdiff3 kompare tkdiff xxdiff meld gvimdiff diffuse\"\n-\t\tfi\n-\tfi\n-\tif echo \"${VISUAL:-$EDITOR}\" | grep 'emacs' > /dev/null 2>&1; then\n-\t\t# $EDITOR is emacs so add emerge as a candidate\n-\t\tmerge_tool_candidates=\"$merge_tool_candidates emerge opendiff vimdiff\"\n-\telif echo \"${VISUAL:-$EDITOR}\" | grep 'vim' > /dev/null 2>&1; then\n-\t\t# $EDITOR is vim so add vimdiff as a candidate\n-\t\tmerge_tool_candidates=\"$merge_tool_candidates vimdiff opendiff emerge\"\n-\telse\n-\t\tmerge_tool_candidates=\"$merge_tool_candidates opendiff emerge vimdiff\"\n-\tfi\n-\techo \"merge tool candidates: $merge_tool_candidates\"\n-\n-\t# Loop over each candidate and stop when a valid merge tool is found.\n-\tfor i in $merge_tool_candidates\n-\tdo\n-\t\tinit_merge_tool_path $i\n-\t\tif type \"$merge_tool_path\" > /dev/null 2>&1; then\n-\t\t\tmerge_tool=$i\n-\t\t\tbreak\n-\t\tfi\n-\tdone\n-\n-\tif test -z \"$merge_tool\" ; then\n-\t\techo \"No known merge resolution program available.\"\n-\t\texit 1\n-\tfi\n-\n-else\n-\t# A merge tool has been set, so verify that it's valid.\n-\tif ! valid_tool \"$merge_tool\"; then\n-\t\techo >&2 \"Unknown merge tool $merge_tool\"\n-\t\texit 1\n-\tfi\n-\n-\tinit_merge_tool_path \"$merge_tool\"\n-\n-\tif test -z \"$merge_tool_cmd\" && ! type \"$merge_tool_path\" > /dev/null 2>&1; then\n-\t\techo \"The merge tool $merge_tool is not available as '$merge_tool_path'\"\n-\t\texit 1\n-\tfi\n-fi\n-\n+merge_tool=$(get_merge_tool \"$merge_tool\") || exit\n+merge_tool_cmd=\"$(get_merge_tool_cmd \"$merge_tool\")\"\n+merge_tool_path=\"$(get_merge_tool_path \"$merge_tool\")\" || exit\n \n # Launch the merge tool on each path provided by 'git diff'\n while test $# -gt 6\ndiff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh\nnew file mode 100644\nindex 0000000..95cc355\n--- /dev/null\n+++ b/git-mergetool--lib.sh\n@@ -0,0 +1,381 @@\n+# git-mergetool--lib is a library for common merge tool functions\n+diff_mode() {\n+\ttest \"$TOOL_MODE\" = diff\n+}\n+\n+merge_mode() {\n+\ttest \"$TOOL_MODE\" = merge\n+}\n+\n+translate_merge_tool_path () {\n+\tif test -n \"$2\"; then\n+\t\techo \"$2\"\n+\telse\n+\t\tcase \"$1\" in\n+\t\tvimdiff)\n+\t\t\tpath=vim\n+\t\t\t;;\n+\t\tgvimdiff)\n+\t\t\tpath=gvim\n+\t\t\t;;\n+\t\temerge)\n+\t\t\tpath=emacs\n+\t\t\t;;\n+\t\t*)\n+\t\t\tpath=\"$1\"\n+\t\t\t;;\n+\t\tesac\n+\t\techo \"$path\"\n+\tfi\n+}\n+\n+check_unchanged () {\n+\tif test \"$MERGED\" -nt \"$BACKUP\"; then\n+\t\tstatus=0\n+\telse\n+\t\twhile true; do\n+\t\t\techo \"$MERGED seems unchanged.\"\n+\t\t\tprintf \"Was the merge successful? [y/n] \"\n+\t\t\tread answer < /dev/tty\n+\t\t\tcase \"$answer\" in\n+\t\t\ty*|Y*) status=0; break ;;\n+\t\t\tn*|N*) status=1; break ;;\n+\t\t\tesac\n+\t\tdone\n+\tfi\n+}\n+\n+valid_tool () {\n+\tcase \"$1\" in\n+\tkdiff3 | tkdiff | xxdiff | meld | opendiff | \\\n+\temerge | vimdiff | gvimdiff | ecmerge | diffuse)\n+\t\t;; # happy\n+\ttortoisemerge)\n+\t\tif ! merge_mode; then\n+\t\t\treturn 1\n+\t\tfi\n+\t\t;;\n+\tkompare)\n+\t\tif ! diff_mode; then\n+\t\t\treturn 1\n+\t\tfi\n+\t\t;;\n+\t*)\n+\t\tif test -z \"$(get_merge_tool_cmd \"$1\")\"; then\n+\t\t\treturn 1\n+\t\tfi\n+\t\t;;\n+\tesac\n+}\n+\n+get_merge_tool_cmd () {\n+\tdiff_mode &&\n+\tcustom_cmd=\"$(git config difftool.$1.cmd)\"\n+\ttest -z \"$custom_cmd\" &&\n+\tcustom_cmd=\"$(git config mergetool.$1.cmd)\"\n+\ttest -n \"$custom_cmd\" &&\n+\techo \"$custom_cmd\"\n+}\n+\n+run_merge_tool () {\n+\tbase_present=\"$2\"\n+\tstatus=0\n+\n+\tcase \"$1\" in\n+\tkdiff3)\n+\t\tif merge_mode; then\n+\t\t\tif $base_present; then\n+\t\t\t\t(\"$merge_tool_path\" --auto \\\n+\t\t\t\t\t--L1 \"$MERGED (Base)\" \\\n+\t\t\t\t\t--L2 \"$MERGED (Local)\" \\\n+\t\t\t\t\t--L3 \"$MERGED (Remote)\" \\\n+\t\t\t\t\t-o \"$MERGED\" \\\n+\t\t\t\t\t\"$BASE\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t> /dev/null 2>&1)\n+\t\t\telse\n+\t\t\t\t(\"$merge_tool_path\" --auto \\\n+\t\t\t\t\t--L1 \"$MERGED (Local)\" \\\n+\t\t\t\t\t--L2 \"$MERGED (Remote)\" \\\n+\t\t\t\t\t-o \"$MERGED\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t> /dev/null 2>&1)\n+\t\t\tfi\n+\t\t\tstatus=$?\n+\t\telse\n+\t\t\t(\"$merge_tool_path\" --auto \\\n+\t\t\t --L1 \"$MERGED (A)\" \\\n+\t\t\t --L2 \"$MERGED (B)\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t > /dev/null 2>&1)\n+\t\tfi\n+\t\t;;\n+\tkompare)\n+\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n+\t\t;;\n+\ttkdiff)\n+\t\tif merge_mode; then\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" -a \"$BASE\" \\\n+\t\t\t\t\t-o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n+\t\t\telse\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t-o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n+\t\t\tfi\n+\t\t\tstatus=$?\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n+\t\tfi\n+\t\t;;\n+\tmeld)\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n+\t\tfi\n+\t\t;;\n+\tdiffuse)\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$MERGED\" \"$REMOTE\" \\\n+\t\t\t\t\t\"$BASE\" | cat\n+\t\t\telse\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$MERGED\" \"$REMOTE\" | cat\n+\t\t\tfi\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" | cat\n+\t\tfi\n+\t\t;;\n+\tvimdiff)\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" \\\n+\t\t\t\t\"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n+\t\tfi\n+\t\t;;\n+\tgvimdiff)\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" -f \\\n+\t\t\t\t\"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" -f \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n+\t\tfi\n+\t\t;;\n+\txxdiff)\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" -X --show-merged-pane \\\n+\t\t\t\t\t-R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n+\t\t\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n+\t\t\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n+\t\t\t\t\t--merged-file \"$MERGED\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$BASE\" \"$REMOTE\"\n+\t\t\telse\n+\t\t\t\t\"$merge_tool_path\" -X $extra \\\n+\t\t\t\t\t-R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n+\t\t\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n+\t\t\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n+\t\t\t\t\t--merged-file \"$MERGED\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n+\t\t\tfi\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n+\t\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n+\t\tfi\n+\t\t;;\n+\topendiff)\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t-ancestor \"$BASE\" \\\n+\t\t\t\t\t-merge \"$MERGED\" | cat\n+\t\t\telse\n+\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t-merge \"$MERGED\" | cat\n+\t\t\tfi\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" | cat\n+\t\tfi\n+\t\t;;\n+\tecmerge)\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t--default --mode=merge3 --to=\"$MERGED\"\n+\t\t\telse\n+\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t--default --mode=merge2 --to=\"$MERGED\"\n+\t\t\tfi\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t--default --mode=merge2 --to=\"$MERGED\"\n+\t\tfi\n+\t\t;;\n+\temerge)\n+\t\tif merge_mode; then\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t-f emerge-files-with-ancestor-command \\\n+\t\t\t\t\t\"$LOCAL\" \"$REMOTE\" \"$BASE\" \\\n+\t\t\t\t\t\"$(basename \"$MERGED\")\"\n+\t\t\telse\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t-f emerge-files-command \\\n+\t\t\t\t\t\"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t\"$(basename \"$MERGED\")\"\n+\t\t\tfi\n+\t\t\tstatus=$?\n+\t\telse\n+\t\t\t\"$merge_tool_path\" -f emerge-files-command \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\" \"$(basename \"$MERGED\")\"\n+\t\tfi\n+\t\t;;\n+\ttortoisemerge)\n+\t\tif $base_present; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t-base:\"$BASE\" -mine:\"$LOCAL\" \\\n+\t\t\t\t-theirs:\"$REMOTE\" -merged:\"$MERGED\"\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\techo \"TortoiseMerge cannot be used without a base\" 1>&2\n+\t\t\tstatus=1\n+\t\tfi\n+\t\t;;\n+\t*)\n+\t\tif test -z \"$merge_tool_cmd\"; then\n+\t\t\tif merge_mode; then\n+\t\t\t\tstatus=1\n+\t\t\tfi\n+\t\t\tbreak\n+\t\tfi\n+\t\tif merge_mode; then\n+\t\t\tif test \"$merge_tool_trust_exit_code\" = \"false\"; then\n+\t\t\t\ttouch \"$BACKUP\"\n+\t\t\t\t( eval $merge_tool_cmd )\n+\t\t\t\tcheck_unchanged\n+\t\t\telse\n+\t\t\t\t( eval $merge_tool_cmd )\n+\t\t\t\tstatus=$?\n+\t\t\tfi\n+\t\telse\n+\t\t\t( eval $merge_tool_cmd )\n+\t\tfi\n+\t\t;;\n+\tesac\n+\treturn $status\n+}\n+\n+guess_merge_tool () {\n+\ttools=\"ecmerge\"\n+\tif merge_mode; then\n+\t\ttools=\"$tools tortoisemerge\"\n+\telse\n+\t\tkompare=\"kompare\"\n+\tfi\n+\tif test -n \"$DISPLAY\"; then\n+\t\tif test -n \"$GNOME_DESKTOP_SESSION_ID\" ; then\n+\t\t\ttools=\"meld opendiff kdiff3 $kompare tkdiff $tools\"\n+\t\t\ttools=\"$tools xxdiff gvimdiff diffuse\"\n+\t\telse\n+\t\t\ttools=\"opendiff kdiff3 $kompare tkdiff xxdiff $tools\"\n+\t\t\ttools=\"$tools meld gvimdiff diffuse\"\n+\t\tfi\n+\tfi\n+\tif echo \"${VISUAL:-$EDITOR}\" | grep emacs > /dev/null 2>&1; then\n+\t\t# $EDITOR is emacs so add emerge as a candidate\n+\t\ttools=\"$tools emerge vimdiff\"\n+\telif echo \"${VISUAL:-$EDITOR}\" | grep vim > /dev/null 2>&1; then\n+\t\t# $EDITOR is vim so add vimdiff as a candidate\n+\t\ttools=\"$tools vimdiff emerge\"\n+\telse\n+\t\ttools=\"$tools emerge vimdiff\"\n+\tfi\n+\ttools=\"$(echo \"$tools\" | sed -e 's/ +/ /g')\"\n+\techo >&2 \"merge tool candidates: $tools\"\n+\n+\t# Loop over each candidate and stop when a valid merge tool is found.\n+\tfor i in $tools\n+\tdo\n+\t\tmerge_tool_path=\"$(translate_merge_tool_path \"$i\")\"\n+\t\tif type \"$merge_tool_path\" > /dev/null 2>&1; then\n+\t\t\tmerge_tool=\"$i\"\n+\t\t\tbreak\n+\t\tfi\n+\tdone\n+\n+\tif test -z \"$merge_tool\" ; then\n+\t\techo >&2 \"No known merge resolution program available.\"\n+\t\treturn 1\n+\tfi\n+\techo \"$merge_tool\"\n+}\n+\n+get_configured_merge_tool () {\n+\t# Diff mode first tries diff.tool and falls back to merge.tool.\n+\t# Merge mode only checks merge.tool\n+\tif diff_mode; then\n+\t\ttool=$(git config diff.tool)\n+\tfi\n+\tif test -z \"$tool\"; then\n+\t\ttool=$(git config merge.tool)\n+\tfi\n+\tif test -n \"$merge_tool\" && ! valid_tool \"$merge_tool\"; then\n+\t\techo >&2 \"git config option $TOOL_MODE.tool set to unknown tool: $merge_tool\"\n+\t\techo >&2 \"Resetting to default...\"\n+\t\treturn 1\n+\tfi\n+\techo \"$tool\"\n+}\n+\n+get_merge_tool_path () {\n+\t# A merge tool has been set, so verify that it's valid.\n+\tif ! valid_tool \"$merge_tool\"; then\n+\t\techo >&2 \"Unknown merge tool $merge_tool\"\n+\t\texit 1\n+\tfi\n+\tif diff_mode; then\n+\t\tmerge_tool_path=$(git config difftool.\"$merge_tool\".path)\n+\tfi\n+\tif test -z \"$merge_tool_path\"; then\n+\t\tmerge_tool_path=$(git config mergetool.\"$merge_tool\".path)\n+\tfi\n+\tmerge_tool_path=\"$(translate_merge_tool_path \"$merge_tool\" \"$merge_tool_path\")\"\n+\tif test -z \"$merge_tool_cmd\" && ! type \"$merge_tool_path\" > /dev/null 2>&1; then\n+\t\techo >&2 \"The $TOOL_MODE tool $merge_tool is not available as '$merge_tool_path'\"\n+\t\texit 1\n+\tfi\n+\techo \"$merge_tool_path\"\n+}\n+\n+get_merge_tool () {\n+\tmerge_tool=\"$1\"\n+\t# Check if a merge tool has been configured\n+\tif test -z \"$merge_tool\"; then\n+\t\tmerge_tool=$(get_configured_merge_tool)\n+\tfi\n+\t# Try to guess an appropriate merge tool if no tool has been set.\n+\tif test -z \"$merge_tool\"; then\n+\t\tmerge_tool=$(guess_merge_tool) || exit\n+\tfi\n+\techo \"$merge_tool\"\n+}\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex cceebb7..efa31a2 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -11,7 +11,9 @@\n USAGE='[--tool=tool] [-y|--no-prompt|--prompt] [file to merge] ...'\n SUBDIRECTORY_OK=Yes\n OPTIONS_SPEC=\n+TOOL_MODE=merge\n . git-sh-setup\n+. git-mergetool--lib\n require_work_tree\n \n # Returns true if the mode reflects a symlink\n@@ -110,22 +112,6 @@ resolve_deleted_merge () {\n \tdone\n }\n \n-check_unchanged () {\n-    if test \"$MERGED\" -nt \"$BACKUP\" ; then\n-\tstatus=0;\n-    else\n-\twhile true; do\n-\t    echo \"$MERGED seems unchanged.\"\n-\t    printf \"Was the merge successful? [y/n] \"\n-\t    read answer < /dev/tty\n-\t    case \"$answer\" in\n-\t\ty*|Y*) status=0; break ;;\n-\t\tn*|N*) status=1; break ;;\n-\t    esac\n-\tdone\n-    fi\n-}\n-\n checkout_staged_file () {\n     tmpfile=$(expr \"$(git checkout-index --temp --stage=\"$1\" \"$2\")\" : '\\([^\t]*\\)\t')\n \n@@ -188,107 +174,11 @@ merge_file () {\n \tread ans\n     fi\n \n-    case \"$merge_tool\" in\n-\tkdiff3)\n-\t    if base_present ; then\n-\t\t(\"$merge_tool_path\" --auto --L1 \"$MERGED (Base)\" --L2 \"$MERGED (Local)\" --L3 \"$MERGED (Remote)\" \\\n-\t\t    -o \"$MERGED\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\n-\t    else\n-\t\t(\"$merge_tool_path\" --auto --L1 \"$MERGED (Local)\" --L2 \"$MERGED (Remote)\" \\\n-\t\t    -o \"$MERGED\" \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\n-\t    fi\n-\t    status=$?\n-\t    ;;\n-\ttkdiff)\n-\t    if base_present ; then\n-\t\t\"$merge_tool_path\" -a \"$BASE\" -o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n-\t    else\n-\t\t\"$merge_tool_path\" -o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n-\t    fi\n-\t    status=$?\n-\t    ;;\n-\tmeld)\n-\t    touch \"$BACKUP\"\n-\t    \"$merge_tool_path\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n-\t    check_unchanged\n-\t    ;;\n-\tvimdiff)\n-\t    touch \"$BACKUP\"\n-\t    \"$merge_tool_path\" -d -c \"wincmd l\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n-\t    check_unchanged\n-\t    ;;\n-\tgvimdiff)\n-\t    touch \"$BACKUP\"\n-\t    \"$merge_tool_path\" -d -c \"wincmd l\" -f \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n-\t    check_unchanged\n-\t    ;;\n-\txxdiff)\n-\t    touch \"$BACKUP\"\n-\t    if base_present ; then\n-\t\t\"$merge_tool_path\" -X --show-merged-pane \\\n-\t\t    -R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n-\t\t    -R 'Accel.Search: \"Ctrl+F\"' \\\n-\t\t    -R 'Accel.SearchForward: \"Ctrl-G\"' \\\n-\t\t    --merged-file \"$MERGED\" \"$LOCAL\" \"$BASE\" \"$REMOTE\"\n-\t    else\n-\t\t\"$merge_tool_path\" -X --show-merged-pane \\\n-\t\t    -R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n-\t\t    -R 'Accel.Search: \"Ctrl+F\"' \\\n-\t\t    -R 'Accel.SearchForward: \"Ctrl-G\"' \\\n-\t\t    --merged-file \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n-\t    fi\n-\t    check_unchanged\n-\t    ;;\n-\topendiff)\n-\t    touch \"$BACKUP\"\n-\t    if base_present; then\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\" | cat\n-\t    else\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" -merge \"$MERGED\" | cat\n-\t    fi\n-\t    check_unchanged\n-\t    ;;\n-\tecmerge)\n-\t    touch \"$BACKUP\"\n-\t    if base_present; then\n-\t\t\"$merge_tool_path\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" --default --mode=merge3 --to=\"$MERGED\"\n-\t    else\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" --default --mode=merge2 --to=\"$MERGED\"\n-\t    fi\n-\t    check_unchanged\n-\t    ;;\n-\temerge)\n-\t    if base_present ; then\n-\t\t\"$merge_tool_path\" -f emerge-files-with-ancestor-command \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$(basename \"$MERGED\")\"\n-\t    else\n-\t\t\"$merge_tool_path\" -f emerge-files-command \"$LOCAL\" \"$REMOTE\" \"$(basename \"$MERGED\")\"\n-\t    fi\n-\t    status=$?\n-\t    ;;\n-\ttortoisemerge)\n-\t    if base_present ; then\n-\t\ttouch \"$BACKUP\"\n-\t\t\"$merge_tool_path\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"\n-\t\tcheck_unchanged\n-\t    else\n-\t\techo \"TortoiseMerge cannot be used without a base\" 1>&2\n-\t\tstatus=1\n-\t    fi\n-\t    ;;\n-\t*)\n-\t    if test -n \"$merge_tool_cmd\"; then\n-\t\tif test \"$merge_tool_trust_exit_code\" = \"false\"; then\n-\t\t    touch \"$BACKUP\"\n-\t\t    ( eval $merge_tool_cmd )\n-\t\t    check_unchanged\n-\t\telse\n-\t\t    ( eval $merge_tool_cmd )\n-\t\t    status=$?\n-\t\tfi\n-\t    fi\n-\t    ;;\n-    esac\n-    if test \"$status\" -ne 0; then\n+    present=false\n+    base_present &&\n+    present=true\n+\n+    if ! run_merge_tool \"$merge_tool\" \"$present\"; then\n \techo \"merge of $MERGED failed\" 1>&2\n \tmv -- \"$BACKUP\" \"$MERGED\"\n \n@@ -347,44 +237,6 @@ do\n     shift\n done\n \n-valid_custom_tool()\n-{\n-    merge_tool_cmd=\"$(git config mergetool.$1.cmd)\"\n-    test -n \"$merge_tool_cmd\"\n-}\n-\n-valid_tool() {\n-\tcase \"$1\" in\n-\t\tkdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge | tortoisemerge)\n-\t\t\t;; # happy\n-\t\t*)\n-\t\t\tif ! valid_custom_tool \"$1\"; then\n-\t\t\t\treturn 1\n-\t\t\tfi\n-\t\t\t;;\n-\tesac\n-}\n-\n-init_merge_tool_path() {\n-\tmerge_tool_path=$(git config mergetool.$1.path)\n-\tif test -z \"$merge_tool_path\" ; then\n-\t\tcase \"$1\" in\n-\t\t\tvimdiff)\n-\t\t\t\tmerge_tool_path=vim\n-\t\t\t\t;;\n-\t\t\tgvimdiff)\n-\t\t\t\tmerge_tool_path=gvim\n-\t\t\t\t;;\n-\t\t\temerge)\n-\t\t\t\tmerge_tool_path=emacs\n-\t\t\t\t;;\n-\t\t\t*)\n-\t\t\t\tmerge_tool_path=$1\n-\t\t\t\t;;\n-\t\tesac\n-\tfi\n-}\n-\n prompt_after_failed_merge() {\n     while true; do\n \tprintf \"Continue merging other unresolved paths (y/n) ? \"\n@@ -402,62 +254,12 @@ prompt_after_failed_merge() {\n     done\n }\n \n-if test -z \"$merge_tool\"; then\n-    merge_tool=$(git config merge.tool)\n-    if test -n \"$merge_tool\" && ! valid_tool \"$merge_tool\"; then\n-\t    echo >&2 \"git config option merge.tool set to unknown tool: $merge_tool\"\n-\t    echo >&2 \"Resetting to default...\"\n-\t    unset merge_tool\n-    fi\n-fi\n-\n-if test -z \"$merge_tool\" ; then\n-    if test -n \"$DISPLAY\"; then\n-        if test -n \"$GNOME_DESKTOP_SESSION_ID\" ; then\n-            merge_tool_candidates=\"meld kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse\"\n-        else\n-            merge_tool_candidates=\"kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse\"\n-        fi\n-    fi\n-    if echo \"${VISUAL:-$EDITOR}\" | grep 'emacs' > /dev/null 2>&1; then\n-        merge_tool_candidates=\"$merge_tool_candidates emerge opendiff vimdiff\"\n-    elif echo \"${VISUAL:-$EDITOR}\" | grep 'vim' > /dev/null 2>&1; then\n-        merge_tool_candidates=\"$merge_tool_candidates vimdiff opendiff emerge\"\n-    else\n-        merge_tool_candidates=\"$merge_tool_candidates opendiff emerge vimdiff\"\n-    fi\n-    echo \"merge tool candidates: $merge_tool_candidates\"\n-    for i in $merge_tool_candidates; do\n-        init_merge_tool_path $i\n-        if type \"$merge_tool_path\" > /dev/null 2>&1; then\n-            merge_tool=$i\n-            break\n-        fi\n-    done\n-    if test -z \"$merge_tool\" ; then\n-\techo \"No known merge resolution program available.\"\n-\texit 1\n-    fi\n-else\n-    if ! valid_tool \"$merge_tool\"; then\n-        echo >&2 \"Unknown merge_tool $merge_tool\"\n-        exit 1\n-    fi\n-\n-    init_merge_tool_path \"$merge_tool\"\n-\n-    merge_keep_backup=\"$(git config --bool merge.keepBackup || echo true)\"\n-    merge_keep_temporaries=\"$(git config --bool mergetool.keepTemporaries || echo false)\"\n-\n-    if test -z \"$merge_tool_cmd\" && ! type \"$merge_tool_path\" > /dev/null 2>&1; then\n-        echo \"The merge tool $merge_tool is not available as '$merge_tool_path'\"\n-        exit 1\n-    fi\n-\n-    if ! test -z \"$merge_tool_cmd\"; then\n-        merge_tool_trust_exit_code=\"$(git config --bool mergetool.$merge_tool.trustExitCode || echo false)\"\n-    fi\n-fi\n+merge_tool=$(get_merge_tool \"$merge_tool\") || exit\n+merge_tool_cmd=\"$(get_merge_tool_cmd \"$merge_tool\")\"\n+merge_tool_path=\"$(get_merge_tool_path \"$merge_tool\")\" || exit\n+merge_keep_backup=\"$(git config --bool merge.keepBackup || echo true)\"\n+merge_keep_temporaries=\"$(git config --bool mergetool.keepTemporaries || echo false)\"\n+merge_tool_trust_exit_code=\"$(git config --bool mergetool.\"$merge_tool\".trustExitCode || echo false)\"\n \n last_status=0\n rollup_status=0\n-- \n1.6.1.3\n"},{"id":"110786","messageId":"200904080733.01030.markus.heidelberg@web.de","threadId":"18771","inReplyTo":"1239145213-76701-1-git-send-email-davvid@gmail.com","subject":"Re: [PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","fromName":"Markus Heidelberg","fromEmail":"markus.heidelberg@web.de","sentAt":"2009-04-08T05:33:00Z","receivedAt":"2009-04-08T05:33:00Z","isPatch":true,"sender":{"key":"markus.heidelberg@web.de","avatar":"https://avatars.githubusercontent.com/u/6334512?v=4"},"body":"David Aguilar, 08.04.2009:\n> diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh\n\n> +guess_merge_tool () {\n> +\ttools=\"ecmerge\"\n> +\tif merge_mode; then\n> +\t\ttools=\"$tools tortoisemerge\"\n\necmerge can now go to the block after \"test -n $DISPLAY\", so that in\nthis if-then-else really only merge-only and diff-only tools are\nhandled.\nThen here it is\n+\t\ttools=\"tortoisemerge\"\n\n> +\telse\n> +\t\tkompare=\"kompare\"\n\nand here\n+\t\ttools=\"kompare\"\n\n> +\tfi\n> +\tif test -n \"$DISPLAY\"; then\n> +\t\tif test -n \"$GNOME_DESKTOP_SESSION_ID\" ; then\n> +\t\t\ttools=\"meld opendiff kdiff3 $kompare tkdiff $tools\"\n> +\t\t\ttools=\"$tools xxdiff gvimdiff diffuse\"\n> +\t\telse\n> +\t\t\ttools=\"opendiff kdiff3 $kompare tkdiff xxdiff $tools\"\n> +\t\t\ttools=\"$tools meld gvimdiff diffuse\"\n> +\t\tfi\n\nAnd above ecmerge\nAnd now that we remove the duplicated spaces afterwards anyway, we can\nget rid of the double tools= and continue the line with \\\nif we adjust the sed command below...\n\n> +\tfi\n> +\tif echo \"${VISUAL:-$EDITOR}\" | grep emacs > /dev/null 2>&1; then\n> +\t\t# $EDITOR is emacs so add emerge as a candidate\n> +\t\ttools=\"$tools emerge vimdiff\"\n> +\telif echo \"${VISUAL:-$EDITOR}\" | grep vim > /dev/null 2>&1; then\n> +\t\t# $EDITOR is vim so add vimdiff as a candidate\n> +\t\ttools=\"$tools vimdiff emerge\"\n> +\telse\n> +\t\ttools=\"$tools emerge vimdiff\"\n> +\tfi\n> +\ttools=\"$(echo \"$tools\" | sed -e 's/ +/ /g')\"\n\nDoesn't work for me. For me 's/ \\+/ /g' works.\n\n...like this: 's/[ \t]\\+/ /g' (space and tab)\n\nOK, for clarification now:\n\tif merge_mode; then\n\t\ttools=\"tortoisemerge\"\n\telse\n\t\ttools=\"kompare\"\n\tfi\n\tif test -n \"$DISPLAY\"; then\n\t\tif test -n \"$GNOME_DESKTOP_SESSION_ID\" ; then\n\t\t\ttools=\"meld opendiff kdiff3 tkdiff xxdiff $tools \\\n\t\t\t\tgvimdiff diffuse ecmerge\"\n\t\telse\n\t\t\ttools=\"opendiff kdiff3 tkdiff xxdiff meld $tools \\\n\t\t\t\tgvimdiff diffuse ecmerge\"\n\t\tfi\n\tfi\n\t[...]\n\ttools=\"$(echo \"$tools\" | sed -e 's/[ \t]\\+/ /g')\"\n\n> +\techo >&2 \"merge tool candidates: $tools\"\n> +\n> +\t# Loop over each candidate and stop when a valid merge tool is found.\n> +\tfor i in $tools\n> +\tdo\n> +\t\tmerge_tool_path=\"$(translate_merge_tool_path \"$i\")\"\n> +\t\tif type \"$merge_tool_path\" > /dev/null 2>&1; then\n> +\t\t\tmerge_tool=\"$i\"\n> +\t\t\tbreak\n> +\t\tfi\n> +\tdone\n> +\n> +\tif test -z \"$merge_tool\" ; then\n> +\t\techo >&2 \"No known merge resolution program available.\"\n> +\t\treturn 1\n> +\tfi\n> +\techo \"$merge_tool\"\n> +}\n\nLooks good to me, after these last 2 issues are adjusted.\nMaybe resend the whole series then, so that Junio can apply them easily?\n\nMarkus\n"},{"id":"110790","messageId":"7vtz4zr80v.fsf@gitster.siamese.dyndns.org","threadId":"18771","inReplyTo":"200904080733.01030.markus.heidelberg@web.de","subject":"Re: [PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-04-08T06:09:36Z","receivedAt":"2009-04-08T06:09:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Heidelberg <markus.heidelberg@web.de> writes:\n\n>> +\tfi\n>> +\tif echo \"${VISUAL:-$EDITOR}\" | grep emacs > /dev/null 2>&1; then\n>> +\t\t# $EDITOR is emacs so add emerge as a candidate\n>> +\t\ttools=\"$tools emerge vimdiff\"\n>> +\telif echo \"${VISUAL:-$EDITOR}\" | grep vim > /dev/null 2>&1; then\n>> +\t\t# $EDITOR is vim so add vimdiff as a candidate\n>> +\t\ttools=\"$tools vimdiff emerge\"\n>> +\telse\n>> +\t\ttools=\"$tools emerge vimdiff\"\n>> +\tfi\n>> +\ttools=\"$(echo \"$tools\" | sed -e 's/ +/ /g')\"\n>\n> Doesn't work for me. For me 's/ \\+/ /g' works.\n> ...like this: 's/[ \t]\\+/ /g' (space and tab)\n\nPleae don't.  \"s/  */ /g' should be the most portable (the point being \"do\nnot use one-or-more +\").\n\n> Looks good to me, after these last 2 issues are adjusted.\n> Maybe resend the whole series then, so that Junio can apply them easily?\n\nThanks.  I've replaced the series with the following applied on top of the\n'master', but I won't be merging them to 'next' for tonight, I guess.\n\n[PATCH 01/14] doc/merge-config: list ecmerge as a built-in merge\n[PATCH 02/14] git-mergetool/difftool: make (g)vimdiff workable under\n[PATCH 03/14] git-mergetool: add new merge tool TortoiseMerge\n[PATCH 04/14] difftool: remove merge options for opendiff, tkdiff,\n[PATCH 05/14] difftool: remove the backup file feature\n[PATCH 06/14] difftool: use perl built-ins when testing for msys\n[PATCH v2 07/14] difftool: add a -y shortcut for --no-prompt\n[PATCH 08/14] difftool/mergetool: add diffuse as merge and diff tool\n[PATCH v2 09/14] difftool: move 'git-difftool' out of contrib\n[PATCH v3 10/14] difftool: add various git-difftool tests\n[PATCH v2 11/14] difftool: add support for a difftool.prompt config variable\n[PATCH 12/14] bash completion: add git-difftool\n[PATCH 13/14] mergetool: use $( ... ) instead of `backticks`\n[PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib\n\nIt appears that, assuming that up to 13/14 above is what you two expected\nme to pick up, we would perhaps need to only replace 14/14?\n\nAs the final sanity check, please eyeball the attached interdiff, created\nthis way:\n\n $ git checkout master^0\n $ git am -s ./+da-fourteen-patches\n $ A=$(git rev-parse HEAD)\n $ git reset --hard master\n $ git merge da/difftool ;# old series\n $ git diff --stat -p HEAD $A ;# what's new in the new series?\n\n Documentation/config.txt               |    3 +-\n Documentation/git-mergetool.txt        |    2 +-\n Documentation/merge-config.txt         |    6 +-\n command-list.txt                       |    1 -\n contrib/completion/git-completion.bash |    2 +-\n git-mergetool--lib.sh                  |  237 ++++++++++++++++++--------------\n t/t7800-difftool.sh                    |    4 +-\n 7 files changed, 144 insertions(+), 111 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 6e29623..d427daf 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -670,7 +670,8 @@ diff.suppressBlankEmpty::\n diff.tool::\n \tControls which diff tool is used.  `diff.tool` overrides\n \t`merge.tool` when used by linkgit:git-difftool[1] and has\n-\tthe same valid values as `merge.tool`.\n+\tthe same valid values as `merge.tool` minus \"tortoisemerge\"\n+\tand plus \"kompare\".\n \n difftool.<tool>.path::\n \tOverride the path for the given tool.  This is useful in case\ndiff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt\nindex c3a8092..ff9700d 100644\n--- a/Documentation/git-mergetool.txt\n+++ b/Documentation/git-mergetool.txt\n@@ -27,7 +27,7 @@ OPTIONS\n \tUse the merge resolution program specified by <tool>.\n \tValid merge tools are:\n \tkdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge,\n-\tdiffuse and opendiff\n+\tdiffuse, tortoisemerge and opendiff\n +\n If a merge resolution program is not specified, 'git-mergetool'\n will use the configuration variable `merge.tool`.  If the\ndiff --git a/Documentation/merge-config.txt b/Documentation/merge-config.txt\nindex c4fc3eb..4832bc7 100644\n--- a/Documentation/merge-config.txt\n+++ b/Documentation/merge-config.txt\n@@ -23,9 +23,9 @@ merge.tool::\n \tControls which merge resolution program is used by\n \tlinkgit:git-mergetool[1].  Valid built-in values are: \"kdiff3\",\n \t\"tkdiff\", \"meld\", \"xxdiff\", \"emerge\", \"vimdiff\", \"gvimdiff\",\n-\t\"diffuse\" and \"opendiff\".  Any other value is treated as a custom\n-\tmerge tool and there must be a corresponding mergetool.<tool>.cmd\n-\toption.\n+\t\"diffuse\", \"ecmerge\", \"tortoisemerge\", and\n+\t\"opendiff\".  Any other value is treated is custom merge tool\n+\tand there must be a corresponding mergetool.<tool>.cmd option.\n \n merge.verbosity::\n \tControls the amount of output shown by the recursive merge\ndiff --git a/command-list.txt b/command-list.txt\nindex fd66395..fb03a2e 100644\n--- a/command-list.txt\n+++ b/command-list.txt\n@@ -69,7 +69,6 @@ git-merge-file                          plumbingmanipulators\n git-merge-index                         plumbingmanipulators\n git-merge-one-file                      purehelpers\n git-mergetool                           ancillarymanipulators\n-git-mergetool--lib                      purehelpers\n git-merge-tree                          ancillaryinterrogators\n git-mktag                               plumbingmanipulators\n git-mktree                              plumbingmanipulators\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 6f96d75..069e19e 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1192,7 +1192,7 @@ _git_mergetool ()\n \tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n \tcase \"$cur\" in\n \t--tool=*)\n-\t\t__gitcomp \"$__git_mergetools_common\" \"\" \"${cur##--tool=}\"\n+\t\t__gitcomp \"$__git_mergetools_common tortoisemerge\" \"\" \"${cur##--tool=}\"\n \t\treturn\n \t\t;;\n \t--*)\ndiff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh\nindex 3d3edda..95cc355 100644\n--- a/git-mergetool--lib.sh\n+++ b/git-mergetool--lib.sh\n@@ -1,10 +1,10 @@\n # git-mergetool--lib is a library for common merge tool functions\n diff_mode() {\n-\ttest $TOOL_MODE = \"diff\"\n+\ttest \"$TOOL_MODE\" = diff\n }\n \n merge_mode() {\n-\ttest $TOOL_MODE = \"merge\"\n+\ttest \"$TOOL_MODE\" = merge\n }\n \n translate_merge_tool_path () {\n@@ -30,36 +30,36 @@ translate_merge_tool_path () {\n }\n \n check_unchanged () {\n-\tif merge_mode; then\n-\t\tif test \"$MERGED\" -nt \"$BACKUP\"; then\n-\t\t\tstatus=0\n-\t\telse\n-\t\t\twhile true; do\n-\t\t\t\techo \"$MERGED seems unchanged.\"\n-\t\t\t\tprintf \"Was the merge successful? [y/n] \"\n-\t\t\t\tread answer < /dev/tty\n-\t\t\t\tcase \"$answer\" in\n-\t\t\t\ty*|Y*) status=0; break ;;\n-\t\t\t\tn*|N*) status=1; break ;;\n-\t\t\t\tesac\n-\t\t\tdone\n-\t\tfi\n-\telse\n+\tif test \"$MERGED\" -nt \"$BACKUP\"; then\n \t\tstatus=0\n+\telse\n+\t\twhile true; do\n+\t\t\techo \"$MERGED seems unchanged.\"\n+\t\t\tprintf \"Was the merge successful? [y/n] \"\n+\t\t\tread answer < /dev/tty\n+\t\t\tcase \"$answer\" in\n+\t\t\ty*|Y*) status=0; break ;;\n+\t\t\tn*|N*) status=1; break ;;\n+\t\t\tesac\n+\t\tdone\n \tfi\n-\treturn $status\n }\n \n valid_tool () {\n \tcase \"$1\" in\n-\tkdiff3 | kompare | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge | diffuse | tortoisemerge)\n-\t\tif test \"$1\" = \"kompare\" && ! diff_mode; then\n+\tkdiff3 | tkdiff | xxdiff | meld | opendiff | \\\n+\temerge | vimdiff | gvimdiff | ecmerge | diffuse)\n+\t\t;; # happy\n+\ttortoisemerge)\n+\t\tif ! merge_mode; then\n \t\t\treturn 1\n \t\tfi\n-\t\tif test \"$1\" = \"tortoisemerge\" && ! merge_mode; then\n+\t\t;;\n+\tkompare)\n+\t\tif ! diff_mode; then\n \t\t\treturn 1\n \t\tfi\n-\t\t;; # happy\n+\t\t;;\n \t*)\n \t\tif test -z \"$(get_merge_tool_cmd \"$1\")\"; then\n \t\t\treturn 1\n@@ -79,160 +79,182 @@ get_merge_tool_cmd () {\n \n run_merge_tool () {\n \tbase_present=\"$2\"\n-\tif diff_mode; then\n-\t\tbase_present=\"false\"\n-\tfi\n-\tif test -z \"$base_present\"; then\n-\t\tbase_present=\"true\"\n-\tfi\n+\tstatus=0\n \n \tcase \"$1\" in\n \tkdiff3)\n-\t\tif $base_present; then\n-\t\t\t(\"$merge_tool_path\" --auto \\\n-\t\t\t --L1 \"$MERGED (Base)\" --L2 \"$MERGED (Local)\" --L3 \"$MERGED (Remote)\" \\\n-\t\t\t -o \"$MERGED\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\n-\t\telse\n-\t\t\tif merge_mode; then\n+\t\tif merge_mode; then\n+\t\t\tif $base_present; then\n \t\t\t\t(\"$merge_tool_path\" --auto \\\n-\t\t\t\t --L1 \"$MERGED (Local)\" \\\n-\t\t\t\t --L2 \"$MERGED (Remote)\" \\\n-\t\t\t\t -o \"$MERGED\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t--L1 \"$MERGED (Base)\" \\\n+\t\t\t\t\t--L2 \"$MERGED (Local)\" \\\n+\t\t\t\t\t--L3 \"$MERGED (Remote)\" \\\n+\t\t\t\t\t-o \"$MERGED\" \\\n+\t\t\t\t\t\"$BASE\" \"$LOCAL\" \"$REMOTE\" \\\n \t\t\t\t> /dev/null 2>&1)\n \t\t\telse\n \t\t\t\t(\"$merge_tool_path\" --auto \\\n-\t\t\t\t --L1 \"$MERGED (A)\" \\\n-\t\t\t\t --L2 \"$MERGED (B)\" \\\n-\t\t\t\t \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t--L1 \"$MERGED (Local)\" \\\n+\t\t\t\t\t--L2 \"$MERGED (Remote)\" \\\n+\t\t\t\t\t-o \"$MERGED\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$REMOTE\" \\\n \t\t\t\t> /dev/null 2>&1)\n \t\t\tfi\n+\t\t\tstatus=$?\n+\t\telse\n+\t\t\t(\"$merge_tool_path\" --auto \\\n+\t\t\t --L1 \"$MERGED (A)\" \\\n+\t\t\t --L2 \"$MERGED (B)\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t > /dev/null 2>&1)\n \t\tfi\n-\t\tstatus=$?\n \t\t;;\n \tkompare)\n \t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n-\t\tstatus=$?\n \t\t;;\n \ttkdiff)\n-\t\tif $base_present; then\n-\t\t\t\"$merge_tool_path\" -a \"$BASE\" -o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n-\t\telse\n-\t\t\tif merge_mode; then\n-\t\t\t\t\"$merge_tool_path\" -o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n+\t\tif merge_mode; then\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" -a \"$BASE\" \\\n+\t\t\t\t\t-o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n \t\t\telse\n-\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t-o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n \t\t\tfi\n+\t\t\tstatus=$?\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n \t\tfi\n-\t\tstatus=$?\n \t\t;;\n \tmeld)\n \t\tif merge_mode; then\n \t\t\ttouch \"$BACKUP\"\n \t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n+\t\t\tcheck_unchanged\n \t\telse\n \t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\"\n \t\tfi\n-\t\tcheck_unchanged\n \t\t;;\n \tdiffuse)\n \t\tif merge_mode; then\n \t\t\ttouch \"$BACKUP\"\n-\t\tfi\n-\t\tif $base_present; then\n-\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\" \"$BASE\" | cat\n-\t\telse\n-\t\t\tif merge_mode; then\n-\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\" | cat\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$MERGED\" \"$REMOTE\" \\\n+\t\t\t\t\t\"$BASE\" | cat\n \t\t\telse\n-\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" | cat\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$MERGED\" \"$REMOTE\" | cat\n \t\t\tfi\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" | cat\n \t\tfi\n-\t\tcheck_unchanged\n \t\t;;\n \tvimdiff)\n \t\tif merge_mode; then\n \t\t\ttouch \"$BACKUP\"\n-\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n+\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" \\\n+\t\t\t\t\"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n \t\t\tcheck_unchanged\n \t\telse\n-\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" \"$LOCAL\" \"$REMOTE\"\n+\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n \t\tfi\n \t\t;;\n \tgvimdiff)\n \t\tif merge_mode; then\n \t\t\ttouch \"$BACKUP\"\n-\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" -f \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n+\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" -f \\\n+\t\t\t\t\"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n \t\t\tcheck_unchanged\n \t\telse\n-\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" -f \"$LOCAL\" \"$REMOTE\"\n+\t\t\t\"$merge_tool_path\" -d -c \"wincmd l\" -f \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n \t\tfi\n \t\t;;\n \txxdiff)\n \t\tif merge_mode; then\n \t\t\ttouch \"$BACKUP\"\n-\t\tfi\n-\t\tif $base_present; then\n-\t\t\t\"$merge_tool_path\" -X --show-merged-pane \\\n-\t\t\t    -R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n-\t\t\t    -R 'Accel.Search: \"Ctrl+F\"' \\\n-\t\t\t    -R 'Accel.SearchForward: \"Ctrl-G\"' \\\n-\t\t\t    --merged-file \"$MERGED\" \"$LOCAL\" \"$BASE\" \"$REMOTE\"\n-\t\telse\n-\t\t\tif merge_mode; then\n-\t\t\t\t\"$merge_tool_path\" -X $extra \\\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" -X --show-merged-pane \\\n \t\t\t\t\t-R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n \t\t\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n \t\t\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n-\t\t\t\t\t--merged-file \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n+\t\t\t\t\t--merged-file \"$MERGED\" \\\n+\t\t\t\t\t\"$LOCAL\" \"$BASE\" \"$REMOTE\"\n \t\t\telse\n-\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\"$merge_tool_path\" -X $extra \\\n+\t\t\t\t\t-R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n \t\t\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n \t\t\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n+\t\t\t\t\t--merged-file \"$MERGED\" \\\n \t\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n \t\t\tfi\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n+\t\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n \t\tfi\n-\t\tcheck_unchanged\n \t\t;;\n \topendiff)\n-\t\tmerge_mode && touch \"$BACKUP\"\n-\t\tif $base_present; then\n-\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n-\t\t\t\t-ancestor \"$BASE\" -merge \"$MERGED\" | cat\n-\t\telse\n-\t\t\tif merge_mode; then\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\tif $base_present; then\n \t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t-ancestor \"$BASE\" \\\n \t\t\t\t\t-merge \"$MERGED\" | cat\n \t\t\telse\n-\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" | cat\n+\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t-merge \"$MERGED\" | cat\n \t\t\tfi\n+\t\t\tcheck_unchanged\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" | cat\n \t\tfi\n-\t\tcheck_unchanged\n \t\t;;\n \tecmerge)\n-\t\tmerge_mode && touch \"$BACKUP\"\n-\t\tif $base_present; then\n-\t\t\t\"$merge_tool_path\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \\\n-\t\t\t\t--default --mode=merge3 --to=\"$MERGED\"\n+\t\tif merge_mode; then\n+\t\t\ttouch \"$BACKUP\"\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t--default --mode=merge3 --to=\"$MERGED\"\n+\t\t\telse\n+\t\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t--default --mode=merge2 --to=\"$MERGED\"\n+\t\t\tfi\n+\t\t\tcheck_unchanged\n \t\telse\n \t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n \t\t\t\t--default --mode=merge2 --to=\"$MERGED\"\n \t\tfi\n-\t\tcheck_unchanged\n \t\t;;\n \temerge)\n-\t\tif $base_present; then\n-\t\t\t\"$merge_tool_path\" -f emerge-files-with-ancestor-command \\\n-\t\t\t\t\"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$(basename \"$MERGED\")\"\n+\t\tif merge_mode; then\n+\t\t\tif $base_present; then\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t-f emerge-files-with-ancestor-command \\\n+\t\t\t\t\t\"$LOCAL\" \"$REMOTE\" \"$BASE\" \\\n+\t\t\t\t\t\"$(basename \"$MERGED\")\"\n+\t\t\telse\n+\t\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t\t-f emerge-files-command \\\n+\t\t\t\t\t\"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t\t\"$(basename \"$MERGED\")\"\n+\t\t\tfi\n+\t\t\tstatus=$?\n \t\telse\n \t\t\t\"$merge_tool_path\" -f emerge-files-command \\\n \t\t\t\t\"$LOCAL\" \"$REMOTE\" \"$(basename \"$MERGED\")\"\n \t\tfi\n-\t\tstatus=$?\n \t\t;;\n \ttortoisemerge)\n \t\tif $base_present; then\n \t\t\ttouch \"$BACKUP\"\n-\t\t\t\"$merge_tool_path\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"\n+\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t-base:\"$BASE\" -mine:\"$LOCAL\" \\\n+\t\t\t\t-theirs:\"$REMOTE\" -merged:\"$MERGED\"\n \t\t\tcheck_unchanged\n \t\telse\n \t\t\techo \"TortoiseMerge cannot be used without a base\" 1>&2\n@@ -240,9 +262,14 @@ run_merge_tool () {\n \t\tfi\n \t\t;;\n \t*)\n-\t\tif test -n \"$merge_tool_cmd\"; then\n-\t\t\tif merge_mode &&\n-\t\t\ttest \"$merge_tool_trust_exit_code\" = \"false\"; then\n+\t\tif test -z \"$merge_tool_cmd\"; then\n+\t\t\tif merge_mode; then\n+\t\t\t\tstatus=1\n+\t\t\tfi\n+\t\t\tbreak\n+\t\tfi\n+\t\tif merge_mode; then\n+\t\t\tif test \"$merge_tool_trust_exit_code\" = \"false\"; then\n \t\t\t\ttouch \"$BACKUP\"\n \t\t\t\t( eval $merge_tool_cmd )\n \t\t\t\tcheck_unchanged\n@@ -250,6 +277,8 @@ run_merge_tool () {\n \t\t\t\t( eval $merge_tool_cmd )\n \t\t\t\tstatus=$?\n \t\t\tfi\n+\t\telse\n+\t\t\t( eval $merge_tool_cmd )\n \t\tfi\n \t\t;;\n \tesac\n@@ -257,27 +286,31 @@ run_merge_tool () {\n }\n \n guess_merge_tool () {\n-\tif diff_mode; then\n+\ttools=\"ecmerge\"\n+\tif merge_mode; then\n+\t\ttools=\"$tools tortoisemerge\"\n+\telse\n \t\tkompare=\"kompare\"\n \tfi\n \tif test -n \"$DISPLAY\"; then\n \t\tif test -n \"$GNOME_DESKTOP_SESSION_ID\" ; then\n-\t\t\ttools=\"meld kdiff3 $kompare tkdiff\"\n+\t\t\ttools=\"meld opendiff kdiff3 $kompare tkdiff $tools\"\n \t\t\ttools=\"$tools xxdiff gvimdiff diffuse\"\n \t\telse\n-\t\t\ttools=\"kdiff3 $kompare tkdiff xxdiff\"\n+\t\t\ttools=\"opendiff kdiff3 $kompare tkdiff xxdiff $tools\"\n \t\t\ttools=\"$tools meld gvimdiff diffuse\"\n \t\tfi\n \tfi\n \tif echo \"${VISUAL:-$EDITOR}\" | grep emacs > /dev/null 2>&1; then\n \t\t# $EDITOR is emacs so add emerge as a candidate\n-\t\ttools=\"$tools emerge opendiff vimdiff\"\n+\t\ttools=\"$tools emerge vimdiff\"\n \telif echo \"${VISUAL:-$EDITOR}\" | grep vim > /dev/null 2>&1; then\n \t\t# $EDITOR is vim so add vimdiff as a candidate\n-\t\ttools=\"$tools vimdiff opendiff emerge\"\n+\t\ttools=\"$tools vimdiff emerge\"\n \telse\n-\t\ttools=\"$tools opendiff emerge vimdiff\"\n+\t\ttools=\"$tools emerge vimdiff\"\n \tfi\n+\ttools=\"$(echo \"$tools\" | sed -e 's/ +/ /g')\"\n \techo >&2 \"merge tool candidates: $tools\"\n \n \t# Loop over each candidate and stop when a valid merge tool is found.\ndiff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh\nindex cbfbe87..2586f86 100755\n--- a/t/t7800-difftool.sh\n+++ b/t/t7800-difftool.sh\n@@ -202,10 +202,10 @@ test_expect_success 'difftool + mergetool config variables' '\n \n test_expect_success 'difftool.<tool>.path' '\n \tgit config difftool.tkdiff.path echo &&\n-\tdiff=$(git difftool -y -t tkdiff branch) &&\n+\tdiff=$(git difftool --tool=tkdiff --no-prompt branch) &&\n \tgit config --unset difftool.tkdiff.path &&\n \tlines=$(echo \"$diff\" | grep file | wc -l) &&\n-\ttest \"$lines\" = 1\n+\ttest \"$lines\" -eq 1\n '\n \n test_done\n"},{"id":"110797","messageId":"20090408063557.GA14404@gmail.com","threadId":"18771","inReplyTo":"7vtz4zr80v.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-08T06:35:58Z","receivedAt":"2009-04-08T06:35:58Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"On  0, Junio C Hamano <gitster@pobox.com> wrote:\n> Markus Heidelberg <markus.heidelberg@web.de> writes:\n> \n> >> +\ttools=\"$(echo \"$tools\" | sed -e 's/ +/ /g')\"\n> >\n> > Doesn't work for me. For me 's/ \\+/ /g' works.\n> > ...like this: 's/[ \t]\\+/ /g' (space and tab)\n> \n> Pleae don't.  \"s/  */ /g' should be the most portable (the point being \"do\n> not use one-or-more +\").\n\nv5 14/14.  good stuff.\n\n\n> > Looks good to me, after these last 2 issues are adjusted.\n> > Maybe resend the whole series then, so that Junio can apply them easily?\n> \n> Thanks.  I've replaced the series with the following applied on top of the\n> 'master', but I won't be merging them to 'next' for tonight, I guess.\n> \n> ...\n> [PATCH v2 07/14] difftool: add a -y shortcut for --no-prompt\n> [PATCH v2 09/14] difftool: move 'git-difftool' out of contrib\n> [PATCH v3 10/14] difftool: add various git-difftool tests\n> [PATCH v2 11/14] difftool: add support for a difftool.prompt config variable\n> [PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib\n> \n> It appears that, assuming that up to 13/14 above is what you two expected\n> me to pick up, we would perhaps need to only replace 14/14?\n\nYup\n\n> \n> As the final sanity check, please eyeball the attached interdiff, created\n> this way:\n\nThat looks right to me.\n\n> \n>  $ git checkout master^0\n>  $ git am -s ./+da-fourteen-patches\n>  $ A=$(git rev-parse HEAD)\n>  $ git reset --hard master\n>  $ git merge da/difftool ;# old series\n>  $ git diff --stat -p HEAD $A ;# what's new in the new series?\n> \n>  Documentation/config.txt               |    3 +-\n>  Documentation/git-mergetool.txt        |    2 +-\n>  Documentation/merge-config.txt         |    6 +-\n>  command-list.txt                       |    1 -\n>  contrib/completion/git-completion.bash |    2 +-\n>  git-mergetool--lib.sh                  |  237 ++++++++++++++++++--------------\n>  t/t7800-difftool.sh                    |    4 +-\n>  7 files changed, 144 insertions(+), 111 deletions(-)\n> \n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> ...\n\n-- \n\n\tDavid\n"},{"id":"110798","messageId":"20090408064037.GA9372@hashpling.org","threadId":"18771","inReplyTo":"7vtz4zr80v.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","fromName":"Charles Bailey","fromEmail":"charles@hashpling.org","sentAt":"2009-04-08T06:40:38Z","receivedAt":"2009-04-08T06:40:38Z","isPatch":true,"sender":{"key":"charles@hashpling.org","avatar":"https://avatars.githubusercontent.com/u/1668475?v=4"},"body":"On Tue, Apr 07, 2009 at 11:09:36PM -0700, Junio C Hamano wrote:\n> Markus Heidelberg <markus.heidelberg@web.de> writes:\n> > Looks good to me, after these last 2 issues are adjusted.\n> > Maybe resend the whole series then, so that Junio can apply them easily?\n> \n> Thanks.  I've replaced the series with the following applied on top of the\n> 'master', but I won't be merging them to 'next' for tonight, I guess.\n\nI feel I should be re-reviewing the mergetool patches, but while I\nhave sufficient time, it is usually at the weekend so I can't always\nrespond very rapidly.\n\nI have been skimming this series, but most of the times that I thought\nI could apply the series and have a thorough review, another comment\nand re-roll has come through and I've decided to wait until it's\nstable.\n\nMy slight concern is that this series has been changing very rapidly,\nis everyone else happy that it is stable enough for merge into next?\nWould you like my further input?\n\nCharles.\n"},{"id":"110799","messageId":"7vvdpfpr9k.fsf@gitster.siamese.dyndns.org","threadId":"18771","inReplyTo":"20090408064037.GA9372@hashpling.org","subject":"Re: [PATCH v4 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-04-08T06:56:55Z","receivedAt":"2009-04-08T06:56:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Charles Bailey <charles@hashpling.org> writes:\n\n> I have been skimming this series, but most of the times that I thought\n> I could apply the series and have a thorough review, another comment\n> and re-roll has come through and I've decided to wait until it's\n> stable.\n>\n> My slight concern is that this series has been changing very rapidly,\n> is everyone else happy that it is stable enough for merge into next?\n> Would you like my further input?\n\nI'd feel safer to pick up v5 of 14/14 from David and park the result in\n'pu' for a few days.  I expect myself to be overloaded with the day job\nfor the rest of the week and shouldn't be advancing topics without having\nenough concentration myself anyway.\n"}]}