{"thread":{"id":"36690","subject":"[PATCH 1/4] rebase -i: add ack action","startedAt":"2014-05-18T21:17:45Z","lastAt":"2014-06-11T08:46:48Z","messageCount":17,"participants":["Michael S. Tsirkin","Eric Sunshine","Junio C Hamano","Fabian Ruch"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"242093","messageId":"1400447743-18513-1-git-send-email-mst@redhat.com","threadId":"36690","inReplyTo":null,"subject":"[PATCH 0/4] ack recoding in commit log","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-18T21:17:45Z","receivedAt":"2014-05-18T21:17:45Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"As a maintainer, I often get patches by mail, then\nacked-by,reviewed-by etc responses are sent by separate\nmail.\n\nI like making acks commits,\nthis way they are easy to keep track of\nas part of git history.\n\n\nSince response mail happens to have appropriate\nsubject matching the patch, it's a natural fit to\nthen use git rebase mechanics if we want to smash\nthese acks into the original commit.\n\nI have been using these patches without any problems\nfor a while now, and find the approach very convenient.\n\nIncluded:\n\trebase: new ack! action to handle ack commits\n\t\tthis part seems ready for merge to me,\n\t\tplease review and comment\n\n\tgit-ack: new tool to record an ack\n\t\tthis does not have proper documentation\n\t\tand tests yet, I definitely intend to\n\t\tdo this but wanted to see whether people\n\t\tlike the UI first.\n\t\tposting for early review and feedback\n\n\nNote: yes, I think notes+git replace could be used for this too,\nmy workflow always includes a rebase with --autosquash\nbefore publishing anyway, so dealing with ack as with any\nother commit is nicer.\n\n\nMichael S. Tsirkin (4):\n  rebase -i: add ack action\n  git-rebase: document ack\n  rebase: test ack\n  git-ack: record an ack\n\n Documentation/git-rebase.txt | 45 ++++++++++++++++++++++---\n contrib/git-ack              | 79 ++++++++++++++++++++++++++++++++++++++++++++\n git-rebase--interactive.sh   | 34 +++++++++++++++----\n t/t3415-rebase-autosquash.sh | 15 +++++++++\n 4 files changed, 161 insertions(+), 12 deletions(-)\n create mode 100755 contrib/git-ack\n\n-- \nMST\n"},{"id":"242091","messageId":"1400447743-18513-2-git-send-email-mst@redhat.com","threadId":"36690","inReplyTo":"1400447743-18513-1-git-send-email-mst@redhat.com","subject":"[PATCH 1/4] rebase -i: add ack action","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-18T21:17:47Z","receivedAt":"2014-05-18T21:17:47Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"This implements a new ack! action for git rebase -i\nIt is essentially a middle ground between fixup! and squash!:\n- commits are squashed silently without editor being started\n- commit logs are concatenated (with action line being discarded)\n- because of the above, empty commits aren't discarded,\n  their log is also included.\n\nI am using it as follows:\n\tgit am -s < mailbox #creates first commit\n\thack ...\n\tget mail with Ack\n\tgit commit --allow-empty -m `cat <<-EOF\n\tack! first\n\n\tAcked-by: maintainer\n\tEOF`\n\trepeat cycle\n\tgit rebase --autosquash -i origin/master\n\tbefore public branch push\n\nThe \"cat\" command above is actually a script that\nparses the Ack mail to create the empty commit -\nto be submitted separately.\n\nSigned-off-by: Michael S. Tsirkin <mst@redhat.com>\n---\n git-rebase--interactive.sh | 34 +++++++++++++++++++++++++++-------\n 1 file changed, 27 insertions(+), 7 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 6ec9d3c..821872c 100644\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -140,6 +140,7 @@ Commands:\n  r, reword = use commit, but edit the commit message\n  e, edit = use commit, but stop for amending\n  s, squash = use commit, but meld into previous commit\n+ a, ack = like \"squash\", but append commit body only to previous commit\n  f, fixup = like \"squash\", but discard this commit's log message\n  x, exec = run command (the rest of the line) using shell\n \n@@ -412,6 +413,15 @@ update_squash_messages () {\n \t\techo\n \t\tcommit_message $2\n \t\t;;\n+\tack)\n+\t\tif test -f \"$fixup_msg\"\n+\t\tthen\n+\t\t\tcommit_message $2 | git stripspace --strip-comments | sed -e '1,2d' >> \"$fixup_msg\"\n+\t\tfi\n+\t\tprintf '%s\\n' \"$comment_char This is the $(nth_string $count) commit message:\"\n+\t\techo\n+\t\tcommit_message $2\n+\t\t;;\n \tfixup)\n \t\techo\n \t\tprintf '%s\\n' \"$comment_char The $(nth_string $count) commit message will be skipped:\"\n@@ -453,7 +463,7 @@ record_in_rewritten() {\n \techo \"$oldsha1\" >> \"$rewritten_pending\"\n \n \tcase \"$(peek_next_command)\" in\n-\tsquash|s|fixup|f)\n+\tsquash|s|fixup|f|ack|a)\n \t\t;;\n \t*)\n \t\tflush_rewritten_pending\n@@ -521,8 +531,11 @@ do_next () {\n \t\twarn \"Stopped at $sha1... $rest\"\n \t\texit_with_patch $sha1 0\n \t\t;;\n-\tsquash|s|fixup|f)\n+\tsquash|s|fixup|f|ack|a)\n \t\tcase \"$command\" in\n+\t\tack|a)\n+\t\t\tsquash_style=ack\n+\t\t\t;;\n \t\tsquash|s)\n \t\t\tsquash_style=squash\n \t\t\t;;\n@@ -546,7 +559,7 @@ do_next () {\n \t\t\tdie_failed_squash $sha1 \"$rest\"\n \t\tfi\n \t\tcase \"$(peek_next_command)\" in\n-\t\tsquash|s|fixup|f)\n+\t\tsquash|s|fixup|f|ack|a)\n \t\t\t# This is an intermediate commit; its message will only be\n \t\t\t# used in case of trouble.  So use the long version:\n \t\t\tdo_with_author output git commit --amend --no-verify -F \"$squash_msg\" \\\n@@ -557,7 +570,7 @@ do_next () {\n \t\t\t# This is the final command of this squash/fixup group\n \t\t\tif test -f \"$fixup_msg\"\n \t\t\tthen\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$fixup_msg\" \\\n+\t\t\t\tdo_with_author git commit --quiet --amend --no-verify -F \"$fixup_msg\" \\\n \t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} ||\n \t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n \t\t\telse\n@@ -690,7 +703,7 @@ skip_unnecessary_picks () {\n \tdone <\"$todo\" >\"$todo.new\" 3>>\"$done\" &&\n \tmv -f \"$todo\".new \"$todo\" &&\n \tcase \"$(peek_next_command)\" in\n-\tsquash|s|fixup|f)\n+\tsquash|s|fixup|f|ack|a)\n \t\trecord_in_rewritten \"$onto\"\n \t\t;;\n \tesac ||\n@@ -732,7 +745,7 @@ rearrange_squash () {\n \twhile read -r pick sha1 message\n \tdo\n \t\tcase \"$message\" in\n-\t\t\"squash! \"*|\"fixup! \"*)\n+\t\t\"squash! \"*|\"fixup! \"*|\"ack! \"*)\n \t\t\taction=\"${message%%!*}\"\n \t\t\trest=$message\n \t\t\tprefix=\n@@ -740,7 +753,7 @@ rearrange_squash () {\n \t\t\twhile :\n \t\t\tdo\n \t\t\t\tcase \"$rest\" in\n-\t\t\t\t\"squash! \"*|\"fixup! \"*)\n+\t\t\t\t\"squash! \"*|\"fixup! \"* |\"ack! \"*)\n \t\t\t\t\tprefix=\"$prefix${rest%%!*},\"\n \t\t\t\t\trest=\"${rest#*! }\"\n \t\t\t\t\t;;\n@@ -975,6 +988,13 @@ do\n \t\tcomment_out=\n \tfi\n \n+\t# keep empty ack! commits around: useful to add text to commit log\n+\tcase \"$rest\" in\n+\t\"ack! \"*)\n+\t\tcomment_out=\n+\t\t;;\n+\tesac\n+\n \tif test t != \"$preserve_merges\"\n \tthen\n \t\tprintf '%s\\n' \"${comment_out}pick $shortsha1 $rest\" >>\"$todo\"\n-- \nMST\n"},{"id":"242092","messageId":"1400447743-18513-3-git-send-email-mst@redhat.com","threadId":"36690","inReplyTo":"1400447743-18513-1-git-send-email-mst@redhat.com","subject":"[PATCH 2/4] git-rebase: document ack","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-18T21:17:49Z","receivedAt":"2014-05-18T21:17:49Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"document ack! behaviour and use\n\nSigned-off-by: Michael S. Tsirkin <mst@redhat.com>\n---\n Documentation/git-rebase.txt | 45 +++++++++++++++++++++++++++++++++++++++-----\n 1 file changed, 40 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 2a93c64..c27aef4 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -384,7 +384,7 @@ or by giving more than one `--exec`:\n +\n If `--autosquash` is used, \"exec\" lines will not be appended for\n the intermediate commits, and will only appear at the end of each\n-squash/fixup series.\n+squash/fixup/ack series.\n \n --root::\n \tRebase all commits reachable from <branch>, instead of\n@@ -398,13 +398,13 @@ squash/fixup series.\n \n --autosquash::\n --no-autosquash::\n-\tWhen the commit log message begins with \"squash! ...\" (or\n-\t\"fixup! ...\"), and there is a commit whose title begins with\n+\tWhen the commit log message begins with \"squash! ...\" (\"fixup! ...\"\n+\tor \"ack! ...\"), and there is a commit whose title begins with\n \tthe same ..., automatically modify the todo list of rebase -i\n \tso that the commit marked for squashing comes right after the\n \tcommit to be modified, and change the action of the moved\n-\tcommit from `pick` to `squash` (or `fixup`).  Ignores subsequent\n-\t\"fixup! \" or \"squash! \" after the first, in case you referred to an\n+\tcommit from `pick` to `squash` (`fixup` or `ack`).  Ignores subsequent\n+\t\"ack! \", \"fixup! \" or \"squash! \" after the first, in case you referred to an\n \tearlier fixup/squash with `git commit --fixup/--squash`.\n +\n This option is only valid when the '--interactive' option is used.\n@@ -624,6 +624,41 @@ consistent (they compile, pass the testsuite, etc.) you should use\n 'git stash' to stash away the not-yet-committed changes\n after each commit, test, and amend the commit if fixes are necessary.\n \n+----------------\n+RECORDING ACKS\n+----------------\n+\n+Interactive mode with --autosquash can be used to concatenate\n+commit log for several commits, which is useful to record\n+extra information about the commit, such as ack signatures.\n+This allows, for example, the following workflow:\n+\n+1. receive patches by mail and commit\n+2. receive by mail ack signatures for the patches\n+3. prepare a series for submission\n+4. submit\n+\n+where point 2. consists of several instances of\n+\ti) create a (possibly empty) commit with signature\n+\t  in the commit message\n+\n+Sometimes the ack signature added in i. cannot be amended to the\n+commit it acks, because that commit is buried deeply in a\n+patch series.  That is exactly what rebase --autosquash\n+option is for: use it\n+after plenty of \"i\"s, to automaticlly rearrange\n+commits, and squashing multiple sign-off commits into\n+the commit that is signed.\n+\n+Start it with the last commit you want to retain as-is:\n+\n+\tgit rebase --autosquash -i <after-this-commit>\n+\n+An editor will be fired up with all the commits in your current branch\n+which come after the given commit. Ack commits will be\n+re-arranged to come after the commit that is acked,\n+and the action will be utomticlly changed from `pick` to `ack`\n+to cause them to be squashed into the acked commit.\n \n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n-- \nMST\n"},{"id":"242094","messageId":"1400447743-18513-4-git-send-email-mst@redhat.com","threadId":"36690","inReplyTo":"1400447743-18513-1-git-send-email-mst@redhat.com","subject":"[PATCH 3/4] rebase: test ack","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-18T21:17:51Z","receivedAt":"2014-05-18T21:17:51Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"test ack! handling\n\nSigned-off-by: Michael S. Tsirkin <mst@redhat.com>\n---\n t/t3415-rebase-autosquash.sh | 15 +++++++++++++++\n 1 file changed, 15 insertions(+)\n\ndiff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh\nindex 41370ab..9d7db13 100755\n--- a/t/t3415-rebase-autosquash.sh\n+++ b/t/t3415-rebase-autosquash.sh\n@@ -74,6 +74,21 @@ test_expect_success 'auto squash (option)' '\n \ttest_auto_squash final-squash --autosquash\n '\n \n+test_expect_success 'auto ack' '\n+\tack=\"Acked-by: xyz\"\n+\tmsg=$(test_write_lines \"ack! first commit\" \"\" \"$ack\")\n+\tgit reset --hard base &&\n+\tgit commit --allow-empty -m \"$msg\" -- &&\n+\tgit tag ack &&\n+\ttest_tick &&\n+\tgit rebase --autosquash -i HEAD^^^ &&\n+\tgit log --oneline >actual &&\n+\tgit show -s first-commit | grep -v ^commit > expected-msg &&\n+\techo \"    $ack\" >> expected-msg &&\n+\tgit show -s HEAD^ | grep -v ^commit > actual-msg &&\n+\tdiff actual-msg expected-msg\n+'\n+\n test_expect_success 'auto squash (config)' '\n \tgit config rebase.autosquash true &&\n \ttest_auto_squash final-squash-config-true &&\n-- \nMST\n"},{"id":"242095","messageId":"1400447743-18513-5-git-send-email-mst@redhat.com","threadId":"36690","inReplyTo":"1400447743-18513-1-git-send-email-mst@redhat.com","subject":"[PATCH 4/4] git-ack: record an ack","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-18T21:17:54Z","receivedAt":"2014-05-18T21:17:54Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"This is a simple script that I use by piping\nincoming mail with an ack to it.\nIt produces an empty ack commit suitable for\nsqushing with git rebase -i -autosquash.\n\nWorks best if people ack individual commits: you simply\npipe each ack to git ack, before pushing your branch,\nrebase.\n\nSome people ack series by responding to cover letter\nor to commit 1.\nTo address this usecase, there are two additional\nflags: -s saves the ack signature in a file (you can\nsave several in a row), -r creates an ack for\na given patch using the saved signature.\nThus: pipe ack(s) to git ack -s, then select and pipe\neach individual patch to git ack -r.\nI don't use these flags much so they likely work\nless well.\n\nIf it's found useful, this script can either\nbecome a first-class command (with documentation\nand tests) or be integrated as a flag into git am.\n\nLimitations: requires that index is clean, this is\nso we can create an empty commit recording the ack.\n\nSigned-off-by: Michael S. Tsirkin <mst@redhat.com>\n---\n contrib/git-ack | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 84 insertions(+)\n create mode 100755 contrib/git-ack\n\ndiff --git a/contrib/git-ack b/contrib/git-ack\nnew file mode 100755\nindex 0000000..4aeb16a\n--- /dev/null\n+++ b/contrib/git-ack\n@@ -0,0 +1,84 @@\n+msg=`mktemp`\n+patch=`mktemp`\n+info=`git mailinfo $msg $patch`\n+subj=`echo \"$info\"|sed -n 's/^Subject: //p'`\n+author=`echo \"$info\"|sed -n 's/^Author: //p'`\n+email=`echo \"$info\"|sed -n 's/^Email: //p'`\n+auth=\"$author <$email>\"\n+date=`echo \"$info\"|sed -n 's/^Date: //p'`\n+sign=`mktemp`\n+echo \"ack! $subj\" > $sign\n+echo \"\" >> $sign\n+if\n+    git diff --cached HEAD\n+then\n+    nop < /dev/null\n+else\n+    echo \"DIFF in cache. Not acked, reset or commit!\"\n+    exit 1\n+fi\n+GIT_DIR=`pwd`/${GIT_DIR}\n+\n+usage () {\n+\techo \"Usage: git ack \" \\\n+            \"[-s|--save|-a|--append|-r|--restore |-c|--clear]\\n\" >& 2;\n+        exit 1;\n+}\n+\n+append=\n+save=\n+clear=\n+\n+while test $# != 0\n+do\n+\tcase \"$1\" in\n+\t-a|--append)\n+\t\tappend=\"y\"\n+\t\t;;\n+\t-s|--s)\n+\t\tsave=\"y\"\n+\t\t;;\n+\t-r|--restore)\n+\t\trestore=\"y\"\n+\t\t;;\n+\t-c|--clear)\n+\t\tclear=\"y\"\n+                ;;\n+\t*)\n+\t\tusage ;;\n+\tesac\n+\tshift\n+done\n+\n+if\n+    test \"$clear\"\n+then\n+    rm -f \"${GIT_DIR}/ACKS\"\n+fi\n+\n+if\n+    test \"$save\"\n+then\n+    if\n+        test \"$append\"\n+    then\n+        cat $msg >> \"${GIT_DIR}/ACKS\"\n+    else\n+        cat $msg > \"${GIT_DIR}/ACKS\"\n+    fi\n+fi\n+\n+if\n+    test \"$restore\"\n+then\n+    msg = ${GIT_DIR}/ACKS\n+fi\n+\n+if\n+    grep '^[A-Z][A-Za-z-]*-by:' $msg >> $sign\n+then\n+    git commit --allow-empty -F $sign --author=\"$auth\" --date=\"$date\"\n+else\n+    echo \"No signature found!\"\n+    exit 2\n+fi\n-- \nMST\n"},{"id":"242134","messageId":"CAPig+cT0evq73-O9Ns5YXjp7Yg-FdX7FehDzW9fOz_Wqp2chUQ@mail.gmail.com","threadId":"36690","inReplyTo":"1400447743-18513-3-git-send-email-mst@redhat.com","subject":"Re: [PATCH 2/4] git-rebase: document ack","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2014-05-18T23:43:45Z","receivedAt":"2014-05-18T23:43:45Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sun, May 18, 2014 at 5:17 PM, Michael S. Tsirkin <mst@redhat.com> wrote:\n> document ack! behaviour and use\n>\n> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>\n> ---\n>  Documentation/git-rebase.txt | 45 +++++++++++++++++++++++++++++++++++++++-----\n>  1 file changed, 40 insertions(+), 5 deletions(-)\n>\n> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\n> index 2a93c64..c27aef4 100644\n> --- a/Documentation/git-rebase.txt\n> +++ b/Documentation/git-rebase.txt\n> @@ -384,7 +384,7 @@ or by giving more than one `--exec`:\n>  +\n>  If `--autosquash` is used, \"exec\" lines will not be appended for\n>  the intermediate commits, and will only appear at the end of each\n> -squash/fixup series.\n> +squash/fixup/ack series.\n>\n>  --root::\n>         Rebase all commits reachable from <branch>, instead of\n> @@ -398,13 +398,13 @@ squash/fixup series.\n>\n>  --autosquash::\n>  --no-autosquash::\n> -       When the commit log message begins with \"squash! ...\" (or\n> -       \"fixup! ...\"), and there is a commit whose title begins with\n> +       When the commit log message begins with \"squash! ...\" (\"fixup! ...\"\n> +       or \"ack! ...\"), and there is a commit whose title begins with\n>         the same ..., automatically modify the todo list of rebase -i\n>         so that the commit marked for squashing comes right after the\n>         commit to be modified, and change the action of the moved\n> -       commit from `pick` to `squash` (or `fixup`).  Ignores subsequent\n> -       \"fixup! \" or \"squash! \" after the first, in case you referred to an\n> +       commit from `pick` to `squash` (`fixup` or `ack`).  Ignores subsequent\n> +       \"ack! \", \"fixup! \" or \"squash! \" after the first, in case you referred to an\n>         earlier fixup/squash with `git commit --fixup/--squash`.\n>  +\n>  This option is only valid when the '--interactive' option is used.\n> @@ -624,6 +624,41 @@ consistent (they compile, pass the testsuite, etc.) you should use\n>  'git stash' to stash away the not-yet-committed changes\n>  after each commit, test, and amend the commit if fixes are necessary.\n>\n> +----------------\n> +RECORDING ACKS\n> +----------------\n> +\n> +Interactive mode with --autosquash can be used to concatenate\n> +commit log for several commits, which is useful to record\n> +extra information about the commit, such as ack signatures.\n> +This allows, for example, the following workflow:\n> +\n> +1. receive patches by mail and commit\n> +2. receive by mail ack signatures for the patches\n> +3. prepare a series for submission\n> +4. submit\n> +\n> +where point 2. consists of several instances of\n> +       i) create a (possibly empty) commit with signature\n> +         in the commit message\n> +\n> +Sometimes the ack signature added in i. cannot be amended to the\n> +commit it acks, because that commit is buried deeply in a\n> +patch series.  That is exactly what rebase --autosquash\n> +option is for: use it\n> +after plenty of \"i\"s, to automaticlly rearrange\n> +commits, and squashing multiple sign-off commits into\n> +the commit that is signed.\n> +\n> +Start it with the last commit you want to retain as-is:\n> +\n> +       git rebase --autosquash -i <after-this-commit>\n> +\n> +An editor will be fired up with all the commits in your current branch\n> +which come after the given commit. Ack commits will be\n> +re-arranged to come after the commit that is acked,\n> +and the action will be utomticlly changed from `pick` to `ack`\n\ns/utomticlly/automatically/\n\n> +to cause them to be squashed into the acked commit.\n>\n>  RECOVERING FROM UPSTREAM REBASE\n>  -------------------------------\n> --\n> MST\n>\n"},{"id":"242207","messageId":"xmqq4n0lwizh.fsf@gitster.dls.corp.google.com","threadId":"36690","inReplyTo":"1400447743-18513-4-git-send-email-mst@redhat.com","subject":"Re: [PATCH 3/4] rebase: test ack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-05-19T21:34:26Z","receivedAt":"2014-05-19T21:34:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Michael S. Tsirkin\" <mst@redhat.com> writes:\n\n> test ack! handling\n>\n> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>\n\nWill queue with this squashed in.\n\n4/4 seems to have some style issues as well, but I didn't look very\nclosely.\n\nThanks.\n\n t/t3415-rebase-autosquash.sh | 12 ++++++------\n 1 file changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh\nindex 9d7db13..dcdba6f 100755\n--- a/t/t3415-rebase-autosquash.sh\n+++ b/t/t3415-rebase-autosquash.sh\n@@ -75,18 +75,18 @@ test_expect_success 'auto squash (option)' '\n '\n \n test_expect_success 'auto ack' '\n-\tack=\"Acked-by: xyz\"\n-\tmsg=$(test_write_lines \"ack! first commit\" \"\" \"$ack\")\n+\tack=\"Acked-by: xyz\" &&\n+\tmsg=$(test_write_lines \"ack! first commit\" \"\" \"$ack\") &&\n \tgit reset --hard base &&\n \tgit commit --allow-empty -m \"$msg\" -- &&\n \tgit tag ack &&\n \ttest_tick &&\n \tgit rebase --autosquash -i HEAD^^^ &&\n \tgit log --oneline >actual &&\n-\tgit show -s first-commit | grep -v ^commit > expected-msg &&\n-\techo \"    $ack\" >> expected-msg &&\n-\tgit show -s HEAD^ | grep -v ^commit > actual-msg &&\n-\tdiff actual-msg expected-msg\n+\tgit show -s first-commit | grep -v ^commit >expected-msg &&\n+\techo \"    $ack\" >>expected-msg &&\n+\tgit show -s HEAD^ | grep -v ^commit >actual-msg &&\n+\ttest_cmp actual-msg expected-msg\n '\n \n test_expect_success 'auto squash (config)' '\n"},{"id":"242211","messageId":"20140519224054.GB29605@redhat.com","threadId":"36690","inReplyTo":"xmqq4n0lwizh.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 3/4] rebase: test ack","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-19T22:40:54Z","receivedAt":"2014-05-19T22:40:54Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"On Mon, May 19, 2014 at 02:34:26PM -0700, Junio C Hamano wrote:\n> \"Michael S. Tsirkin\" <mst@redhat.com> writes:\n> \n> > test ack! handling\n> >\n> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>\n> \n> Will queue with this squashed in.\n\nThanks! And sorry about the style issues.\n\n> 4/4 seems to have some style issues as well, but I didn't look very\n> closely.\n\nI'll try to clean it for the next submission.\nI'll be glad to hear about them as well.\nThanks!\n\n> Thanks.\n> \n>  t/t3415-rebase-autosquash.sh | 12 ++++++------\n>  1 file changed, 6 insertions(+), 6 deletions(-)\n> \n> diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh\n> index 9d7db13..dcdba6f 100755\n> --- a/t/t3415-rebase-autosquash.sh\n> +++ b/t/t3415-rebase-autosquash.sh\n> @@ -75,18 +75,18 @@ test_expect_success 'auto squash (option)' '\n>  '\n>  \n>  test_expect_success 'auto ack' '\n> -\tack=\"Acked-by: xyz\"\n> -\tmsg=$(test_write_lines \"ack! first commit\" \"\" \"$ack\")\n> +\tack=\"Acked-by: xyz\" &&\n> +\tmsg=$(test_write_lines \"ack! first commit\" \"\" \"$ack\") &&\n>  \tgit reset --hard base &&\n>  \tgit commit --allow-empty -m \"$msg\" -- &&\n>  \tgit tag ack &&\n>  \ttest_tick &&\n>  \tgit rebase --autosquash -i HEAD^^^ &&\n>  \tgit log --oneline >actual &&\n> -\tgit show -s first-commit | grep -v ^commit > expected-msg &&\n> -\techo \"    $ack\" >> expected-msg &&\n> -\tgit show -s HEAD^ | grep -v ^commit > actual-msg &&\n> -\tdiff actual-msg expected-msg\n> +\tgit show -s first-commit | grep -v ^commit >expected-msg &&\n> +\techo \"    $ack\" >>expected-msg &&\n> +\tgit show -s HEAD^ | grep -v ^commit >actual-msg &&\n> +\ttest_cmp actual-msg expected-msg\n>  '\n>  \n>  test_expect_success 'auto squash (config)' '\n"},{"id":"242268","messageId":"20140520143850.GA13099@redhat.com","threadId":"36690","inReplyTo":"xmqq4n0lwizh.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 3/4] rebase: test ack","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-20T14:38:50Z","receivedAt":"2014-05-20T14:38:50Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"On Mon, May 19, 2014 at 02:34:26PM -0700, Junio C Hamano wrote:\n> \"Michael S. Tsirkin\" <mst@redhat.com> writes:\n> \n> > test ack! handling\n> >\n> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>\n> \n> Will queue with this squashed in.\n> \n> 4/4 seems to have some style issues as well, but I didn't look very\n> closely.\n> \n> Thanks.\n\nJust to clarify I can post v2 of 4/4 without reposting 1-3 since they\nare queued?\n\n>  t/t3415-rebase-autosquash.sh | 12 ++++++------\n>  1 file changed, 6 insertions(+), 6 deletions(-)\n> \n> diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh\n> index 9d7db13..dcdba6f 100755\n> --- a/t/t3415-rebase-autosquash.sh\n> +++ b/t/t3415-rebase-autosquash.sh\n> @@ -75,18 +75,18 @@ test_expect_success 'auto squash (option)' '\n>  '\n>  \n>  test_expect_success 'auto ack' '\n> -\tack=\"Acked-by: xyz\"\n> -\tmsg=$(test_write_lines \"ack! first commit\" \"\" \"$ack\")\n> +\tack=\"Acked-by: xyz\" &&\n> +\tmsg=$(test_write_lines \"ack! first commit\" \"\" \"$ack\") &&\n>  \tgit reset --hard base &&\n>  \tgit commit --allow-empty -m \"$msg\" -- &&\n>  \tgit tag ack &&\n>  \ttest_tick &&\n>  \tgit rebase --autosquash -i HEAD^^^ &&\n>  \tgit log --oneline >actual &&\n> -\tgit show -s first-commit | grep -v ^commit > expected-msg &&\n> -\techo \"    $ack\" >> expected-msg &&\n> -\tgit show -s HEAD^ | grep -v ^commit > actual-msg &&\n> -\tdiff actual-msg expected-msg\n> +\tgit show -s first-commit | grep -v ^commit >expected-msg &&\n> +\techo \"    $ack\" >>expected-msg &&\n> +\tgit show -s HEAD^ | grep -v ^commit >actual-msg &&\n> +\ttest_cmp actual-msg expected-msg\n>  '\n>  \n>  test_expect_success 'auto squash (config)' '\n"},{"id":"242274","messageId":"xmqqvbt01o14.fsf@gitster.dls.corp.google.com","threadId":"36690","inReplyTo":"20140520143850.GA13099@redhat.com","subject":"Re: [PATCH 3/4] rebase: test ack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-05-20T15:13:27Z","receivedAt":"2014-05-20T15:13:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Michael S. Tsirkin\" <mst@redhat.com> writes:\n\n> Just to clarify I can post v2 of 4/4 without reposting 1-3 since they\n> are queued?\n\nIf you need to update anything queued only on 'pu' but not yet in\n'next', it is customary to resend the whole for everybody to see\n(what is already in 'next' should only be built upon incrementally\nand not updated with replacement patches), while noting which ones\nare the same as before.  Christian Couder has been doing it nicely\nin his recent rerolls (if the series were not in 'next', that is).\n\nThanks.\n"},{"id":"242373","messageId":"20140521125246.GA21476@redhat.com","threadId":"36690","inReplyTo":"xmqqvbt01o14.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 3/4] rebase: test ack","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-21T12:52:46Z","receivedAt":"2014-05-21T12:52:46Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"On Tue, May 20, 2014 at 08:13:27AM -0700, Junio C Hamano wrote:\n> \"Michael S. Tsirkin\" <mst@redhat.com> writes:\n> \n> > Just to clarify I can post v2 of 4/4 without reposting 1-3 since they\n> > are queued?\n> \n> If you need to update anything queued only on 'pu' but not yet in\n> 'next', it is customary to resend the whole for everybody to see\n> (what is already in 'next' should only be built upon incrementally\n> and not updated with replacement patches), while noting which ones\n> are the same as before.  Christian Couder has been doing it nicely\n> in his recent rerolls (if the series were not in 'next', that is).\n> \n> Thanks.\n\nActually I don't see anything like it in pu.\nWhat I would like is for 1-3 to be in pu,\n4/4 was for illustrative purposes it's not yet\nready for that, and 1-3 are useful by themselves.\nI could then iterate on 4/4 without reposting 1-3.\n"},{"id":"242387","messageId":"xmqqioozqdgo.fsf@gitster.dls.corp.google.com","threadId":"36690","inReplyTo":"20140521125246.GA21476@redhat.com","subject":"Re: [PATCH 3/4] rebase: test ack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-05-21T16:54:47Z","receivedAt":"2014-05-21T16:54:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Michael S. Tsirkin\" <mst@redhat.com> writes:\n\n> On Tue, May 20, 2014 at 08:13:27AM -0700, Junio C Hamano wrote:\n>> \"Michael S. Tsirkin\" <mst@redhat.com> writes:\n>> \n>> > Just to clarify I can post v2 of 4/4 without reposting 1-3 since they\n>> > are queued?\n>> \n>> If you need to update anything queued only on 'pu' but not yet in\n>> 'next', it is customary to resend the whole for everybody to see\n>> (what is already in 'next' should only be built upon incrementally\n>> and not updated with replacement patches), while noting which ones\n>> are the same as before.  Christian Couder has been doing it nicely\n>> in his recent rerolls (if the series were not in 'next', that is).\n>> \n>> Thanks.\n>\n> Actually I don't see anything like it in pu.\n\nThe way I usually work is to apply a non-fix (i.e. enhancement)\nseries on a topic branch forked from 'master' (or the last tagged\nversion contained in its tip) and see if it makes sense, and then\ntry-merge the result to 'next' to see if it is free of potential\nfunny interactions with other topics that are already in flight.\nAfter that happens, the topic branch is merged to somewhere in 'pu'.\n\nIt is possible that I did not have time to go through all the steps\nabove (after all, I had to make another -rc release and there was an\nunexpected last-minute change of plans in the morning that blew a\nfew hours of work).  Or there may have been some merge conflicts\nthat I didn't feel like resolving for various reasons (e.g. if I\nknew the series would be rerolled anyway, it can wait; if the other\ntopic that interacts with your series has been cooking sufficiently\nlong in 'next' and if it is very close to the final release of this\ncycle, it may be easier to wait for the other topic to graduate to\n'master', which would happen soon after this cycle finishes, and ask\nyou to rebase your series).\n\nI don't remember which ;-)\n"},{"id":"242397","messageId":"20140521173950.GA24564@redhat.com","threadId":"36690","inReplyTo":"xmqqioozqdgo.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 3/4] rebase: test ack","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-05-21T17:39:50Z","receivedAt":"2014-05-21T17:39:50Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"On Wed, May 21, 2014 at 09:54:47AM -0700, Junio C Hamano wrote:\n> \"Michael S. Tsirkin\" <mst@redhat.com> writes:\n> \n> > On Tue, May 20, 2014 at 08:13:27AM -0700, Junio C Hamano wrote:\n> >> \"Michael S. Tsirkin\" <mst@redhat.com> writes:\n> >> \n> >> > Just to clarify I can post v2 of 4/4 without reposting 1-3 since they\n> >> > are queued?\n> >> \n> >> If you need to update anything queued only on 'pu' but not yet in\n> >> 'next', it is customary to resend the whole for everybody to see\n> >> (what is already in 'next' should only be built upon incrementally\n> >> and not updated with replacement patches), while noting which ones\n> >> are the same as before.  Christian Couder has been doing it nicely\n> >> in his recent rerolls (if the series were not in 'next', that is).\n> >> \n> >> Thanks.\n> >\n> > Actually I don't see anything like it in pu.\n> \n> The way I usually work is to apply a non-fix (i.e. enhancement)\n> series on a topic branch forked from 'master' (or the last tagged\n> version contained in its tip) and see if it makes sense, and then\n> try-merge the result to 'next' to see if it is free of potential\n> funny interactions with other topics that are already in flight.\n> After that happens, the topic branch is merged to somewhere in 'pu'.\n> \n> It is possible that I did not have time to go through all the steps\n> above (after all, I had to make another -rc release and there was an\n> unexpected last-minute change of plans in the morning that blew a\n> few hours of work).  Or there may have been some merge conflicts\n> that I didn't feel like resolving for various reasons (e.g. if I\n> knew the series would be rerolled anyway, it can wait; if the other\n> topic that interacts with your series has been cooking sufficiently\n> long in 'next' and if it is very close to the final release of this\n> cycle, it may be easier to wait for the other topic to graduate to\n> 'master', which would happen soon after this cycle finishes, and ask\n> you to rebase your series).\n> \n> I don't remember which ;-)\n> \n\nOh sorry, didn't mean to try to pressure you. I was just surprised\nnot to see it there. I know this applies cleanly to next so I'll just\nwait for 2.0 to be out.\n\n-- \nMST\n"},{"id":"242401","messageId":"xmqqoayrougt.fsf@gitster.dls.corp.google.com","threadId":"36690","inReplyTo":"20140521173950.GA24564@redhat.com","subject":"Re: [PATCH 3/4] rebase: test ack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-05-21T18:30:26Z","receivedAt":"2014-05-21T18:30:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Michael S. Tsirkin\" <mst@redhat.com> writes:\n\n> On Wed, May 21, 2014 at 09:54:47AM -0700, Junio C Hamano wrote:\n>> \"Michael S. Tsirkin\" <mst@redhat.com> writes:\n>> \n>> > On Tue, May 20, 2014 at 08:13:27AM -0700, Junio C Hamano wrote:\n>> >> \"Michael S. Tsirkin\" <mst@redhat.com> writes:\n>> >> \n>> >> > Just to clarify I can post v2 of 4/4 without reposting 1-3 since they\n>> >> > are queued?\n>> >> \n>> >> If you need to update anything queued only on 'pu' but not yet in\n>> >> 'next', it is customary to ...\n>> >\n>> > Actually I don't see anything like it in pu.\n>> ... \n> Oh sorry, didn't mean to try to pressure you. I was just surprised\n> not to see it there. I know this applies cleanly to next so I'll just\n> wait for 2.0 to be out.\n\nOh, no.  No pressure felt and no need to be sorry about anything.\n\nI described a preferred procedure when the topic appeared in 'pu',\nand I didn't answer your question for topics that are not even in\n'pu' yet.\n\nBeing in 'pu' and not in 'next' is not much different from not being\nin 'pu', so the preferred procedure is to send out the entire series\n(unless it is a large 47-patch series ;-) to give everybody another\nchance to comment, and it would be extra nice if you indicated which\nones are unchanged since the previous round to help those who did\nalready saw them.\n\nThanks.\n"},{"id":"243271","messageId":"538E5FF2.2080506@gmail.com","threadId":"36690","inReplyTo":"1400447743-18513-5-git-send-email-mst@redhat.com","subject":"Re: [PATCH 4/4] git-ack: record an ack","fromName":"Fabian Ruch","fromEmail":"bafain@gmail.com","sentAt":"2014-06-03T23:53:22Z","receivedAt":"2014-06-03T23:53:22Z","isPatch":true,"sender":{"key":"bafain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1150972?v=4"},"body":"Hi Michael,\n\nI have some inline comments below. Also, some parts of the patch do not\nadhere to the style rules\n\n - tabs for indentation\n - $(...) for command substitution\n - no space after redirection operators\n - double-quotes around redirection targets\n\nfor shell scripts (from the file `Documentation/CodingGuidelines`).\n\nOn 05/18/2014 11:17 PM, Michael S. Tsirkin wrote:\n> diff --git a/contrib/git-ack b/contrib/git-ack\n> new file mode 100755\n> index 0000000..4aeb16a\n> --- /dev/null\n> +++ b/contrib/git-ack\n> @@ -0,0 +1,84 @@\n> +msg=`mktemp`\n> +patch=`mktemp`\n> +info=`git mailinfo $msg $patch`\n> +subj=`echo \"$info\"|sed -n 's/^Subject: //p'`\n> +author=`echo \"$info\"|sed -n 's/^Author: //p'`\n> +email=`echo \"$info\"|sed -n 's/^Email: //p'`\n> +auth=\"$author <$email>\"\n> +date=`echo \"$info\"|sed -n 's/^Date: //p'`\n> +sign=`mktemp`\n> +echo \"ack! $subj\" > $sign\n> +echo \"\" >> $sign\n> +if\n> +    git diff --cached HEAD\n\nIf I am not mistaken, the exit code of `git-diff(1)` doesn't change\naccording to whether there are differences or not, unless the option\n`--exit-code` is given.\n\n> +then\n> +    nop < /dev/null\n\nIs it correct that this is a do-nothing operation? Is that a common\nidiom? I found the null command (`:`, colon) to be used in many places\ninstead.\n\n> +else\n> +    echo \"DIFF in cache. Not acked, reset or commit!\"\n> +    exit 1\n> +fi\n> +GIT_DIR=`pwd`/${GIT_DIR}\n\nThis seems incorrect to me. If `GIT_DIR` is already set, it might point\nto an absolute path and not `.git`. If the environment variable is not\nset, the state file `ACKS` ends up in the working directory.\n\nMaybe `git-sh-setup(1)` can be of help. It uses\n\n    git rev-parse --git-dir\n\nto probe the path to the .git directory.\n\n> +\n> +usage () {\n> +\techo \"Usage: git ack \" \\\n> +            \"[-s|--save|-a|--append|-r|--restore |-c|--clear]\\n\" >& 2;\n> +        exit 1;\n> +}\n> +\n> +append=\n> +save=\n> +clear=\n\nThe restore flag seems to be missing from this list of declarations.\n\n> +\n> +while test $# != 0\n> +do\n> +\tcase \"$1\" in\n> +\t-a|--append)\n> +\t\tappend=\"y\"\n> +\t\t;;\n> +\t-s|--s)\n> +\t\tsave=\"y\"\n> +\t\t;;\n> +\t-r|--restore)\n> +\t\trestore=\"y\"\n> +\t\t;;\n> +\t-c|--clear)\n> +\t\tclear=\"y\"\n> +                ;;\n> +\t*)\n> +\t\tusage ;;\n> +\tesac\n> +\tshift\n> +done\n> +\n> +if\n> +    test \"$clear\"\n> +then\n> +    rm -f \"${GIT_DIR}/ACKS\"\n> +fi\n> +\n> +if\n> +    test \"$save\"\n> +then\n> +    if\n> +        test \"$append\"\n> +    then\n> +        cat $msg >> \"${GIT_DIR}/ACKS\"\n> +    else\n> +        cat $msg > \"${GIT_DIR}/ACKS\"\n> +    fi\n> +fi\n> +\n> +if\n> +    test \"$restore\"\n> +then\n> +    msg = ${GIT_DIR}/ACKS\n> +fi\n> +\n> +if\n> +    grep '^[A-Z][A-Za-z-]*-by:' $msg >> $sign\n> +then\n> +    git commit --allow-empty -F $sign --author=\"$auth\" --date=\"$date\"\n> +else\n> +    echo \"No signature found!\"\n> +    exit 2\n> +fi\n\n   Fabian\n"},{"id":"243881","messageId":"53980DDA.1040407@gmail.com","threadId":"36690","inReplyTo":"1400447743-18513-1-git-send-email-mst@redhat.com","subject":"Re: [PATCH 0/4] ack recoding in commit log","fromName":"Fabian Ruch","fromEmail":"bafain@gmail.com","sentAt":"2014-06-11T08:05:46Z","receivedAt":"2014-06-11T08:05:46Z","isPatch":true,"sender":{"key":"bafain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1150972?v=4"},"body":"Hi Michael,\n\nOn 05/18/2014 11:17 PM, Michael S. Tsirkin wrote:\n> As a maintainer, I often get patches by mail, then\n> acked-by,reviewed-by etc responses are sent by separate\n> mail.\n> \n> I like making acks commits,\n> this way they are easy to keep track of\n> as part of git history.\n\nIn order to fully understand your additions, I think, I need some\nclarification on the term \"ack commit\". What is an ack commit exactly?\nSuppose our principal commit has the commit message\n\n    Some changes\n\n    The changes are...\n\n    Signed-off-by: A U Thor <author@example.com>\n\nand we receive an email from Somebody saying\n\n    > Some changes\n    >\n    > The changes are...\n    >\n    > Signed-off-by: A U Thor <author@example.com>\n\n    Reviewed-by: Somebody <somebody@example.com>\n\n. Now, if I understand correctly, we create an empty commit on top of\nthe principal commit using the following commit message.\n\n    Some changes\n\n    Reviewed-by: Somebody <somebody@example.com>\n\nIs this commit then called an ack commit?\n\nCan an ack commit be non-empty?\n\nIs a commit still an ack if its description mentions additional text\nbetween the subject and the tag lines?\n\nMaybe the ack command for todo lists and ack commits have little to do\nwith one another. If we stick to the term \"ack commit\", then the command\nname suggests that it takes the tags from some commit b and appends them\nto the list of tags in the previous commit's (a) message:\n\n    pick a A commit\n    ack  b The next commit\n\nHowever, this obviously does not work by just appending messages. For\ninstance, there could be additional text before or after some tag line\nin either commit message. If we treat the workflow you described as a\nvery specific use case of the ack command instead, it seems reasonable\nto add such a todo list functionality for melding commits by silently\nappending messages. However, we might consider parametrizing a single\nsquash command instead of defining just another name that one has to\nkeep in mind for melding commits:\n\n    pick             a A commit\n    squash --no-edit b The next commit\n\n> Since response mail happens to have appropriate\n> subject matching the patch, it's a natural fit to\n> then use git rebase mechanics if we want to smash\n> these acks into the original commit.\n> \n> I have been using these patches without any problems\n> for a while now, and find the approach very convenient.\n> \n> Included:\n> \trebase: new ack! action to handle ack commits\n> \t\tthis part seems ready for merge to me,\n> \t\tplease review and comment\n> \n> \tgit-ack: new tool to record an ack\n> \t\tthis does not have proper documentation\n> \t\tand tests yet, I definitely intend to\n> \t\tdo this but wanted to see whether people\n> \t\tlike the UI first.\n> \t\tposting for early review and feedback\n> \n> [..]\n\nThanks for your time,\n   Fabian\n"},{"id":"243885","messageId":"20140611084648.GD7248@redhat.com","threadId":"36690","inReplyTo":"53980DDA.1040407@gmail.com","subject":"Re: [PATCH 0/4] ack recoding in commit log","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2014-06-11T08:46:48Z","receivedAt":"2014-06-11T08:46:48Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"On Wed, Jun 11, 2014 at 10:05:46AM +0200, Fabian Ruch wrote:\n> Hi Michael,\n> \n> On 05/18/2014 11:17 PM, Michael S. Tsirkin wrote:\n> > As a maintainer, I often get patches by mail, then\n> > acked-by,reviewed-by etc responses are sent by separate\n> > mail.\n> > \n> > I like making acks commits,\n> > this way they are easy to keep track of\n> > as part of git history.\n> \n> In order to fully understand your additions, I think, I need some\n> clarification on the term \"ack commit\".\n\nI think the two additions should be judged separately, they aren't\nrelated.\n\nSo I am not sure we need to spend time discussing\nwhat is an ack commit.\n\nWhat I mean is that I prefer using git history for\nrecording activity, and git rebase for modifying\nhistory.\nI think I am not alone in this.\n\nTo record acks, I wrote this tool to\ncreate empty commits, that only record log\nchanges. They are named specially such that\nrebase knows not to discard them, and to\nautomate the editing stage.\n\nI added some features to the tool since.\nDid not yet address all comments I got here, but just in case\nyou are curious it's attached at the end.\n\n> What is an ack commit exactly?\n> Suppose our principal commit has the commit message\n> \n>     Some changes\n> \n>     The changes are...\n> \n>     Signed-off-by: A U Thor <author@example.com>\n> \n> and we receive an email from Somebody saying\n> \n>     > Some changes\n>     >\n>     > The changes are...\n>     >\n>     > Signed-off-by: A U Thor <author@example.com>\n> \n>     Reviewed-by: Somebody <somebody@example.com>\n\nOther possible cases I handle:\n    people reply with:\n\n    For the series:\n        Reviewed-by: Somebody <somebody@example.com>\n\nThis uses the save/restore flags.\n\nor an informal\n    Ack the series\n(this one I handle by creating ACKS file manually,\n then applying it with git ack restore)\n\nSomeone sends a fixup! patch, and someone else\nreplies to the fixup with Reviewed-by: tag.\n(this was not handled correctly in the version\nyou reviewed, I attach latest one below where it is\nhandled correctly).\n\n\n> . Now, if I understand correctly, we create an empty commit on top of\n> the principal commit using the following commit message.\n> \n>     Some changes\n> \n>     Reviewed-by: Somebody <somebody@example.com>\n> \n> Is this commit then called an ack commit?\n\ngit ack creates commits like this:\n\n----\nack! Some changes\n\nReviewed-by: Somebody <somebody@example.com>\n---\n\nOther work-flows\n\n\n> Can an ack commit be non-empty?\n\nAt the moment git ack does not create non empty commits.\n\n> Is a commit still an ack if its description mentions additional text\n> between the subject and the tag lines?\n\nAt the moment git ack does not create such commits.\n\n> Maybe the ack command for todo lists and ack commits have little to do\n> with one another.\n\nI use them together but ack command is more powerful than git ack.\nSame as commit --fixup, that is not the only way to\nuse fixup!.\n\n\n> If we stick to the term \"ack commit\", then the command\n> name suggests that it takes the tags from some commit b and appends them\n> to the list of tags in the previous commit's (a) message:\n> \n>     pick a A commit\n>     ack  b The next commit\n> \n> However, this obviously does not work by just appending messages. For\n> instance, there could be additional text before or after some tag line\n> in either commit message. If we treat the workflow you described as a\n> very specific use case of the ack command instead, it seems reasonable\n> to add such a todo list functionality for melding commits by silently\n> appending messages. However, we might consider parametrizing a single\n> squash command instead of defining just another name that one has to\n> keep in mind for melding commits:\n\nHmm, I don't see why is flag any easier to remember than a separate command\nfrankly, and there's help text at the end to remind you.\n\n> \n>     pick             a A commit\n>     squash --no-edit b The next commit\n\nThat's too much typing I think, I just want to use a\nsingle letter.\nYou could argue the same thing for fixup right?\nIt's really squash but discards the log, and there\nis no requirement that it fixes anything, it can\nadd functionality or whatever.\nSo why not\nsquash --discardlog b The next commit\n\nI think that would be bad usability, and so would --no-edit.\n\n--no-edit also does not convey the fact that it allows\nempty commits.\n\n\nI don't mind renaming the command to something else\nbut I could not come up with a better name so far.\n\n> > Since response mail happens to have appropriate\n> > subject matching the patch, it's a natural fit to\n> > then use git rebase mechanics if we want to smash\n> > these acks into the original commit.\n> > \n> > I have been using these patches without any problems\n> > for a while now, and find the approach very convenient.\n> > \n> > Included:\n> > \trebase: new ack! action to handle ack commits\n> > \t\tthis part seems ready for merge to me,\n> > \t\tplease review and comment\n> > \n> > \tgit-ack: new tool to record an ack\n> > \t\tthis does not have proper documentation\n> > \t\tand tests yet, I definitely intend to\n> > \t\tdo this but wanted to see whether people\n> > \t\tlike the UI first.\n> > \t\tposting for early review and feedback\n> > \n> > [..]\n> \n> Thanks for your time,\n>    Fabian\n\n\n## latest git-ack\n## changes: handle fixup!/squash!/ack! messages in mail\n\nmsg=`mktemp`\npatch=`mktemp`\ninfo=`git mailinfo $msg $patch`\nsubj=`echo \"$info\"|sed -n 's/^Subject: //p'`\n#strip ack!/fixup!/squash! prefix\nsubj=`echo \"$subj\"|sed \"s/^fixup![ \t]*//\"`\nsubj=`echo \"$subj\"|sed \"s/^squash![ \t]*//\"`\nsubj=`echo \"$subj\"|sed \"s/^ack![ \t]*//\"`\nauthor=`echo \"$info\"|sed -n 's/^Author: //p'`\nemail=`echo \"$info\"|sed -n 's/^Email: //p'`\nauth=\"$author <$email>\"\ndate=`echo \"$info\"|sed -n 's/^Date: //p'`\nsign=`mktemp`\necho \"ack! $subj\" > $sign\necho \"\" >> $sign\nif\n    git diff --cached HEAD\nthen\n    nop < /dev/null\nelse\n    echo \"DIFF in cache. Not acked, reset or commit!\"\n    exit 1\nfi\nGIT_DIR=`pwd`/.git\n\nusage () {\n\techo \"Usage: git ack \" \\\n            \"[-s|--save|-a|--append|-r|--restore |-c|--clear]\\n\" >& 2;\n        exit 1;\n}\n\nappend=\nsave=\nclear=\n\nwhile test $# != 0\ndo\n\tcase \"$1\" in\n\t-a|--append)\n\t\tappend=\"y\"\n\t\t;;\n\t-s|--s)\n\t\tsave=\"y\"\n\t\t;;\n\t-r|--restore)\n\t\trestore=\"y\"\n\t\t;;\n\t-c|--clear)\n\t\tclear=\"y\"\n                ;;\n\t*)\n\t\tusage ;;\n\tesac\n\tshift\ndone\n\nif\n    test \"$clear\"\nthen\n    rm -f \"${GIT_DIR}/ACKS\"\nfi\n\nif\n    test \"$save\"\nthen\n    if\n        test \"$append\"\n    then\n        cat $msg >> \"${GIT_DIR}/ACKS\"\n    else\n        cat $msg > \"${GIT_DIR}/ACKS\"\n    fi\nfi\n\nif\n    test \"$restore\"\nthen\n    msg=${GIT_DIR}/ACKS\nfi\n\necho $msg > /dev/tty\nif\n    grep '^[A-Z][A-Za-z-]*-by:' $msg >> $sign\nthen\n    git commit --allow-empty -F $sign --author=\"$auth\" --date=\"$date\"\nelse\n    echo \"No signature found!\"\n    exit 2\nfi\n"}]}