{"thread":{"id":"12251","subject":"[PATCH 1/4] Tidy up git mergetool's backup file behaviour","startedAt":"2008-02-21T23:30:02Z","lastAt":"2008-02-21T23:31:56Z","messageCount":4,"participants":["Charles Bailey"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"69535","messageId":"e6d984bbbb5d4dab54c38caa5c0c71b060d69156.1203636096.git.charles@hashpling.org","threadId":"12251","inReplyTo":null,"subject":"[PATCH 1/4] Tidy up git mergetool's backup file behaviour","fromName":"Charles Bailey","fromEmail":"charles@hashpling.org","sentAt":"2008-02-21T23:30:02Z","receivedAt":"2008-02-21T23:30:02Z","isPatch":true,"sender":{"key":"charles@hashpling.org","avatar":"https://avatars.githubusercontent.com/u/1668475?v=4"},"body":"Currently a backup pre-merge file with conflict markers is sometimes\nkept with a .orig extenstion and sometimes removed depending on the\nparticular merge tool used.\n\nThis patch makes the handling consistent across all merge tools and\nconfigurable via a new mergetool.keepBackup config variable\n\nSigned-off-by: Charles Bailey <charles@hashpling.org>\n---\n\nI'm resending this series with result of all the previous contents\nintegrated. This is, though, still the 'eval' version of the patch\nsimply because it is significantly easier to implement and is not\nsignificantly worse than any of the other suggested implementations in\nany particular way.\n\n Documentation/config.txt |    6 ++++++\n git-mergetool.sh         |   25 +++++++++++++------------\n 2 files changed, 19 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 7b67671..4e17fd2 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -769,6 +769,12 @@ mergetool.<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+mergetool.keepBackup::\n+\tAfter performing a merge, the original file with conflict markers\n+\tcan be saved as a file with a `.orig` extension.  If this variable\n+\tis set to `false` then this file is not preserved.  Defaults to\n+\t`true` (i.e. keep the backup files).\n+\n pack.window::\n \tThe size of the window used by linkgit:git-pack-objects[1] when no\n \twindow size is given on the command line. Defaults to 10.\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex cbbb707..e27bb7b 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -201,7 +201,6 @@ merge_file () {\n \t\t    -o \"$path\" -- \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\n \t    fi\n \t    status=$?\n-\t    remove_backup\n \t    ;;\n \ttkdiff)\n \t    if base_present ; then\n@@ -210,20 +209,17 @@ merge_file () {\n \t\t\"$merge_tool_path\" -o \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n \t    fi\n \t    status=$?\n-\t    save_backup\n \t    ;;\n \tmeld|vimdiff)\n \t    touch \"$BACKUP\"\n \t    \"$merge_tool_path\" -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n \t    check_unchanged\n-\t    save_backup\n \t    ;;\n \tgvimdiff)\n-\t\ttouch \"$BACKUP\"\n-\t\t\"$merge_tool_path\" -f -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n-\t\tcheck_unchanged\n-\t\tsave_backup\n-\t\t;;\n+\t    touch \"$BACKUP\"\n+\t    \"$merge_tool_path\" -f -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n+\t    check_unchanged\n+\t    ;;\n \txxdiff)\n \t    touch \"$BACKUP\"\n \t    if base_present ; then\n@@ -240,7 +236,6 @@ merge_file () {\n \t\t    --merged-file \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n \t    fi\n \t    check_unchanged\n-\t    save_backup\n \t    ;;\n \topendiff)\n \t    touch \"$BACKUP\"\n@@ -250,7 +245,6 @@ merge_file () {\n \t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" -merge \"$path\" | cat\n \t    fi\n \t    check_unchanged\n-\t    save_backup\n \t    ;;\n \tecmerge)\n \t    touch \"$BACKUP\"\n@@ -260,7 +254,6 @@ merge_file () {\n \t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" --mode=merge2 --to=\"$path\"\n \t    fi\n \t    check_unchanged\n-\t    save_backup\n \t    ;;\n \temerge)\n \t    if base_present ; then\n@@ -269,7 +262,6 @@ merge_file () {\n \t\t\"$merge_tool_path\" -f emerge-files-command \"$LOCAL\" \"$REMOTE\" \"$(basename \"$path\")\"\n \t    fi\n \t    status=$?\n-\t    save_backup\n \t    ;;\n     esac\n     if test \"$status\" -ne 0; then\n@@ -277,6 +269,13 @@ merge_file () {\n \tmv -- \"$BACKUP\" \"$path\"\n \texit 1\n     fi\n+\n+    if test \"$merge_keep_backup\" = \"true\"; then\n+\tmv -- \"$BACKUP\" \"$path.orig\"\n+    else\n+\trm -- \"$BACKUP\"\n+    fi\n+\n     git add -- \"$path\"\n     cleanup_temp_files\n }\n@@ -380,6 +379,8 @@ else\n \n     init_merge_tool_path \"$merge_tool\"\n \n+    merge_keep_backup=\"$(git config --bool merge.keepBackup || echo true)\"\n+\n     if ! 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-- \n1.5.4.2.133.g3d51e\n\n\n-- \nCharles Bailey\nhttp://ccgi.hashpling.plus.com/blog/\n"},{"id":"69536","messageId":"73391eb9efe812da00fe049b97a13d28a5605777.1203636096.git.charles@hashpling.org","threadId":"12251","inReplyTo":"e6d984bbbb5d4dab54c38caa5c0c71b060d69156.1203636096.git.charles@hashpling.org","subject":"[PATCH 2/4] Changed an internal variable of mergetool to support custom commands","fromName":"Charles Bailey","fromEmail":"charles@hashpling.org","sentAt":"2008-02-21T23:30:34Z","receivedAt":"2008-02-21T23:30:34Z","isPatch":true,"sender":{"key":"charles@hashpling.org","avatar":"https://avatars.githubusercontent.com/u/1668475?v=4"},"body":"The variable $path changes to $MERGED so that it is more consistent\nwith $BASE, $LOCAL and $REMOTE for future custom command lines.\n\nSigned-off-by: Charles Bailey <charles@hashpling.org>\n---\n git-mergetool.sh |  102 +++++++++++++++++++++++++++---------------------------\n 1 files changed, 51 insertions(+), 51 deletions(-)\n\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex e27bb7b..d3dd7f8 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -34,7 +34,7 @@ base_present () {\n \n cleanup_temp_files () {\n     if test \"$1\" = --save-backup ; then\n-\tmv -- \"$BACKUP\" \"$path.orig\"\n+\tmv -- \"$BACKUP\" \"$MERGED.orig\"\n \trm -f -- \"$LOCAL\" \"$REMOTE\" \"$BASE\"\n     else\n \trm -f -- \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$BACKUP\"\n@@ -67,14 +67,14 @@ resolve_symlink_merge () {\n \tread ans\n \tcase \"$ans\" in\n \t    [lL]*)\n-\t\tgit checkout-index -f --stage=2 -- \"$path\"\n-\t\tgit add -- \"$path\"\n+\t\tgit checkout-index -f --stage=2 -- \"$MERGED\"\n+\t\tgit add -- \"$MERGED\"\n \t\tcleanup_temp_files --save-backup\n \t\treturn\n \t\t;;\n \t    [rR]*)\n-\t\tgit checkout-index -f --stage=3 -- \"$path\"\n-\t\tgit add -- \"$path\"\n+\t\tgit checkout-index -f --stage=3 -- \"$MERGED\"\n+\t\tgit add -- \"$MERGED\"\n \t\tcleanup_temp_files --save-backup\n \t\treturn\n \t\t;;\n@@ -95,12 +95,12 @@ resolve_deleted_merge () {\n \tread ans\n \tcase \"$ans\" in\n \t    [mMcC]*)\n-\t\tgit add -- \"$path\"\n+\t\tgit add -- \"$MERGED\"\n \t\tcleanup_temp_files --save-backup\n \t\treturn\n \t\t;;\n \t    [dD]*)\n-\t\tgit rm -- \"$path\" > /dev/null\n+\t\tgit rm -- \"$MERGED\" > /dev/null\n \t\tcleanup_temp_files\n \t\treturn\n \t\t;;\n@@ -112,11 +112,11 @@ resolve_deleted_merge () {\n }\n \n check_unchanged () {\n-    if test \"$path\" -nt \"$BACKUP\" ; then\n+    if test \"$MERGED\" -nt \"$BACKUP\" ; then\n \tstatus=0;\n     else\n \twhile true; do\n-\t    echo \"$path seems unchanged.\"\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@@ -129,7 +129,7 @@ check_unchanged () {\n \n save_backup () {\n     if test \"$status\" -eq 0; then\n-\tmv -- \"$BACKUP\" \"$path.orig\"\n+\tmv -- \"$BACKUP\" \"$MERGED.orig\"\n     fi\n }\n \n@@ -140,37 +140,37 @@ remove_backup () {\n }\n \n merge_file () {\n-    path=\"$1\"\n+    MERGED=\"$1\"\n \n-    f=`git ls-files -u -- \"$path\"`\n+    f=`git ls-files -u -- \"$MERGED\"`\n     if test -z \"$f\" ; then\n-\tif test ! -f \"$path\" ; then\n-\t    echo \"$path: file not found\"\n+\tif test ! -f \"$MERGED\" ; then\n+\t    echo \"$MERGED: file not found\"\n \telse\n-\t    echo \"$path: file does not need merging\"\n+\t    echo \"$MERGED: file does not need merging\"\n \tfi\n \texit 1\n     fi\n \n-    ext=\"$$$(expr \"$path\" : '.*\\(\\.[^/]*\\)$')\"\n-    BACKUP=\"$path.BACKUP.$ext\"\n-    LOCAL=\"$path.LOCAL.$ext\"\n-    REMOTE=\"$path.REMOTE.$ext\"\n-    BASE=\"$path.BASE.$ext\"\n+    ext=\"$$$(expr \"$MERGED\" : '.*\\(\\.[^/]*\\)$')\"\n+    BACKUP=\"$MERGED.BACKUP.$ext\"\n+    LOCAL=\"$MERGED.LOCAL.$ext\"\n+    REMOTE=\"$MERGED.REMOTE.$ext\"\n+    BASE=\"$MERGED.BASE.$ext\"\n \n-    mv -- \"$path\" \"$BACKUP\"\n-    cp -- \"$BACKUP\" \"$path\"\n+    mv -- \"$MERGED\" \"$BACKUP\"\n+    cp -- \"$BACKUP\" \"$MERGED\"\n \n-    base_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==1) print $1;}'`\n-    local_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==2) print $1;}'`\n-    remote_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==3) print $1;}'`\n+    base_mode=`git ls-files -u -- \"$MERGED\" | awk '{if ($3==1) print $1;}'`\n+    local_mode=`git ls-files -u -- \"$MERGED\" | awk '{if ($3==2) print $1;}'`\n+    remote_mode=`git ls-files -u -- \"$MERGED\" | awk '{if ($3==3) print $1;}'`\n \n-    base_present   && git cat-file blob \":1:$prefix$path\" >\"$BASE\" 2>/dev/null\n-    local_present  && git cat-file blob \":2:$prefix$path\" >\"$LOCAL\" 2>/dev/null\n-    remote_present && git cat-file blob \":3:$prefix$path\" >\"$REMOTE\" 2>/dev/null\n+    base_present   && git cat-file blob \":1:$prefix$MERGED\" >\"$BASE\" 2>/dev/null\n+    local_present  && git cat-file blob \":2:$prefix$MERGED\" >\"$LOCAL\" 2>/dev/null\n+    remote_present && git cat-file blob \":3:$prefix$MERGED\" >\"$REMOTE\" 2>/dev/null\n \n     if test -z \"$local_mode\" -o -z \"$remote_mode\"; then\n-\techo \"Deleted merge conflict for '$path':\"\n+\techo \"Deleted merge conflict for '$MERGED':\"\n \tdescribe_file \"$local_mode\" \"local\" \"$LOCAL\"\n \tdescribe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n \tresolve_deleted_merge\n@@ -178,14 +178,14 @@ merge_file () {\n     fi\n \n     if is_symlink \"$local_mode\" || is_symlink \"$remote_mode\"; then\n-\techo \"Symbolic link merge conflict for '$path':\"\n+\techo \"Symbolic link merge conflict for '$MERGED':\"\n \tdescribe_file \"$local_mode\" \"local\" \"$LOCAL\"\n \tdescribe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n \tresolve_symlink_merge\n \treturn\n     fi\n \n-    echo \"Normal merge conflict for '$path':\"\n+    echo \"Normal merge conflict for '$MERGED':\"\n     describe_file \"$local_mode\" \"local\" \"$LOCAL\"\n     describe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n     printf \"Hit return to start merge resolution tool (%s): \" \"$merge_tool\"\n@@ -194,30 +194,30 @@ merge_file () {\n     case \"$merge_tool\" in\n \tkdiff3)\n \t    if base_present ; then\n-\t\t(\"$merge_tool_path\" --auto --L1 \"$path (Base)\" --L2 \"$path (Local)\" --L3 \"$path (Remote)\" \\\n-\t\t    -o \"$path\" -- \"$BASE\" \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\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 \"$path (Local)\" --L2 \"$path (Remote)\" \\\n-\t\t    -o \"$path\" -- \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\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 \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n+\t\t\"$merge_tool_path\" -a \"$BASE\" -o \"$MERGED\" -- \"$LOCAL\" \"$REMOTE\"\n \t    else\n-\t\t\"$merge_tool_path\" -o \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n+\t\t\"$merge_tool_path\" -o \"$MERGED\" -- \"$LOCAL\" \"$REMOTE\"\n \t    fi\n \t    status=$?\n \t    ;;\n \tmeld|vimdiff)\n \t    touch \"$BACKUP\"\n-\t    \"$merge_tool_path\" -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n+\t    \"$merge_tool_path\" -- \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n \t    check_unchanged\n \t    ;;\n \tgvimdiff)\n \t    touch \"$BACKUP\"\n-\t    \"$merge_tool_path\" -f -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n+\t    \"$merge_tool_path\" -f -- \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n \t    check_unchanged\n \t    ;;\n \txxdiff)\n@@ -227,56 +227,56 @@ merge_file () {\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 \"$path\" -- \"$LOCAL\" \"$BASE\" \"$REMOTE\"\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 \"$path\" -- \"$LOCAL\" \"$REMOTE\"\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 \"$path\" | cat\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 \"$path\" | cat\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\" --mode=merge3 --to=\"$path\"\n+\t\t\"$merge_tool_path\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" --mode=merge3 --to=\"$MERGED\"\n \t    else\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" --mode=merge2 --to=\"$path\"\n+\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" --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 \"$path\")\"\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 \"$path\")\"\n+\t\t\"$merge_tool_path\" -f emerge-files-command \"$LOCAL\" \"$REMOTE\" \"$(basename \"$MERGED\")\"\n \t    fi\n \t    status=$?\n \t    ;;\n     esac\n     if test \"$status\" -ne 0; then\n-\techo \"merge of $path failed\" 1>&2\n-\tmv -- \"$BACKUP\" \"$path\"\n+\techo \"merge of $MERGED failed\" 1>&2\n+\tmv -- \"$BACKUP\" \"$MERGED\"\n \texit 1\n     fi\n \n     if test \"$merge_keep_backup\" = \"true\"; then\n-\tmv -- \"$BACKUP\" \"$path.orig\"\n+\tmv -- \"$BACKUP\" \"$MERGED.orig\"\n     else\n \trm -- \"$BACKUP\"\n     fi\n \n-    git add -- \"$path\"\n+    git add -- \"$MERGED\"\n     cleanup_temp_files\n }\n \n-- \n1.5.4.2.133.g3d51e\n\n\n-- \nCharles Bailey\nhttp://ccgi.hashpling.plus.com/blog/\n"},{"id":"69537","messageId":"0e0179231be0e23cc83fb72269def2f3de3ba420.1203636096.git.charles@hashpling.org","threadId":"12251","inReplyTo":"e6d984bbbb5d4dab54c38caa5c0c71b060d69156.1203636096.git.charles@hashpling.org","subject":"[PATCH 3/4] Teach git mergetool to use custom commands defined at config time","fromName":"Charles Bailey","fromEmail":"charles@hashpling.org","sentAt":"2008-02-21T23:31:12Z","receivedAt":"2008-02-21T23:31:12Z","isPatch":true,"sender":{"key":"charles@hashpling.org","avatar":"https://avatars.githubusercontent.com/u/1668475?v=4"},"body":"Currently git mergetool is restricted to a set of commands defined\nin the script. You can subvert the mergetool.<tool>.path to force\ngit mergetool to use a different command, but if you have a command\nwhose invocation syntax does not match one of the current tools then\nyou would have to write a wrapper script for it.\n\nThis patch adds two git config variable patterns which allow a more\nflexible choice of merge tool.\n\nIf you run git mergetool with -t/--tool or the merge.tool config\nvariable set to an unrecognized tool then git mergetool will query the\nmergetool.<tool>.cmd config variable. If this variable exists, then git\nmergetool will treat the specified tool as a custom command and will use\na shell eval to run the command with the documented shell variables set.\n\nmergetool.<tool>.trustExitCode can be used to indicate that the exit\ncode of the custom command can be used to determine the success of the\nmerge.\n\nSigned-off-by: Charles Bailey <charles@hashpling.org>\n---\n Documentation/config.txt |   25 +++++++++++++++++++++++--\n git-mergetool.sh         |   28 ++++++++++++++++++++++++++--\n 2 files changed, 49 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 4e17fd2..33b7ce9 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -741,8 +741,10 @@ merge.summary::\n \n merge.tool::\n \tControls which merge resolution program is used by\n-\tlinkgit:git-mergetool[1].  Valid values are: \"kdiff3\", \"tkdiff\",\n-\t\"meld\", \"xxdiff\", \"emerge\", \"vimdiff\", \"gvimdiff\", and \"opendiff\".\n+\tlinkgit:git-mergetool[1].  Valid built-in values are: \"kdiff3\",\n+\t\"tkdiff\", \"meld\", \"xxdiff\", \"emerge\", \"vimdiff\", \"gvimdiff\", and\n+\t\"opendiff\".  Any other value is treated is custom merge tool\n+\tand there must be a corresponing mergetool.<tool>.cmd option.\n \n merge.verbosity::\n \tControls the amount of output shown by the recursive merge\n@@ -769,6 +771,25 @@ mergetool.<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+mergetool.<tool>.cmd::\n+\tSpecify the command to invoke the specified merge tool.  The\n+\tspecified command is evaluated in shell with the following\n+\tvariables available: 'BASE' is the name of a temporary file\n+\tcontaining the common base of the files to be merged, if available;\n+\t'LOCAL' is the name of a temporary file containing the contents of\n+\tthe file on the current branch; 'REMOTE' is the name of a temporary\n+\tfile containing the contents of the file from the branch being\n+\tmerged; 'MERGED' contains the name of the file to which the merge\n+\ttool should write the results of a successful merge.\n+\n+mergetool.<tool>.trustExitCode::\n+\tFor a custom merge command, specify whether the exit code of\n+\tthe merge command can be used to determine whether the merge was\n+\tsuccessful.  If this is not set to true then the merge target file\n+\ttimestamp is checked and the merge assumed to have been successful\n+\tif the file has been updated, otherwise the user is prompted to\n+\tindicate the success of the merge.\n+\n mergetool.keepBackup::\n \tAfter performing a merge, the original file with conflict markers\n \tcan be saved as a file with a `.orig` extension.  If this variable\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex d3dd7f8..d12bedf 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -263,6 +263,18 @@ merge_file () {\n \t    fi\n \t    status=$?\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 \techo \"merge of $MERGED failed\" 1>&2\n@@ -308,12 +320,20 @@ 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)\n \t\t\t;; # happy\n \t\t*)\n-\t\t\treturn 1\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@@ -381,10 +401,14 @@ else\n \n     merge_keep_backup=\"$(git config --bool merge.keepBackup || echo true)\"\n \n-    if ! type \"$merge_tool_path\" > /dev/null 2>&1; then\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 \n \n-- \n1.5.4.2.133.g3d51e\n\n\n-- \nCharles Bailey\nhttp://ccgi.hashpling.plus.com/blog/\n"},{"id":"69538","messageId":"75cca7ef76ce7cb0453ae2d940751dd1957b2075.1203636096.git.charles@hashpling.org","threadId":"12251","inReplyTo":"e6d984bbbb5d4dab54c38caa5c0c71b060d69156.1203636096.git.charles@hashpling.org","subject":"[PATCH 4/4] Add a very basic test script for git mergetool","fromName":"Charles Bailey","fromEmail":"charles@hashpling.org","sentAt":"2008-02-21T23:31:56Z","receivedAt":"2008-02-21T23:31:56Z","isPatch":true,"sender":{"key":"charles@hashpling.org","avatar":"https://avatars.githubusercontent.com/u/1668475?v=4"},"body":"Signed-off-by: Charles Bailey <charles@hashpling.org>\n---\n t/t7610-mergetool.sh |   46 ++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 46 insertions(+), 0 deletions(-)\n create mode 100644 t/t7610-mergetool.sh\n\ndiff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh\nnew file mode 100644\nindex 0000000..6b0483f\n--- /dev/null\n+++ b/t/t7610-mergetool.sh\n@@ -0,0 +1,46 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2008 Charles Bailey\n+#\n+\n+test_description='git-mergetool\n+\n+Testing basic merge tool invocation'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'setup' '\n+    echo master >file1 &&\n+    git add file1 &&\n+    git commit -m \"added file1\" &&\n+    git checkout -b branch1 master &&\n+    echo branch1 change >file1 &&\n+    echo branch1 newfile >file2 &&\n+    git add file1 file2 &&\n+    git commit -m \"branch1 changes\" &&\n+    git checkout -b branch2 master &&\n+    echo branch2 change >file1 &&\n+    echo branch2 newfile >file2 &&\n+    git add file1 file2 &&\n+    git commit -m \"branch2 changes\" &&\n+    git checkout master &&\n+    echo master updated >file1 &&\n+    echo master new >file2 &&\n+    git add file1 file2 &&\n+    git commit -m \"master updates\"\n+'\n+\n+test_expect_success 'custom mergetool' '\n+    git config merge.tool mytool &&\n+    git config mergetool.mytool.cmd \"cat \\\"\\$REMOTE\\\" >\\\"\\$MERGED\\\"\" &&\n+    git config mergetool.mytool.trustExitCode true &&\n+\tgit checkout branch1 &&\n+    ! git merge master >/dev/null 2>&1 &&\n+    ( yes \"\" | git mergetool file1>/dev/null 2>&1 ) &&\n+    ( yes \"\" | git mergetool file2>/dev/null 2>&1 ) &&\n+    test \"$(cat file1)\" = \"master updated\" &&\n+    test \"$(cat file2)\" = \"master new\" &&\n+\tgit commit -m \"branch1 resolved with mergetool\"\n+'\n+\n+test_done\n-- \n1.5.4.2.133.g3d51e\n\n\n-- \nCharles Bailey\nhttp://ccgi.hashpling.plus.com/blog/\n"}]}