{"thread":{"id":"44248","subject":"[PATCH v3 1/4] mergetool: add copyright","startedAt":"2016-10-07T23:58:16Z","lastAt":"2016-10-07T23:58:26Z","messageCount":4,"participants":["David Aguilar"],"isPatch":true,"patchVersion":3,"patchTotal":4},"messages":[{"id":"303619","messageId":"20161007235806.22247-1-davvid@gmail.com","threadId":"44248","inReplyTo":null,"subject":"[PATCH v3 1/4] mergetool: add copyright","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2016-10-07T23:58:03Z","receivedAt":"2016-10-07T23:58:16Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"Signed-off-by: David Aguilar <davvid@gmail.com>\n---\nUnchanged since v1; included for completeness.\n\n git-mergetool.sh | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex bf86270..300ce7f 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -3,6 +3,7 @@\n # This program resolves merge conflicts in git\n #\n # Copyright (c) 2006 Theodore Y. Ts'o\n+# Copyright (c) 2009-2016 David Aguilar\n #\n # This file is licensed under the GPL v2, or a later version\n # at the discretion of Junio C Hamano.\n-- \n2.10.1.386.g8ee99a0\n\n"},{"id":"303620","messageId":"20161007235806.22247-2-davvid@gmail.com","threadId":"44248","inReplyTo":"20161007235806.22247-1-davvid@gmail.com","subject":"[PATCH v3 2/4] mergetool: move main program flow into a main() function","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2016-10-07T23:58:04Z","receivedAt":"2016-10-07T23:58:20Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"Make it easier to follow the program's flow by isolating all\nlogic into functions.  Isolate the main execution code path into\na single unit instead of having prompt_after_failed_merge()\ninterrupt it partyway through.\n\nThe use of a main() function is borrowing a convention from C,\nPython, Perl, and many other languages.  This helps readers more\nfamiliar with other languages understand the purpose of each\nfunction when diving into the codebase with fresh eyes.\n\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\nUnchanged since v2; included for completeness.\n\n git-mergetool.sh | 180 ++++++++++++++++++++++++++++---------------------------\n 1 file changed, 93 insertions(+), 87 deletions(-)\n\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex 300ce7f..b2cd0a4 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -366,51 +366,6 @@ merge_file () {\n \treturn 0\n }\n \n-prompt=$(git config --bool mergetool.prompt)\n-guessed_merge_tool=false\n-\n-while test $# != 0\n-do\n-\tcase \"$1\" in\n-\t--tool-help=*)\n-\t\tTOOL_MODE=${1#--tool-help=}\n-\t\tshow_tool_help\n-\t\t;;\n-\t--tool-help)\n-\t\tshow_tool_help\n-\t\t;;\n-\t-t|--tool*)\n-\t\tcase \"$#,$1\" in\n-\t\t*,*=*)\n-\t\t\tmerge_tool=$(expr \"z$1\" : 'z-[^=]*=\\(.*\\)')\n-\t\t\t;;\n-\t\t1,*)\n-\t\t\tusage ;;\n-\t\t*)\n-\t\t\tmerge_tool=\"$2\"\n-\t\t\tshift ;;\n-\t\tesac\n-\t\t;;\n-\t-y|--no-prompt)\n-\t\tprompt=false\n-\t\t;;\n-\t--prompt)\n-\t\tprompt=true\n-\t\t;;\n-\t--)\n-\t\tshift\n-\t\tbreak\n-\t\t;;\n-\t-*)\n-\t\tusage\n-\t\t;;\n-\t*)\n-\t\tbreak\n-\t\t;;\n-\tesac\n-\tshift\n-done\n-\n prompt_after_failed_merge () {\n \twhile true\n \tdo\n@@ -427,57 +382,108 @@ prompt_after_failed_merge () {\n \tdone\n }\n \n-git_dir_init\n-require_work_tree\n+main () {\n+\tprompt=$(git config --bool mergetool.prompt)\n+\tguessed_merge_tool=false\n+\n+\twhile test $# != 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t--tool-help=*)\n+\t\t\tTOOL_MODE=${1#--tool-help=}\n+\t\t\tshow_tool_help\n+\t\t\t;;\n+\t\t--tool-help)\n+\t\t\tshow_tool_help\n+\t\t\t;;\n+\t\t-t|--tool*)\n+\t\t\tcase \"$#,$1\" in\n+\t\t\t*,*=*)\n+\t\t\t\tmerge_tool=$(expr \"z$1\" : 'z-[^=]*=\\(.*\\)')\n+\t\t\t\t;;\n+\t\t\t1,*)\n+\t\t\t\tusage ;;\n+\t\t\t*)\n+\t\t\t\tmerge_tool=\"$2\"\n+\t\t\t\tshift ;;\n+\t\t\tesac\n+\t\t\t;;\n+\t\t-y|--no-prompt)\n+\t\t\tprompt=false\n+\t\t\t;;\n+\t\t--prompt)\n+\t\t\tprompt=true\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t-*)\n+\t\t\tusage\n+\t\t\t;;\n+\t\t*)\n+\t\t\tbreak\n+\t\t\t;;\n+\t\tesac\n+\t\tshift\n+\tdone\n+\n+\tgit_dir_init\n+\trequire_work_tree\n \n-if test -z \"$merge_tool\"\n-then\n-\t# Check if a merge tool has been configured\n-\tmerge_tool=$(get_configured_merge_tool)\n-\t# Try to guess an appropriate merge tool if no tool has been set.\n \tif test -z \"$merge_tool\"\n \tthen\n-\t\tmerge_tool=$(guess_merge_tool) || exit\n-\t\tguessed_merge_tool=true\n+\t\t# Check if a merge tool has been configured\n+\t\tmerge_tool=$(get_configured_merge_tool)\n+\t\t# Try to guess an appropriate merge tool if no tool has been set.\n+\t\tif test -z \"$merge_tool\"\n+\t\tthen\n+\t\t\tmerge_tool=$(guess_merge_tool) || exit\n+\t\t\tguessed_merge_tool=true\n+\t\tfi\n \tfi\n-fi\n-merge_keep_backup=\"$(git config --bool mergetool.keepBackup || echo true)\"\n-merge_keep_temporaries=\"$(git config --bool mergetool.keepTemporaries || echo false)\"\n-\n-files=\n+\tmerge_keep_backup=\"$(git config --bool mergetool.keepBackup || echo true)\"\n+\tmerge_keep_temporaries=\"$(git config --bool mergetool.keepTemporaries || echo false)\"\n \n-if test $# -eq 0\n-then\n-\tcd_to_toplevel\n+\tfiles=\n \n-\tif test -e \"$GIT_DIR/MERGE_RR\"\n+\tif test $# -eq 0\n \tthen\n-\t\tfiles=$(git rerere remaining)\n+\t\tcd_to_toplevel\n+\n+\t\tif test -e \"$GIT_DIR/MERGE_RR\"\n+\t\tthen\n+\t\t\tfiles=$(git rerere remaining)\n+\t\telse\n+\t\t\tfiles=$(git ls-files -u |\n+\t\t\t\tsed -e 's/^[^\t]*\t//' | sort -u)\n+\t\tfi\n \telse\n-\t\tfiles=$(git ls-files -u | sed -e 's/^[^\t]*\t//' | sort -u)\n+\t\tfiles=$(git ls-files -u -- \"$@\" |\n+\t\t\tsed -e 's/^[^\t]*\t//' | sort -u)\n \tfi\n-else\n-\tfiles=$(git ls-files -u -- \"$@\" | sed -e 's/^[^\t]*\t//' | sort -u)\n-fi\n-\n-if test -z \"$files\"\n-then\n-\techo \"No files need merging\"\n-\texit 0\n-fi\n-\n-printf \"Merging:\\n\"\n-printf \"%s\\n\" \"$files\"\n-\n-rc=0\n-for i in $files\n-do\n-\tprintf \"\\n\"\n-\tif ! merge_file \"$i\"\n+\n+\tif test -z \"$files\"\n \tthen\n-\t\trc=1\n-\t\tprompt_after_failed_merge || exit 1\n+\t\techo \"No files need merging\"\n+\t\texit 0\n \tfi\n-done\n \n-exit $rc\n+\tprintf \"Merging:\\n\"\n+\tprintf \"%s\\n\" \"$files\"\n+\n+\trc=0\n+\tfor i in $files\n+\tdo\n+\t\tprintf \"\\n\"\n+\t\tif ! merge_file \"$i\"\n+\t\tthen\n+\t\t\trc=1\n+\t\t\tprompt_after_failed_merge || exit 1\n+\t\tfi\n+\tdone\n+\n+\texit $rc\n+}\n+\n+main \"$@\"\n-- \n2.10.1.386.g8ee99a0\n\n"},{"id":"303621","messageId":"20161007235806.22247-3-davvid@gmail.com","threadId":"44248","inReplyTo":"20161007235806.22247-1-davvid@gmail.com","subject":"[PATCH v3 3/4] mergetool: honor diff.orderFile","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2016-10-07T23:58:05Z","receivedAt":"2016-10-07T23:58:23Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"Teach mergetool to get the list of files to edit via `diff` so that we\ngain support for diff.orderFile.\n\nSuggested-by: Luis Gutierrez <luisgutz@gmail.com>\nHelped-by: Johannes Sixt <j6t@kdbg.org>\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\nChanges since v2:\n\nThe tests no longer rely on \"grep -A\" and instead use \"git grep\"\nfor portability.  The mergetool output in the test is redirected\nto a file so that we can catch its exit code.\n\n Documentation/git-mergetool.txt |  5 +++++\n git-mergetool.sh                | 30 +++++++++++++++---------------\n t/t7610-mergetool.sh            | 33 +++++++++++++++++++++++++++++++++\n 3 files changed, 53 insertions(+), 15 deletions(-)\n\ndiff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt\nindex e846c2e..c4c1a9b 100644\n--- a/Documentation/git-mergetool.txt\n+++ b/Documentation/git-mergetool.txt\n@@ -79,6 +79,11 @@ success of the resolution after the custom tool has exited.\n \tPrompt before each invocation of the merge resolution program\n \tto give the user a chance to skip the path.\n \n+DIFF ORDER FILES\n+----------------\n+`git mergetool` honors the `diff.orderFile` configuration variable\n+used by `git diff`.  See linkgit:git-config[1] for more details.\n+\n TEMPORARY FILES\n ---------------\n `git mergetool` creates `*.orig` backup files while resolving merges.\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex b2cd0a4..65696d8 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -382,6 +382,11 @@ prompt_after_failed_merge () {\n \tdone\n }\n \n+print_noop_and_exit () {\n+\techo \"No files need merging\"\n+\texit 0\n+}\n+\n main () {\n \tprompt=$(git config --bool mergetool.prompt)\n \tguessed_merge_tool=false\n@@ -445,28 +450,23 @@ main () {\n \tmerge_keep_backup=\"$(git config --bool mergetool.keepBackup || echo true)\"\n \tmerge_keep_temporaries=\"$(git config --bool mergetool.keepTemporaries || echo false)\"\n \n-\tfiles=\n-\n-\tif test $# -eq 0\n+\tif test $# -eq 0 && test -e \"$GIT_DIR/MERGE_RR\"\n \tthen\n-\t\tcd_to_toplevel\n-\n-\t\tif test -e \"$GIT_DIR/MERGE_RR\"\n+\t\tset -- $(git rerere remaining)\n+\t\tif test $# -eq 0\n \t\tthen\n-\t\t\tfiles=$(git rerere remaining)\n-\t\telse\n-\t\t\tfiles=$(git ls-files -u |\n-\t\t\t\tsed -e 's/^[^\t]*\t//' | sort -u)\n+\t\t\tprint_noop_and_exit\n \t\tfi\n-\telse\n-\t\tfiles=$(git ls-files -u -- \"$@\" |\n-\t\t\tsed -e 's/^[^\t]*\t//' | sort -u)\n \tfi\n \n+\tfiles=$(git -c core.quotePath=false \\\n+\t\tdiff --name-only --diff-filter=U -- \"$@\")\n+\n+\tcd_to_toplevel\n+\n \tif test -z \"$files\"\n \tthen\n-\t\techo \"No files need merging\"\n-\t\texit 0\n+\t\tprint_noop_and_exit\n \tfi\n \n \tprintf \"Merging:\\n\"\ndiff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh\nindex 7217f39..38c1e4d 100755\n--- a/t/t7610-mergetool.sh\n+++ b/t/t7610-mergetool.sh\n@@ -606,4 +606,37 @@ test_expect_success MKTEMP 'temporary filenames are used with mergetool.writeToT\n \tgit reset --hard master >/dev/null 2>&1\n '\n \n+test_expect_success 'diff.orderFile configuration is honored' '\n+\ttest_config diff.orderFile order-file &&\n+\ttest_config mergetool.myecho.cmd \"echo \\\"\\$LOCAL\\\"\" &&\n+\ttest_config mergetool.myecho.trustExitCode true &&\n+\techo b >order-file &&\n+\techo a >>order-file &&\n+\tgit checkout -b order-file-start master &&\n+\techo start >a &&\n+\techo start >b &&\n+\tgit add a b &&\n+\tgit commit -m start &&\n+\tgit checkout -b order-file-side1 order-file-start &&\n+\techo side1 >a &&\n+\techo side1 >b &&\n+\tgit add a b &&\n+\tgit commit -m side1 &&\n+\tgit checkout -b order-file-side2 order-file-start &&\n+\techo side2 >a &&\n+\techo side2 >b &&\n+\tgit add a b &&\n+\tgit commit -m side2 &&\n+\ttest_must_fail git merge order-file-side1 &&\n+\tcat >expect <<-\\EOF &&\n+\t\tMerging:\n+\t\tb\n+\t\ta\n+\tEOF\n+\tgit mergetool --no-prompt --tool myecho >output &&\n+\tgit grep --no-index -h -A2 Merging: output >actual &&\n+\ttest_cmp expect actual &&\n+\tgit reset --hard >/dev/null\n+'\n+\n test_done\n-- \n2.10.1.386.g8ee99a0\n\n"},{"id":"303622","messageId":"20161007235806.22247-4-davvid@gmail.com","threadId":"44248","inReplyTo":"20161007235806.22247-1-davvid@gmail.com","subject":"[PATCH v3 4/4] mergetool: honor -O<orderfile>","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2016-10-07T23:58:06Z","receivedAt":"2016-10-07T23:58:26Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"Teach mergetool to pass \"-O<orderfile>\" down to `git diff` when\nspecified on the command-line.\n\nHelped-by: Johannes Sixt <j6t@kdbg.org>\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\nChanges since v2:\n\nThe tests no longer rely on \"grep -A\" and instead use \"git grep\"\nfor portability.  The mergetool output in the test is redirected\nto a file so that we can catch its exit code.\n\nThe $orderfile variable is now passed using ${xxx:+\"$xxx\"}\nto avoid conditional logic.\n\n Documentation/git-mergetool.txt | 10 ++++++----\n git-mergetool.sh                |  9 +++++++--\n t/t7610-mergetool.sh            | 27 +++++++++++++++++++++++++++\n 3 files changed, 40 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt\nindex c4c1a9b..3622d66 100644\n--- a/Documentation/git-mergetool.txt\n+++ b/Documentation/git-mergetool.txt\n@@ -79,10 +79,12 @@ success of the resolution after the custom tool has exited.\n \tPrompt before each invocation of the merge resolution program\n \tto give the user a chance to skip the path.\n \n-DIFF ORDER FILES\n-----------------\n-`git mergetool` honors the `diff.orderFile` configuration variable\n-used by `git diff`.  See linkgit:git-config[1] for more details.\n+-O<orderfile>::\n+\tProcess files in the order specified in the\n+\t<orderfile>, which has one shell glob pattern per line.\n+\tThis overrides the `diff.orderFile` configuration variable\n+\t(see linkgit:git-config[1]).  To cancel `diff.orderFile`,\n+\tuse `-O/dev/null`.\n \n TEMPORARY FILES\n ---------------\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex 65696d8..e52b4e4 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -9,7 +9,7 @@\n # at the discretion of Junio C Hamano.\n #\n \n-USAGE='[--tool=tool] [--tool-help] [-y|--no-prompt|--prompt] [file to merge] ...'\n+USAGE='[--tool=tool] [--tool-help] [-y|--no-prompt|--prompt] [-O<orderfile>] [file to merge] ...'\n SUBDIRECTORY_OK=Yes\n NONGIT_OK=Yes\n OPTIONS_SPEC=\n@@ -390,6 +390,7 @@ print_noop_and_exit () {\n main () {\n \tprompt=$(git config --bool mergetool.prompt)\n \tguessed_merge_tool=false\n+\torderfile=\n \n \twhile test $# != 0\n \tdo\n@@ -419,6 +420,9 @@ main () {\n \t\t--prompt)\n \t\t\tprompt=true\n \t\t\t;;\n+\t\t-O*)\n+\t\t\torderfile=\"$1\"\n+\t\t\t;;\n \t\t--)\n \t\t\tshift\n \t\t\tbreak\n@@ -460,7 +464,8 @@ main () {\n \tfi\n \n \tfiles=$(git -c core.quotePath=false \\\n-\t\tdiff --name-only --diff-filter=U -- \"$@\")\n+\t\tdiff --name-only --diff-filter=U \\\n+\t\t${orderfile:+\"$orderfile\"} -- \"$@\")\n \n \tcd_to_toplevel\n \ndiff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh\nindex 38c1e4d..5cfad76 100755\n--- a/t/t7610-mergetool.sh\n+++ b/t/t7610-mergetool.sh\n@@ -638,5 +638,32 @@ test_expect_success 'diff.orderFile configuration is honored' '\n \ttest_cmp expect actual &&\n \tgit reset --hard >/dev/null\n '\n+test_expect_success 'mergetool -Oorder-file is honored' '\n+\ttest_config diff.orderFile order-file &&\n+\ttest_config mergetool.myecho.cmd \"echo \\\"\\$LOCAL\\\"\" &&\n+\ttest_config mergetool.myecho.trustExitCode true &&\n+\ttest_must_fail git merge order-file-side1 &&\n+\tcat >expect <<-\\EOF &&\n+\t\tMerging:\n+\t\ta\n+\t\tb\n+\tEOF\n+\tgit mergetool -O/dev/null --no-prompt --tool myecho |\n+\tgrep -A 2 Merging: >actual &&\n+\ttest_cmp expect actual &&\n+\tgit reset --hard >/dev/null 2>&1 &&\n+\n+\tgit config --unset diff.orderFile &&\n+\ttest_must_fail git merge order-file-side1 &&\n+\tcat >expect <<-\\EOF &&\n+\t\tMerging:\n+\t\tb\n+\t\ta\n+\tEOF\n+\tgit mergetool -Oorder-file --no-prompt --tool myecho >output &&\n+\tgit grep --no-index -h -A2 Merging: output >actual &&\n+\ttest_cmp expect actual &&\n+\tgit reset --hard >/dev/null 2>&1\n+'\n \n test_done\n-- \n2.10.1.386.g8ee99a0\n\n"}]}