{"thread":{"id":"39593","subject":"[PATCH v3] git-rebase--interactive.sh: add config option for custom instruction format","startedAt":"2015-06-11T01:30:43Z","lastAt":"2015-06-11T14:40:35Z","messageCount":5,"participants":["Michael Rappazzo","Johannes Schindelin","Mike Rappazzo"],"isPatch":true,"patchVersion":3,"patchTotal":null},"messages":[{"id":"263548","messageId":"1433986244-76038-1-git-send-email-rappazzo@gmail.com","threadId":"39593","inReplyTo":null,"subject":"[PATCH v3] git-rebase--interactive.sh: add config option for custom instruction format","fromName":"Michael Rappazzo","fromEmail":"rappazzo@gmail.com","sentAt":"2015-06-11T01:30:43Z","receivedAt":"2015-06-11T01:30:43Z","isPatch":true,"sender":{"key":"rappazzo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/525287?v=4"},"body":"Difference between v2 and v3 of this patch:\n\n    - Fixed autosquash\n    - Added documentation on the config options\n    - Added two tests to t3414 (rebase-autosquash)\n\nMichael Rappazzo (1):\n  git-rebase--interactive.sh: add config option for custom instruction\n    format\n\n Documentation/git-rebase.txt |  7 +++++++\n git-rebase--interactive.sh   | 34 ++++++++++++++++++++++++++++------\n t/t3415-rebase-autosquash.sh | 33 +++++++++++++++++++++++++++++++++\n 3 files changed, 68 insertions(+), 6 deletions(-)\n\n-- \n2.4.2\n"},{"id":"263550","messageId":"1433986244-76038-2-git-send-email-rappazzo@gmail.com","threadId":"39593","inReplyTo":"1433986244-76038-1-git-send-email-rappazzo@gmail.com","subject":"[PATCH] git-rebase--interactive.sh: add config option for custom instruction format","fromName":"Michael Rappazzo","fromEmail":"rappazzo@gmail.com","sentAt":"2015-06-11T01:30:44Z","receivedAt":"2015-06-11T01:30:44Z","isPatch":true,"sender":{"key":"rappazzo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/525287?v=4"},"body":"A config option 'rebase.instructionFormat' can override the\ndefault 'oneline' format of the rebase instruction list.\n\nSince the list is parsed using the left, right or boundary mark plus\nthe sha1, they are prepended to the instruction format.\n\nSigned-off-by: Michael Rappazzo <rappazzo@gmail.com>\n---\n Documentation/git-rebase.txt |  7 +++++++\n git-rebase--interactive.sh   | 34 ++++++++++++++++++++++++++++------\n t/t3415-rebase-autosquash.sh | 33 +++++++++++++++++++++++++++++++++\n 3 files changed, 68 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 1d01baa..8ddab77 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -213,6 +213,9 @@ rebase.autoSquash::\n rebase.autoStash::\n \tIf set to true enable '--autostash' option by default.\n \n+rebase.instructionFormat::\n+   Custom commit list format to use during an '--interactive' rebase.\n+\n OPTIONS\n -------\n --onto <newbase>::\n@@ -359,6 +362,10 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.\n \tMake a list of the commits which are about to be rebased.  Let the\n \tuser edit that list before rebasing.  This mode can also be used to\n \tsplit commits (see SPLITTING COMMITS below).\n++\n+The commit list format can be changed by setting the configuration option\n+rebase.instructionFormat.  A customized instruction format will automatically\n+have the long commit hash prepended to the format.\n \n -p::\n --preserve-merges::\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex dc3133f..6d14315 100644\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -740,10 +740,19 @@ collapse_todo_ids() {\n # \"pick sha1 fixup!/squash! msg\" appears in it so that the latter\n # comes immediately after the former, and change \"pick\" to\n # \"fixup\"/\"squash\".\n+#\n+# Note that if the config has specified a custom instruction format\n+# each log message will be re-retrieved in order to normalize the \n+# autosquash arrangement\n rearrange_squash () {\n \t# extract fixup!/squash! lines and resolve any referenced sha1's\n-\twhile read -r pick sha1 message\n+\twhile read -r pick sha1 todo_message\n \tdo\n+\t\tmessage=${todo_message}\n+\t\tif test -n \"${format}\"\n+\t\tthen\n+\t\t\tmessage=$(git log -n 1 --format=\"%s\" ${sha1})\n+\t\tfi\n \t\tcase \"$message\" in\n \t\t\"squash! \"*|\"fixup! \"*)\n \t\t\taction=\"${message%%!*}\"\n@@ -779,12 +788,17 @@ rearrange_squash () {\n \ttest -s \"$1.sq\" || return\n \n \tused=\n-\twhile read -r pick sha1 message\n+\twhile read -r pick sha1 todo_message\n \tdo\n \t\tcase \" $used\" in\n \t\t*\" $sha1 \"*) continue ;;\n \t\tesac\n-\t\tprintf '%s\\n' \"$pick $sha1 $message\"\n+\t\tmessage=$todo_message\n+\t\tif test -n \"${format}\"\n+\t\tthen\n+\t\t\tmessage=$(git log -n 1 --format=\"%s\" ${sha1})\n+\t\tfi\n+\t\tprintf '%s\\n' \"$pick $sha1 $todo_message\"\n \t\tused=\"$used$sha1 \"\n \t\twhile read -r squash action msg_prefix msg_content\n \t\tdo\n@@ -802,8 +816,13 @@ rearrange_squash () {\n \t\t\t\tcase \"$message\" in \"$msg_content\"*) emit=1;; esac ;;\n \t\t\tesac\n \t\t\tif test $emit = 1; then\n-\t\t\t\treal_prefix=$(echo \"$msg_prefix\" | sed \"s/,/! /g\")\n-\t\t\t\tprintf '%s\\n' \"$action $squash ${real_prefix}$msg_content\"\n+\t\t\t\tif test -n \"${format}\"\n+\t\t\t\tthen\n+\t\t\t\t\tmsg_content=$(git log -n 1 --format=\"${format}\" ${squash})\n+\t\t\t\telse\n+\t\t\t\t\tmsg_content=\"$(echo \"$msg_prefix\" | sed \"s/,/! /g\")$msg_content\"\n+\t\t\t\tfi\n+\t\t\t\tprintf '%s\\n' \"$action $squash $msg_content\"\n \t\t\t\tused=\"$used$squash \"\n \t\t\tfi\n \t\tdone <\"$1.sq\"\n@@ -977,7 +996,10 @@ else\n \trevisions=$onto...$orig_head\n \tshortrevisions=$shorthead\n fi\n-git rev-list $merges_option --pretty=oneline --reverse --left-right --topo-order \\\n+format=$(git config --get rebase.instructionFormat)\n+# the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse\n+git rev-list $merges_option --format=\"%m%H ${format:-%s}\" \\\n+\t--reverse --left-right --topo-order \\\n \t$revisions ${restrict_revision+^$restrict_revision} | \\\n \tsed -n \"s/^>//p\" |\n while read -r sha1 rest\ndiff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh\nindex 41370ab..1ef96eb 100755\n--- a/t/t3415-rebase-autosquash.sh\n+++ b/t/t3415-rebase-autosquash.sh\n@@ -250,4 +250,37 @@ test_expect_success 'squash! fixup!' '\n \ttest_auto_fixup_fixup squash fixup\n '\n \n+test_expect_success 'autosquash with custom inst format matching on sha1' '\n+\tgit reset --hard base &&\n+\tgit config --add rebase.instructionFormat \"[%an @ %ar] %s\"  &&\n+\techo 1 >file1 &&\n+\tgit add -u &&\n+\ttest_tick &&\n+\tgit commit -m \"squash! $(git rev-parse --short HEAD^)\" &&\n+\tgit tag final-shasquash-instFmt &&\n+\ttest_tick &&\n+\tgit rebase --autosquash -i HEAD^^^ &&\n+\tgit log --oneline >actual &&\n+\ttest_line_count = 3 actual &&\n+\tgit diff --exit-code final-shasquash-instFmt &&\n+\ttest 1 = \"$(git cat-file blob HEAD^:file1)\" &&\n+\ttest 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)\n+'\n+\n+test_expect_success 'autosquash with custom inst format matching on comment' '\n+\tgit reset --hard base &&\n+\tgit config --add rebase.instructionFormat \"[%an @ %ar] %s\"  &&\n+\techo 1 >file1 &&\n+\tgit add -u &&\n+\ttest_tick &&\n+\tgit commit -m \"squash! $(git log -n 1 --format=%s HEAD^)\" &&\n+\tgit tag final-comment-squash-instFmt &&\n+\ttest_tick &&\n+\tgit rebase --autosquash -i HEAD^^^ &&\n+\tgit log --oneline >actual &&\n+\ttest_line_count = 3 actual &&\n+\tgit diff --exit-code final-comment-squash-instFmt &&\n+\ttest 1 = \"$(git cat-file blob HEAD^:file1)\" &&\n+\ttest 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)\n+'\n test_done\n-- \n2.4.2\n"},{"id":"263583","messageId":"dabb4e8e3a864b26c002e9ef966bdf85@www.dscho.org","threadId":"39593","inReplyTo":"1433986244-76038-2-git-send-email-rappazzo@gmail.com","subject":"Re: [PATCH] git-rebase--interactive.sh: add config option for custom instruction format","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2015-06-11T13:40:07Z","receivedAt":"2015-06-11T13:40:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Michael,\n\nOn 2015-06-11 03:30, Michael Rappazzo wrote:\n\n> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\n> index dc3133f..6d14315 100644\n> --- a/git-rebase--interactive.sh\n> +++ b/git-rebase--interactive.sh\n> @@ -740,10 +740,19 @@ collapse_todo_ids() {\n>  # \"pick sha1 fixup!/squash! msg\" appears in it so that the latter\n>  # comes immediately after the former, and change \"pick\" to\n>  # \"fixup\"/\"squash\".\n> +#\n> +# Note that if the config has specified a custom instruction format\n> +# each log message will be re-retrieved in order to normalize the \n> +# autosquash arrangement\n>  rearrange_squash () {\n>  \t# extract fixup!/squash! lines and resolve any referenced sha1's\n> -\twhile read -r pick sha1 message\n> +\twhile read -r pick sha1 todo_message\n>  \tdo\n> +\t\tmessage=${todo_message}\n\nWhy not just leave the `read -r pick sha1 message` as-is and simply write\n\n\t\t# For \"autosquash\":\n\t\ttest -z \"$format\" ||\n\t\tmessage=\"$(git log -n 1 --format=\"%s\" $sha1)\"\n\nhere?\n\n> diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh\n> index 41370ab..1ef96eb 100755\n> --- a/t/t3415-rebase-autosquash.sh\n> +++ b/t/t3415-rebase-autosquash.sh\n> @@ -250,4 +250,37 @@ test_expect_success 'squash! fixup!' '\n>  \ttest_auto_fixup_fixup squash fixup\n>  '\n>  \n> +test_expect_success 'autosquash with custom inst format matching on sha1' '\n> +\tgit reset --hard base &&\n> +\tgit config --add rebase.instructionFormat \"[%an @ %ar] %s\"  &&\n> +\techo 1 >file1 &&\n> +\tgit add -u &&\n> +\ttest_tick &&\n> +\tgit commit -m \"squash! $(git rev-parse --short HEAD^)\" &&\n> +\tgit tag final-shasquash-instFmt &&\n> +\ttest_tick &&\n> +\tgit rebase --autosquash -i HEAD^^^ &&\n\nWe usually write HEAD~3 instead of HEAD^^^...\n\n> +\tgit log --oneline >actual &&\n> +\ttest_line_count = 3 actual &&\n> +\tgit diff --exit-code final-shasquash-instFmt &&\n> +\ttest 1 = \"$(git cat-file blob HEAD^:file1)\" &&\n> +\ttest 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)\n> +'\n> +\n> +test_expect_success 'autosquash with custom inst format matching on comment' '\n> +\tgit reset --hard base &&\n> +\tgit config --add rebase.instructionFormat \"[%an @ %ar] %s\"  &&\n> +\techo 1 >file1 &&\n> +\tgit add -u &&\n> +\ttest_tick &&\n> +\tgit commit -m \"squash! $(git log -n 1 --format=%s HEAD^)\" &&\n> +\tgit tag final-comment-squash-instFmt &&\n> +\ttest_tick &&\n> +\tgit rebase --autosquash -i HEAD^^^ &&\n> +\tgit log --oneline >actual &&\n> +\ttest_line_count = 3 actual &&\n> +\tgit diff --exit-code final-comment-squash-instFmt &&\n> +\ttest 1 = \"$(git cat-file blob HEAD^:file1)\" &&\n> +\ttest 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)\n> +'\n\nThat is copied almost verbatim, except for the commit message. The code would be easier to maintain if it did not repeat so much code e.g. by refactoring out a function that takes the commit message as a parameter.\n\nCiao,\nJohannes\n"},{"id":"263584","messageId":"CANoM8SW13UYazBQgXn6BSDa-rz+jqj19CO3b0K82CV5Ab6HmKw@mail.gmail.com","threadId":"39593","inReplyTo":"dabb4e8e3a864b26c002e9ef966bdf85@www.dscho.org","subject":"Re: [PATCH] git-rebase--interactive.sh: add config option for custom instruction format","fromName":"Mike Rappazzo","fromEmail":"rappazzo@gmail.com","sentAt":"2015-06-11T14:02:38Z","receivedAt":"2015-06-11T14:02:38Z","isPatch":true,"sender":{"key":"rappazzo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/525287?v=4"},"body":"On Thu, Jun 11, 2015 at 9:40 AM, Johannes Schindelin\n<johannes.schindelin@gmx.de> wrote:\n> Hi Michael,\n>\n> On 2015-06-11 03:30, Michael Rappazzo wrote:\n>\n>> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\n>> index dc3133f..6d14315 100644\n>> --- a/git-rebase--interactive.sh\n>> +++ b/git-rebase--interactive.sh\n>> @@ -740,10 +740,19 @@ collapse_todo_ids() {\n>>  # \"pick sha1 fixup!/squash! msg\" appears in it so that the latter\n>>  # comes immediately after the former, and change \"pick\" to\n>>  # \"fixup\"/\"squash\".\n>> +#\n>> +# Note that if the config has specified a custom instruction format\n>> +# each log message will be re-retrieved in order to normalize the\n>> +# autosquash arrangement\n>>  rearrange_squash () {\n>>       # extract fixup!/squash! lines and resolve any referenced sha1's\n>> -     while read -r pick sha1 message\n>> +     while read -r pick sha1 todo_message\n>>       do\n>> +             message=${todo_message}\n>\n> Why not just leave the `read -r pick sha1 message` as-is and simply write\n>\n>                 # For \"autosquash\":\n>                 test -z \"$format\" ||\n>                 message=\"$(git log -n 1 --format=\"%s\" $sha1)\"\n>\n> here?\n\nI did notice that I am not using '$todo_message' in the first loop at\nall, so I will adjust it.  In the second loop, I do use both the\noriginal and the reformatted.  I will apply your suggestion there if\napplicable.\n\n\n>\n>> diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh\n>> +     git rebase --autosquash -i HEAD^^^ &&\n>\n> We usually write HEAD~3 instead of HEAD^^^...\n>\n\nSure, I'll adjust it.  I personally usually use up to 3 '^' and then\nswitch to '~' for > 3\n\n>\n> [The two test functions are] copied almost verbatim, except for the commit message. The code would be easier to maintain if it did not repeat so much code e.g. by refactoring out a function that takes the commit message as a parameter.\n\nMakes sense.  I'll implement that.\n"},{"id":"263587","messageId":"fc77a32f3e571e012591f992ba37bf5a@www.dscho.org","threadId":"39593","inReplyTo":"CANoM8SW13UYazBQgXn6BSDa-rz+jqj19CO3b0K82CV5Ab6HmKw@mail.gmail.com","subject":"Re: [PATCH] git-rebase--interactive.sh: add config option for custom instruction format","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2015-06-11T14:40:35Z","receivedAt":"2015-06-11T14:40:35Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Mike,\n\nOn 2015-06-11 16:02, Mike Rappazzo wrote:\n> On Thu, Jun 11, 2015 at 9:40 AM, Johannes Schindelin\n> <johannes.schindelin@gmx.de> wrote:\n>>\n>> On 2015-06-11 03:30, Michael Rappazzo wrote:\n>>\n>>> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\n>>> index dc3133f..6d14315 100644\n>>> --- a/git-rebase--interactive.sh\n>>> +++ b/git-rebase--interactive.sh\n>>> @@ -740,10 +740,19 @@ collapse_todo_ids() {\n>>>  # \"pick sha1 fixup!/squash! msg\" appears in it so that the latter\n>>>  # comes immediately after the former, and change \"pick\" to\n>>>  # \"fixup\"/\"squash\".\n>>> +#\n>>> +# Note that if the config has specified a custom instruction format\n>>> +# each log message will be re-retrieved in order to normalize the\n>>> +# autosquash arrangement\n>>>  rearrange_squash () {\n>>>       # extract fixup!/squash! lines and resolve any referenced sha1's\n>>> -     while read -r pick sha1 message\n>>> +     while read -r pick sha1 todo_message\n>>>       do\n>>> +             message=${todo_message}\n>>\n>> Why not just leave the `read -r pick sha1 message` as-is and simply write\n>>\n>>                 # For \"autosquash\":\n>>                 test -z \"$format\" ||\n>>                 message=\"$(git log -n 1 --format=\"%s\" $sha1)\"\n>>\n>> here?\n> \n> I did notice that I am not using '$todo_message' in the first loop at\n> all, so I will adjust it.  In the second loop, I do use both the\n> original and the reformatted.  I will apply your suggestion there if\n> applicable.\n\nIt might make sense to use\n\n                 if test -z \"$format\"\n                 then\n                         oneline=\"$message\"\n                 else\n                         oneline=\"$(git log -n 1 --format=\"%s\" $sha1)\"\n                 fi\n\nin the instances where you need to compare against the original oneline, and then only adjust the \"message\" variable name in places that require the original oneline.\n\n>> [The two test functions are] copied almost verbatim, except for the commit message. The code would be easier to maintain if it did not repeat so much code e.g. by refactoring out a function that takes the commit message as a parameter.\n> \n> Makes sense.  I'll implement that.\n\nThank you,\nJohannes\n"}]}