{"thread":{"id":"18763","subject":"Updates to the latest {diff,merge}tool series","startedAt":"2009-04-07T08:21:18Z","lastAt":"2009-04-07T23:32:34Z","messageCount":10,"participants":["David Aguilar","Markus Heidelberg"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"110680","messageId":"1239092483-14973-1-git-send-email-davvid@gmail.com","threadId":"18763","inReplyTo":null,"subject":"Updates to the latest {diff,merge}tool series","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T08:21:18Z","receivedAt":"2009-04-07T08:21:18Z","isPatch":false,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"Here they are.\n\n07/14: Updated usage synopsis\n09/14: Updated diff.tool config.txt documentation\n10/14: The original broke the test suite on Mac OS...\n       Testing {diff,merge}tool.<tool>.path is tricky.\n11/14: This depends on 07/14, so the rebase requires a resend\n14/14: Reworked logic as discussed.\n"},{"id":"110682","messageId":"1239092483-14973-2-git-send-email-davvid@gmail.com","threadId":"18763","inReplyTo":"1239092483-14973-1-git-send-email-davvid@gmail.com","subject":"[PATCH v2 07/14] difftool: add a -y shortcut for --no-prompt","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T08:21:19Z","receivedAt":"2009-04-07T08:21:19Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"This is another consistency cleanup to make git-difftool's options\nmatch git-mergetool.\n\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\n\nIncludes suggestions from Markus\n\n contrib/difftool/git-difftool     |    6 +++---\n contrib/difftool/git-difftool.txt |   36 ++++++++++++++----------------------\n 2 files changed, 17 insertions(+), 25 deletions(-)\n\ndiff --git a/contrib/difftool/git-difftool b/contrib/difftool/git-difftool\nindex 207dd50..8c160e5 100755\n--- a/contrib/difftool/git-difftool\n+++ b/contrib/difftool/git-difftool\n@@ -18,7 +18,7 @@ my $DIR = abs_path(dirname($0));\n sub usage\n {\n \tprint << 'USAGE';\n-usage: git difftool [--tool=<tool>] [--no-prompt] [\"git diff\" options]\n+usage: git difftool [--tool=<tool>] [-y|--no-prompt] [\"git diff\" options]\n USAGE\n \texit 1;\n }\n@@ -60,11 +60,11 @@ sub generate_command\n \t\t\t$ENV{GIT_DIFF_TOOL} = substr($arg, 7);\n \t\t\tnext;\n \t\t}\n-\t\tif ($arg eq '--no-prompt') {\n+\t\tif ($arg eq '-y' || $arg eq '--no-prompt') {\n \t\t\t$ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';\n \t\t\tnext;\n \t\t}\n-\t\tif ($arg eq '-h' or $arg eq '--help') {\n+\t\tif ($arg eq '-h' || $arg eq '--help') {\n \t\t\tusage();\n \t\t}\n \t\tpush @command, $arg;\ndiff --git a/contrib/difftool/git-difftool.txt b/contrib/difftool/git-difftool.txt\nindex 2b7bc03..a00e943 100644\n--- a/contrib/difftool/git-difftool.txt\n+++ b/contrib/difftool/git-difftool.txt\n@@ -3,35 +3,32 @@ git-difftool(1)\n \n NAME\n ----\n-git-difftool - compare changes using common merge tools\n+git-difftool - Show changes using common diff tools\n \n SYNOPSIS\n --------\n-'git difftool' [--tool=<tool>] [--no-prompt] ['git diff' options]\n+'git difftool' [--tool=<tool>] [-y|--no-prompt] [<'git diff' options>]\n \n DESCRIPTION\n -----------\n 'git-difftool' is a git command that allows you to compare and edit files\n-between revisions using common merge tools.  At its most basic level,\n-'git-difftool' does what 'git-mergetool' does but its use is for non-merge\n-situations such as when preparing commits or comparing changes against\n-the index.\n-\n-'git difftool' is a frontend to 'git diff' and accepts the same\n-arguments and options.\n-\n-See linkgit:git-diff[1] for the full list of supported options.\n+between revisions using common diff tools.  'git difftool' is a frontend\n+to 'git-diff' and accepts the same options and arguments.\n \n OPTIONS\n -------\n+-y::\n+--no-prompt::\n+\tDo not prompt before launching a diff tool.\n+\n -t <tool>::\n --tool=<tool>::\n-\tUse the merge resolution program specified by <tool>.\n+\tUse the diff tool specified by <tool>.\n \tValid merge tools are:\n \tkdiff3, kompare, tkdiff, meld, xxdiff, emerge,\n \tvimdiff, gvimdiff, ecmerge, and opendiff\n +\n-If a merge resolution program is not specified, 'git-difftool'\n+If a diff tool is not specified, 'git-difftool'\n will use the configuration variable `diff.tool`.  If the\n configuration variable `diff.tool` is not set, 'git-difftool'\n will pick a suitable default.\n@@ -42,7 +39,7 @@ can configure the absolute path to kdiff3 by setting\n `difftool.kdiff3.path`. Otherwise, 'git-difftool' assumes the\n tool is available in PATH.\n +\n-Instead of running one of the known merge tool programs,\n+Instead of running one of the known diff tools,\n 'git-difftool' can be customized to run an alternative program\n by specifying the command line to invoke in a configuration\n variable `difftool.<tool>.cmd`.\n@@ -56,8 +53,7 @@ is set to the name of the temporary file containing the contents\n of the diff post-image.  `$BASE` is provided for compatibility\n with custom merge tool commands and has the same value as `$LOCAL`.\n \n---no-prompt::\n-\tDo not prompt before launching a diff tool.\n+See linkgit:git-diff[1] for the full list of supported options.\n \n CONFIG VARIABLES\n ----------------\n@@ -65,21 +61,17 @@ CONFIG VARIABLES\n difftool equivalents have not been defined.\n \n diff.tool::\n-\tThe default merge tool to use.\n+\tThe default diff tool to use.\n \n difftool.<tool>.path::\n \tOverride the path for the given tool.  This is useful in case\n \tyour tool is not in the PATH.\n \n difftool.<tool>.cmd::\n-\tSpecify the command to invoke the specified merge tool.\n+\tSpecify the command to invoke the specified diff tool.\n +\n See the `--tool=<tool>` option above for more details.\n \n-merge.keepBackup::\n-\tThe original, unedited file content can be saved to a file with\n-\ta `.orig` extension.  Defaults to `true` (i.e. keep the backup files).\n-\n SEE ALSO\n --------\n linkgit:git-diff[1]::\n-- \n1.6.2.2.414.g81aa9\n"},{"id":"110681","messageId":"1239092483-14973-3-git-send-email-davvid@gmail.com","threadId":"18763","inReplyTo":"1239092483-14973-2-git-send-email-davvid@gmail.com","subject":"[PATCH v2 09/14] difftool: move 'git-difftool' out of contrib","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T08:21:20Z","receivedAt":"2009-04-07T08:21:20Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"This prepares 'git-difftool' and its documentation for\nmainstream use.\n\n'git-difftool-helper' became 'git-difftool--helper'\nsince users should not use it directly.\n\n'git-difftool' was added to the list of commands as\nan ancillaryinterrogator.\n\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\n\nIncludes suggestions from Markus\n\n .gitignore                                         |    2 ++\n Documentation/config.txt                           |   18 ++++++++++++++++++\n .../difftool => Documentation}/git-difftool.txt    |    0\n Makefile                                           |    2 ++\n command-list.txt                                   |    1 +\n .../git-difftool-helper => git-difftool--helper.sh |    2 +-\n contrib/difftool/git-difftool => git-difftool.perl |    6 +++---\n 7 files changed, 27 insertions(+), 4 deletions(-)\n rename {contrib/difftool => Documentation}/git-difftool.txt (100%)\n rename contrib/difftool/git-difftool-helper => git-difftool--helper.sh (98%)\n rename contrib/difftool/git-difftool => git-difftool.perl (92%)\n\ndiff --git a/.gitignore b/.gitignore\nindex 1c57d4c..a36da9d 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -35,6 +35,8 @@ git-diff\n git-diff-files\n git-diff-index\n git-diff-tree\n+git-difftool\n+git-difftool--helper\n git-describe\n git-fast-export\n git-fast-import\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 3afd124..94ef1a6 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -667,6 +667,24 @@ diff.suppressBlankEmpty::\n \tA boolean to inhibit the standard behavior of printing a space\n \tbefore each empty output line. Defaults to false.\n \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` minus \"tortoisemerge\"\n+\tand plus \"kompare\".\n+\n+difftool.<tool>.path::\n+\tOverride the path for the given tool.  This is useful in case\n+\tyour tool is not in the PATH.\n+\n+difftool.<tool>.cmd::\n+\tSpecify the command to invoke the specified diff tool.\n+\tThe specified command is evaluated in shell with the following\n+\tvariables available:  'LOCAL' is set to the name of the temporary\n+\tfile containing the contents of the diff pre-image and 'REMOTE'\n+\tis set to the name of the temporary file containing the contents\n+\tof the diff post-image.\n+\n diff.wordRegex::\n \tA POSIX Extended Regular Expression used to determine what is a \"word\"\n \twhen performing word-by-word difference calculations.  Character\ndiff --git a/contrib/difftool/git-difftool.txt b/Documentation/git-difftool.txt\nsimilarity index 100%\nrename from contrib/difftool/git-difftool.txt\nrename to Documentation/git-difftool.txt\ndiff --git a/Makefile b/Makefile\nindex 7867eac..a80055f 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -277,6 +277,7 @@ TEST_PROGRAMS =\n \n SCRIPT_SH += git-am.sh\n SCRIPT_SH += git-bisect.sh\n+SCRIPT_SH += git-difftool--helper.sh\n SCRIPT_SH += git-filter-branch.sh\n SCRIPT_SH += git-lost-found.sh\n SCRIPT_SH += git-merge-octopus.sh\n@@ -296,6 +297,7 @@ SCRIPT_SH += git-submodule.sh\n SCRIPT_SH += git-web--browse.sh\n \n SCRIPT_PERL += git-add--interactive.perl\n+SCRIPT_PERL += git-difftool.perl\n SCRIPT_PERL += git-archimport.perl\n SCRIPT_PERL += git-cvsexportcommit.perl\n SCRIPT_PERL += git-cvsimport.perl\ndiff --git a/command-list.txt b/command-list.txt\nindex 3583a33..fb03a2e 100644\n--- a/command-list.txt\n+++ b/command-list.txt\n@@ -33,6 +33,7 @@ git-diff                                mainporcelain common\n git-diff-files                          plumbinginterrogators\n git-diff-index                          plumbinginterrogators\n git-diff-tree                           plumbinginterrogators\n+git-difftool                            ancillaryinterrogators\n git-fast-export\t\t\t\tancillarymanipulators\n git-fast-import\t\t\t\tancillarymanipulators\n git-fetch                               mainporcelain common\ndiff --git a/contrib/difftool/git-difftool-helper b/git-difftool--helper.sh\nsimilarity index 98%\nrename from contrib/difftool/git-difftool-helper\nrename to git-difftool--helper.sh\nindex 4b0daec..fc61416 100755\n--- a/contrib/difftool/git-difftool-helper\n+++ b/git-difftool--helper.sh\n@@ -1,5 +1,5 @@\n #!/bin/sh\n-# git-difftool-helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher.\n+# git-difftool--helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher.\n # This script is typically launched by using the 'git difftool'\n # convenience command.\n #\ndiff --git a/contrib/difftool/git-difftool b/git-difftool.perl\nsimilarity index 92%\nrename from contrib/difftool/git-difftool\nrename to git-difftool.perl\nindex 8c160e5..8857ac8 100755\n--- a/contrib/difftool/git-difftool\n+++ b/git-difftool.perl\n@@ -2,9 +2,9 @@\n # Copyright (c) 2009 David Aguilar\n #\n # This is a wrapper around the GIT_EXTERNAL_DIFF-compatible\n-# git-difftool-helper script.  This script exports\n+# git-difftool--helper script.  This script exports\n # GIT_EXTERNAL_DIFF and GIT_PAGER for use by git, and\n-# GIT_DIFFTOOL_NO_PROMPT and GIT_DIFF_TOOL for use by git-difftool-helper.\n+# GIT_DIFFTOOL_NO_PROMPT and GIT_DIFF_TOOL for use by git-difftool--helper.\n # Any arguments that are unknown to this script are forwarded to 'git diff'.\n \n use strict;\n@@ -27,7 +27,7 @@ sub setup_environment\n {\n \t$ENV{PATH} = \"$DIR:$ENV{PATH}\";\n \t$ENV{GIT_PAGER} = '';\n-\t$ENV{GIT_EXTERNAL_DIFF} = 'git-difftool-helper';\n+\t$ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper';\n }\n \n sub exe\n-- \n1.6.2.2.414.g81aa9\n"},{"id":"110685","messageId":"1239092483-14973-4-git-send-email-davvid@gmail.com","threadId":"18763","inReplyTo":"1239092483-14973-3-git-send-email-davvid@gmail.com","subject":"[PATCH v2 10/14] difftool: add various git-difftool tests","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T08:21:21Z","receivedAt":"2009-04-07T08:21:21Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"t7800-difftool.sh tests the various command-line flags,\ngit-config variables, and environment settings supported by\ngit-difftool.\n\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\n\nThe original broke the test suite on Mac OS.\nTesting difftool.<path>.path is hard without internal support\nfor a fake tool.\n\n t/t7800-difftool.sh |  139 +++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 139 insertions(+), 0 deletions(-)\n create mode 100755 t/t7800-difftool.sh\n\ndiff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh\nnew file mode 100755\nindex 0000000..ceef84b\n--- /dev/null\n+++ b/t/t7800-difftool.sh\n@@ -0,0 +1,139 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2009 David Aguilar\n+#\n+\n+test_description='git-difftool\n+\n+Testing basic diff tool invocation\n+'\n+\n+. ./test-lib.sh\n+\n+remove_config_vars()\n+{\n+\t# Unset all config variables used by git-difftool\n+\tgit config --unset diff.tool\n+\tgit config --unset difftool.test-tool.cmd\n+\tgit config --unset merge.tool\n+\tgit config --unset mergetool.test-tool.cmd\n+\treturn 0\n+}\n+\n+restore_test_defaults()\n+{\n+\t# Restores the test defaults used by several tests\n+\tremove_config_vars\n+\tunset GIT_DIFF_TOOL\n+\tunset GIT_MERGE_TOOL\n+\tunset GIT_DIFFTOOL_NO_PROMPT\n+\tgit config diff.tool test-tool &&\n+\tgit config difftool.test-tool.cmd 'cat $LOCAL'\n+}\n+\n+# Create a file on master and change it on branch\n+test_expect_success 'setup' '\n+\techo master >file &&\n+\tgit add file &&\n+\tgit commit -m \"added file\" &&\n+\n+\tgit checkout -b branch master &&\n+\techo branch >file &&\n+\tgit commit -a -m \"branch changed file\" &&\n+\tgit checkout master\n+'\n+\n+# Configure a custom difftool.<tool>.cmd and use it\n+test_expect_success 'custom commands' '\n+\trestore_test_defaults &&\n+\tgit config difftool.test-tool.cmd \"cat \\$REMOTE\" &&\n+\n+\tdiff=$(git difftool --no-prompt branch) &&\n+\ttest \"$diff\" = \"master\" &&\n+\n+\trestore_test_defaults &&\n+\tdiff=$(git difftool --no-prompt branch) &&\n+\ttest \"$diff\" = \"branch\"\n+'\n+\n+# Ensures that git-difftool ignores bogus --tool values\n+test_expect_success 'difftool ignores bad --tool values' '\n+\tdiff=$(git difftool --no-prompt --tool=bogus-tool branch)\n+\ttest \"$?\" = 1 &&\n+\ttest \"$diff\" = \"\"\n+'\n+\n+# Specify the diff tool using $GIT_DIFF_TOOL\n+test_expect_success 'GIT_DIFF_TOOL variable' '\n+\tgit config --unset diff.tool\n+\tGIT_DIFF_TOOL=test-tool &&\n+\texport GIT_DIFF_TOOL &&\n+\n+\tdiff=$(git difftool --no-prompt branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\trestore_test_defaults\n+'\n+\n+# Test the $GIT_*_TOOL variables and ensure\n+# that $GIT_DIFF_TOOL always wins unless --tool is specified\n+test_expect_success 'GIT_DIFF_TOOL overrides' '\n+\tgit config diff.tool bogus-tool &&\n+\tgit config merge.tool bogus-tool &&\n+\n+\tGIT_MERGE_TOOL=test-tool &&\n+\texport GIT_MERGE_TOOL &&\n+\tdiff=$(git difftool --no-prompt branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\tunset GIT_MERGE_TOOL &&\n+\n+\tGIT_MERGE_TOOL=bogus-tool &&\n+\tGIT_DIFF_TOOL=test-tool &&\n+\texport GIT_MERGE_TOOL &&\n+\texport GIT_DIFF_TOOL &&\n+\n+\tdiff=$(git difftool --no-prompt branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\tGIT_DIFF_TOOL=bogus-tool &&\n+\texport GIT_DIFF_TOOL &&\n+\n+\tdiff=$(git difftool --no-prompt --tool=test-tool branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\trestore_test_defaults\n+'\n+\n+# Test that we don't have to pass --no-prompt to difftool\n+# when $GIT_DIFFTOOL_NO_PROMPT is true\n+test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' '\n+\tGIT_DIFFTOOL_NO_PROMPT=true &&\n+\texport GIT_DIFFTOOL_NO_PROMPT &&\n+\n+\tdiff=$(git difftool branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\trestore_test_defaults\n+'\n+\n+# git-difftool falls back to git-mergetool config variables\n+# so test that behavior here\n+test_expect_success 'difftool + mergetool config variables' '\n+\tremove_config_vars\n+\tgit config merge.tool test-tool &&\n+\tgit config mergetool.test-tool.cmd \"cat \\$LOCAL\" &&\n+\n+\tdiff=$(git difftool --no-prompt branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\t# set merge.tool to something bogus, diff.tool to test-tool\n+\tgit config merge.tool bogus-tool &&\n+\tgit config diff.tool test-tool &&\n+\n+\tdiff=$(git difftool --no-prompt branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\trestore_test_defaults\n+'\n+\n+test_done\n-- \n1.6.2.2.414.g81aa9\n"},{"id":"110683","messageId":"1239092483-14973-5-git-send-email-davvid@gmail.com","threadId":"18763","inReplyTo":"1239092483-14973-4-git-send-email-davvid@gmail.com","subject":"[PATCH v2 11/14] difftool: add support for a difftool.prompt config variable","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T08:21:22Z","receivedAt":"2009-04-07T08:21:22Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"difftool now supports difftool.prompt so that users do not have to\npass --no-prompt or hit enter each time a diff tool is launched.\nThe --prompt flag overrides the configuration variable.\n\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\n\nThis one had to be resent since rewriting #9 would\nhave caused a conflict in here.\n\n Documentation/config.txt       |    3 ++\n Documentation/git-difftool.txt |   10 +++++-\n git-difftool--helper.sh        |   10 +++++-\n git-difftool.perl              |   15 +++++++--\n t/t7800-difftool.sh            |   64 ++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 96 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex e8ff0be..6e29623 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -684,6 +684,9 @@ difftool.<tool>.cmd::\n \tis set to the name of the temporary file containing the contents\n \tof the diff post-image.\n \n+difftool.prompt::\n+\tPrompt before each invocation of the diff tool.\n+\n diff.wordRegex::\n \tA POSIX Extended Regular Expression used to determine what is a \"word\"\n \twhen performing word-by-word difference calculations.  Character\ndiff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt\nindex af68466..15b247b 100644\n--- a/Documentation/git-difftool.txt\n+++ b/Documentation/git-difftool.txt\n@@ -7,7 +7,7 @@ git-difftool - Show changes using common diff tools\n \n SYNOPSIS\n --------\n-'git difftool' [--tool=<tool>] [-y|--no-prompt] [<'git diff' options>]\n+'git difftool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<'git diff' options>]\n \n DESCRIPTION\n -----------\n@@ -21,6 +21,11 @@ OPTIONS\n --no-prompt::\n \tDo not prompt before launching a diff tool.\n \n+--prompt::\n+\tPrompt before each invocation of the diff tool.\n+\tThis is the default behaviour; the option is provided to\n+\toverride any configuration settings.\n+\n -t <tool>::\n --tool=<tool>::\n \tUse the diff tool specified by <tool>.\n@@ -72,6 +77,9 @@ difftool.<tool>.cmd::\n +\n See the `--tool=<tool>` option above for more details.\n \n+difftool.prompt::\n+\tPrompt before each invocation of the diff tool.\n+\n SEE ALSO\n --------\n linkgit:git-diff[1]::\ndiff --git a/git-difftool--helper.sh b/git-difftool--helper.sh\nindex fc61416..f3c27d8 100755\n--- a/git-difftool--helper.sh\n+++ b/git-difftool--helper.sh\n@@ -5,9 +5,15 @@\n #\n # Copyright (c) 2009 David Aguilar\n \n-# Set GIT_DIFFTOOL_NO_PROMPT to bypass the per-file prompt.\n+# difftool.prompt controls the default prompt/no-prompt behavior\n+# and is overridden with $GIT_DIFFTOOL*_PROMPT.\n should_prompt () {\n-\ttest -z \"$GIT_DIFFTOOL_NO_PROMPT\"\n+\tprompt=$(git config --bool difftool.prompt || echo true)\n+\tif test \"$prompt\" = true; then\n+\t\ttest -z \"$GIT_DIFFTOOL_NO_PROMPT\"\n+\telse\n+\t\ttest -n \"$GIT_DIFFTOOL_PROMPT\"\n+\tfi\n }\n \n # This function prepares temporary files and launches the appropriate\ndiff --git a/git-difftool.perl b/git-difftool.perl\nindex 8857ac8..948ff7f 100755\n--- a/git-difftool.perl\n+++ b/git-difftool.perl\n@@ -2,9 +2,12 @@\n # Copyright (c) 2009 David Aguilar\n #\n # This is a wrapper around the GIT_EXTERNAL_DIFF-compatible\n-# git-difftool--helper script.  This script exports\n-# GIT_EXTERNAL_DIFF and GIT_PAGER for use by git, and\n-# GIT_DIFFTOOL_NO_PROMPT and GIT_DIFF_TOOL for use by git-difftool--helper.\n+# git-difftool--helper script.\n+#\n+# This script exports GIT_EXTERNAL_DIFF and GIT_PAGER for use by git.\n+# GIT_DIFFTOOL_NO_PROMPT, GIT_DIFFTOOL_PROMPT, and GIT_DIFF_TOOL\n+# are exported for use by git-difftool--helper.\n+#\n # Any arguments that are unknown to this script are forwarded to 'git diff'.\n \n use strict;\n@@ -62,6 +65,12 @@ sub generate_command\n \t\t}\n \t\tif ($arg eq '-y' || $arg eq '--no-prompt') {\n \t\t\t$ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';\n+\t\t\tdelete $ENV{GIT_DIFFTOOL_PROMPT};\n+\t\t\tnext;\n+\t\t}\n+\t\tif ($arg eq '--prompt') {\n+\t\t\t$ENV{GIT_DIFFTOOL_PROMPT} = 'true';\n+\t\t\tdelete $ENV{GIT_DIFFTOOL_NO_PROMPT};\n \t\t\tnext;\n \t\t}\n \t\tif ($arg eq '-h' || $arg eq '--help') {\ndiff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh\nindex 85946d9..0b263ea 100755\n--- a/t/t7800-difftool.sh\n+++ b/t/t7800-difftool.sh\n@@ -15,6 +15,7 @@ remove_config_vars()\n \t# Unset all config variables used by git-difftool\n \tgit config --unset diff.tool\n \tgit config --unset difftool.test-tool.cmd\n+\tgit config --unset difftool.prompt\n \tgit config --unset merge.tool\n \tgit config --unset mergetool.test-tool.cmd\n \treturn 0\n@@ -26,11 +27,18 @@ restore_test_defaults()\n \tremove_config_vars\n \tunset GIT_DIFF_TOOL\n \tunset GIT_MERGE_TOOL\n+\tunset GIT_DIFFTOOL_PROMPT\n \tunset GIT_DIFFTOOL_NO_PROMPT\n \tgit config diff.tool test-tool &&\n \tgit config difftool.test-tool.cmd 'cat $LOCAL'\n }\n \n+prompt_given()\n+{\n+\tprompt=\"$1\"\n+\ttest \"$prompt\" = \"Hit return to launch 'test-tool': branch\"\n+}\n+\n # Create a file on master and change it on branch\n test_expect_success 'setup' '\n \techo master >file &&\n@@ -116,6 +124,62 @@ test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' '\n \trestore_test_defaults\n '\n \n+# git-difftool supports the difftool.prompt variable.\n+# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false\n+test_expect_success 'GIT_DIFFTOOL_PROMPT variable' '\n+\tgit config difftool.prompt false &&\n+\tGIT_DIFFTOOL_PROMPT=true &&\n+\texport GIT_DIFFTOOL_PROMPT &&\n+\n+\tprompt=$(echo | git difftool --prompt branch | tail -1) &&\n+\tprompt_given \"$prompt\" &&\n+\n+\trestore_test_defaults\n+'\n+\n+# Test that we don't have to pass --no-prompt when difftool.prompt is false\n+test_expect_success 'difftool.prompt config variable is false' '\n+\tgit config difftool.prompt false &&\n+\n+\tdiff=$(git difftool branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\trestore_test_defaults\n+'\n+\n+# Test that the -y flag can override difftool.prompt = true\n+test_expect_success 'difftool.prompt can overridden with -y' '\n+\tgit config difftool.prompt true &&\n+\n+\tdiff=$(git difftool -y branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\trestore_test_defaults\n+'\n+\n+# Test that the --prompt flag can override difftool.prompt = false\n+test_expect_success 'difftool.prompt can overridden with --prompt' '\n+\tgit config difftool.prompt false &&\n+\n+\tprompt=$(echo | git difftool --prompt branch | tail -1) &&\n+\tprompt_given \"$prompt\" &&\n+\n+\trestore_test_defaults\n+'\n+\n+# Test that the last flag passed on the command-line wins\n+test_expect_success 'difftool last flag wins' '\n+\tdiff=$(git difftool --prompt --no-prompt branch) &&\n+\ttest \"$diff\" = \"branch\" &&\n+\n+\trestore_test_defaults &&\n+\n+\tprompt=$(echo | git difftool --no-prompt --prompt branch | tail -1) &&\n+\tprompt_given \"$prompt\" &&\n+\n+\trestore_test_defaults\n+'\n+\n # git-difftool falls back to git-mergetool config variables\n # so test that behavior here\n test_expect_success 'difftool + mergetool config variables' '\n-- \n1.6.2.2.414.g81aa9\n"},{"id":"110684","messageId":"1239092483-14973-6-git-send-email-davvid@gmail.com","threadId":"18763","inReplyTo":"1239092483-14973-5-git-send-email-davvid@gmail.com","subject":"[PATCH v3 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T08:21:23Z","receivedAt":"2009-04-07T08:21:23Z","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 suggestions from Markus.\nWe also moved opendiff up to the front so that it's\npreferred when on Mac OS.\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                |  387 ++++++++++++++++++++++++++++++++++\n git-mergetool.sh                     |  224 ++------------------\n 6 files changed, 467 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..a2f45ee\n--- /dev/null\n+++ b/git-mergetool--lib.sh\n@@ -0,0 +1,387 @@\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 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+\t\tstatus=0\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+\tif diff_mode; then\n+\t\tstatus=0\n+\t\tbase_present=\"false\"\n+\tfi\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\tfi\n+\t\t\tstatus=$?\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+\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.2.2.414.g81aa9\n"},{"id":"110719","messageId":"200904071952.21109.markus.heidelberg@web.de","threadId":"18763","inReplyTo":"1239092483-14973-4-git-send-email-davvid@gmail.com","subject":"Re: [PATCH v2 10/14] difftool: add various git-difftool tests","fromName":"Markus Heidelberg","fromEmail":"markus.heidelberg@web.de","sentAt":"2009-04-07T17:52:19Z","receivedAt":"2009-04-07T17:52:19Z","isPatch":true,"sender":{"key":"markus.heidelberg@web.de","avatar":"https://avatars.githubusercontent.com/u/6334512?v=4"},"body":"David Aguilar, 07.04.2009:\n> t7800-difftool.sh tests the various command-line flags,\n> git-config variables, and environment settings supported by\n> git-difftool.\n> \n> Signed-off-by: David Aguilar <davvid@gmail.com>\n> ---\n> \n> The original broke the test suite on Mac OS.\n> Testing difftool.<path>.path is hard without internal support\n> for a fake tool.\n\nMac OS doesn't have the \"echo\" command?\n"},{"id":"110723","messageId":"200904072011.15503.markus.heidelberg@web.de","threadId":"18763","inReplyTo":"1239092483-14973-6-git-send-email-davvid@gmail.com","subject":"Re: [PATCH v3 14/14] difftool/mergetool: refactor commands to use git-mergetool--lib","fromName":"Markus Heidelberg","fromEmail":"markus.heidelberg@web.de","sentAt":"2009-04-07T18:11:14Z","receivedAt":"2009-04-07T18:11:14Z","isPatch":true,"sender":{"key":"markus.heidelberg@web.de","avatar":"https://avatars.githubusercontent.com/u/6334512?v=4"},"body":"David Aguilar, 07.04.2009:\n> This consolidates the common functionality from git-mergetool and\n> git-difftool--helper into a single git-mergetool--lib scriptlet.\n> \n> Signed-off-by: David Aguilar <davvid@gmail.com>\n> ---\n> \n> Includes suggestions from Markus.\n> We also moved opendiff up to the front so that it's\n> preferred when on Mac OS.\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                |  387 ++++++++++++++++++++++++++++++++++\n>  git-mergetool.sh                     |  224 ++------------------\n>  6 files changed, 467 insertions(+), 388 deletions(-)\n>  create mode 100644 Documentation/git-mergetool--lib.txt\n>  create mode 100644 git-mergetool--lib.sh\n> \n> diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh\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> +\t\tstatus=0\n> +\tfi\n> +}\n\nThis function is now only called when $merge_mode is set.\n\n> +run_merge_tool () {\n> +\tbase_present=\"$2\"\n> +\tif diff_mode; then\n> +\t\tstatus=0\n> +\t\tbase_present=\"false\"\n> +\tfi\n\n$base_present also is only used when $merge_mode is set. And I think we\ndon't need to set status=0 conditionally then.\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\nLooks nice.\n\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\tfi\n> +\t\t\tstatus=$?\n\n\"fi\" and \"status=$?\" have to be swapped, else it overwrites the value\nset by check_unchanged():\n+\t\t\t\tstatus=$?\n+\t\t\tfi\n\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\nThe setting of $tools looks a bit weird. Maybe we can just ignore the\nadditional spaces here...\n\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\n...and delete them here with something like\n    sed -e 's/ \\+/ /g'\nto have it look nice here?:\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"},{"id":"110754","messageId":"20090407223834.GA71200@gmail.com","threadId":"18763","inReplyTo":"200904071952.21109.markus.heidelberg@web.de","subject":"Re: [PATCH v2 10/14] difftool: add various git-difftool tests","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T22:38:35Z","receivedAt":"2009-04-07T22:38:35Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"On  0, Markus Heidelberg <markus.heidelberg@web.de> wrote:\n> David Aguilar, 07.04.2009:\n> > t7800-difftool.sh tests the various command-line flags,\n> > git-config variables, and environment settings supported by\n> > git-difftool.\n> > \n> > Signed-off-by: David Aguilar <davvid@gmail.com>\n> > ---\n> > \n> > The original broke the test suite on Mac OS.\n> > Testing difftool.<path>.path is hard without internal support\n> > for a fake tool.\n> \n> Mac OS doesn't have the \"echo\" command?\n> \n\nHmmm maybe the thing that validates the merge tool isn't\nusing the $merge_tool_path when validating.  All I know is that\nit was failing so figured I could add it again later.\n\n-- \n\t\tDavid\n"},{"id":"110759","messageId":"20090407233233.GA71372@gmail.com","threadId":"18763","inReplyTo":"200904071952.21109.markus.heidelberg@web.de","subject":"Re: [PATCH v2 10/14] difftool: add various git-difftool tests","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2009-04-07T23:32:34Z","receivedAt":"2009-04-07T23:32:34Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"On  0, Markus Heidelberg <markus.heidelberg@web.de> wrote:\n> David Aguilar, 07.04.2009:\n> > t7800-difftool.sh tests the various command-line flags,\n> > git-config variables, and environment settings supported by\n> > git-difftool.\n> > \n> > Signed-off-by: David Aguilar <davvid@gmail.com>\n> > ---\n> > \n> > The original broke the test suite on Mac OS.\n> > Testing difftool.<path>.path is hard without internal support\n> > for a fake tool.\n> \n> Mac OS doesn't have the \"echo\" command?\n> \n\nI figured it out.\nThe test was using wc -l.\nOn Mac OS the results are formatted differently (leading spaces)\nso I modified the test to be more robust.\n\nSee [PATCH v3 10/14].\n\n-- \n\t\tDavid\n"}]}