{"thread":{"id":"22217","subject":"[PATCH 00/18] rebase -i: For pure fixups, do not start log message editor","startedAt":"2010-01-14T05:54:39Z","lastAt":"2010-01-26T13:11:03Z","messageCount":34,"participants":["Michael Haggerty","Johannes Sixt","Junio C Hamano","Eric Blake","Paolo Bonzini","Greg Price","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":18},"messages":[{"id":"131584","messageId":"cover.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":null,"subject":"[PATCH 00/18] rebase -i: For pure fixups, do not start log message editor","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:39Z","receivedAt":"2010-01-14T05:54:39Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"This patch series is a successor to mh/rebase-fixup, which causes\n\"rebase -i\" to skip opening the log message editor when processing a\nblock of \"fixup\" commands that does not include any \"squash\"es.  The\nidea was discussed on the mailing list [1] to general approval.\n\nThis patch series applies to \"next\", as it depends on earlier commits\nin mh/rebase-fixup.  With this patch series, I believe that this topic\nis finished.\n\nThe first several commits are trivial fixups.\n\nThe three commits starting with \"Document how temporary files are\nused\" attempt to document how the existing git-rebase--interactive.sh\nscript uses temporary files, as that information was not obvious.  I\nwould appreciate feedback about whether I have inferred the uses\ncorrectly.\n\nFollowing are several refactorings leading to the main point of this\npatch series, \"For fixup commands without squashes, do not start\neditor\".\n\nI also noticed a related (pre-existing) bug, namely that when there is\na conflict during the processing of a \"squash\" series, the user is\nsometimes asked to edit an intermediate commit message.  But after\nlater squashes are processed, the user's edited message is discarded.\nThe last two patches fix this problem--whenever the user has edited a\ncommit message, the resulting combined commit is treated (internally)\nas a new starting point for further squash/fixups.  As such, the\nuser-edited commit message is the first part of the suggested commit\nmessage for the final squashed/fixedup commit.\n\nMichael\n\n[1] http://article.gmane.org/gmane.comp.version-control.git/134510\n\nMichael Haggerty (18):\n  rebase -i: Make the condition for an \"if\" more transparent\n  rebase -i: Remove dead code\n  rebase -i: Inline expression\n  rebase -i: Use \"test -n\" instead of \"test ! -z\"\n  rebase -i: Use symbolic constant $MSG consistently\n  rebase -i: Document how temporary files are used\n  rebase -i: Introduce a constant AUTHOR_SCRIPT\n  rebase -i: Introduce a constant AMEND\n  t3404: Test the commit count in commit messages generated by \"rebase\n    -i\"\n  rebase -i: Improve consistency of commit count in generated commit\n    messages\n  rebase -i: Simplify commit counting for generated commit messages\n  rebase -i: Extract a function \"commit_message\"\n  rebase -i: Handle the author script all in one place in do_next\n  rebase -i: Extract function do_with_author\n  rebase -i: Change function make_squash_message into\n    update_squash_message\n  rebase -i: For fixup commands without squashes, do not start editor\n  t3404: Set up more of the test repo in the \"setup\" step\n  rebase -i: Retain user-edited commit messages after squash/fixup\n    conflicts\n\n git-rebase--interactive.sh    |  224 ++++++++++++++++++++++++++---------------\n t/lib-rebase.sh               |    6 +-\n t/t3404-rebase-interactive.sh |  101 +++++++++++++------\n 3 files changed, 219 insertions(+), 112 deletions(-)\n"},{"id":"131596","messageId":"aa37ee8a68d460df172b23b4999fbe4ce7d77c1e.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 01/18] rebase -i: Make the condition for an \"if\" more transparent","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:40Z","receivedAt":"2010-01-14T05:54:40Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Test $no_ff separately rather than testing it indirectly by gluing it\nonto a comparison of two SHA1s.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |    3 ++-\n 1 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 2e56e64..fba8fb6 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -166,7 +166,8 @@ pick_one () {\n \tparent_sha1=$(git rev-parse --verify $sha1^) ||\n \t\tdie \"Could not get the parent of $sha1\"\n \tcurrent_sha1=$(git rev-parse --verify HEAD)\n-\tif test \"$no_ff$current_sha1\" = \"$parent_sha1\"; then\n+\tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n+\tthen\n \t\toutput git reset --hard $sha1\n \t\ttest \"a$1\" = a-n && output git reset --soft $current_sha1\n \t\tsha1=$(git rev-parse --short $sha1)\n-- \n1.6.6\n"},{"id":"131585","messageId":"affe8160c091f8f329b4bbc16d7c9641b1483296.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 02/18] rebase -i: Remove dead code","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:41Z","receivedAt":"2010-01-14T05:54:41Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"This branch of the \"if\" is only executed if $no_ff is empty, which\nonly happens if $1 was not '-n'.  (This code has been dead since\n1d25c8cf82eead72e11287d574ef72d3ebec0db1.)\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |    1 -\n 1 files changed, 0 insertions(+), 1 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex fba8fb6..c6174bb 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -169,7 +169,6 @@ pick_one () {\n \tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n \tthen\n \t\toutput git reset --hard $sha1\n-\t\ttest \"a$1\" = a-n && output git reset --soft $current_sha1\n \t\tsha1=$(git rev-parse --short $sha1)\n \t\toutput warn Fast-forward to $sha1\n \telse\n-- \n1.6.6\n"},{"id":"131586","messageId":"487578e19c491360d2a957603db778faa4e3188d.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 03/18] rebase -i: Inline expression","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:42Z","receivedAt":"2010-01-14T05:54:42Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Inline expression when generating output rather than overwriting the\n\"sha1\" local variable with a short SHA1.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |    3 +--\n 1 files changed, 1 insertions(+), 2 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex c6174bb..3b65cdf 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -169,8 +169,7 @@ pick_one () {\n \tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n \tthen\n \t\toutput git reset --hard $sha1\n-\t\tsha1=$(git rev-parse --short $sha1)\n-\t\toutput warn Fast-forward to $sha1\n+\t\toutput warn Fast-forward to $(git rev-parse --short $sha1)\n \telse\n \t\toutput git cherry-pick \"$@\"\n \tfi\n-- \n1.6.6\n"},{"id":"131600","messageId":"8f2d7bbf4aee7e0e7bfb1b32843430c3cb3b0e11.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 04/18] rebase -i: Use \"test -n\" instead of \"test ! -z\"","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:43Z","receivedAt":"2010-01-14T05:54:43Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"It is a tiny bit simpler.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 3b65cdf..6dbc64e 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -158,7 +158,7 @@ pick_one () {\n \toutput git rev-parse --verify $sha1 || die \"Invalid commit name: $sha1\"\n \ttest -d \"$REWRITTEN\" &&\n \t\tpick_one_preserving_merges \"$@\" && return\n-\tif test ! -z \"$REBASE_ROOT\"\n+\tif test -n \"$REBASE_ROOT\"\n \tthen\n \t\toutput git cherry-pick \"$@\"\n \t\treturn\n-- \n1.6.6\n"},{"id":"131587","messageId":"1dc77ab5f378ce6fc41b01541fbf15c5ae037aa8.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 05/18] rebase -i: Use symbolic constant $MSG consistently","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:44Z","receivedAt":"2010-01-14T05:54:44Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"The filename constant $MSG was previously used in some places and\nwritten out literally in others.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |    8 ++++----\n 1 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 6dbc64e..b7e8189 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -131,8 +131,8 @@ make_patch () {\n \t\techo \"Root commit\"\n \t\t;;\n \tesac > \"$DOTEST\"/patch\n-\ttest -f \"$DOTEST\"/message ||\n-\t\tgit cat-file commit \"$1\" | sed \"1,/^$/d\" > \"$DOTEST\"/message\n+\ttest -f \"$MSG\" ||\n+\t\tgit cat-file commit \"$1\" | sed \"1,/^$/d\" > \"$MSG\"\n \ttest -f \"$DOTEST\"/author-script ||\n \t\tget_author_ident_from_commit \"$1\" > \"$DOTEST\"/author-script\n }\n@@ -343,7 +343,7 @@ peek_next_command () {\n }\n \n do_next () {\n-\trm -f \"$DOTEST\"/message \"$DOTEST\"/author-script \\\n+\trm -f \"$MSG\" \"$DOTEST\"/author-script \\\n \t\t\"$DOTEST\"/amend || exit\n \tread command sha1 rest < \"$TODO\"\n \tcase \"$command\" in\n@@ -611,7 +611,7 @@ first and then run 'git rebase --continue' again.\"\n \t\t\t\tdie \"Cannot rewind the HEAD\"\n \t\t\tfi\n \t\t\texport GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE &&\n-\t\t\tgit commit --no-verify -F \"$DOTEST\"/message -e || {\n+\t\t\tgit commit --no-verify -F \"$MSG\" -e || {\n \t\t\t\ttest -n \"$amend\" && git reset --soft $amend\n \t\t\t\tdie \"Could not commit staged changes.\"\n \t\t\t}\n-- \n1.6.6\n"},{"id":"131594","messageId":"ec177b9d2b2354c446793df42525b4f7377bc413.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 06/18] rebase -i: Document how temporary files are used","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:45Z","receivedAt":"2010-01-14T05:54:45Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Add documentation, inferred by reverse-engineering, about how\ngit-rebase--interactive.sh uses many of its temporary files.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |   41 ++++++++++++++++++++++++++++++++++-------\n 1 files changed, 34 insertions(+), 7 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex b7e8189..77e5773 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -35,11 +35,45 @@ autosquash         move commits that begin with squash!/fixup! under -i\n require_work_tree\n \n DOTEST=\"$GIT_DIR/rebase-merge\"\n+\n+# The file containing rebase commands, comments, and empty lines.\n+# This file is created by \"git rebase -i\" then edited by the user.  As\n+# the lines are processed, they are removed from the front of this\n+# file and written to the tail of $DONE.\n TODO=\"$DOTEST\"/git-rebase-todo\n+\n+# The rebase command lines that have already been processed.  A line\n+# is moved here when it is first handled, before any associated user\n+# actions.\n DONE=\"$DOTEST\"/done\n+\n+# The commit message that is planned to be used for any changes that\n+# need to be committed following a user interaction.\n MSG=\"$DOTEST\"/message\n+\n+# The file into which is accumulated the suggested commit message for\n+# squash/fixup commands.  When the first of a series of squash/fixups\n+# is seen, the file is created and the commit message from the\n+# previous commit and from the first squash/fixup commit are written\n+# to it.  The commit message for each subsequent squash/fixup commit\n+# is appended to the file as it is processed.\n+#\n+# The first line of the file is of the form\n+#     # This is a combination of $COUNT commits.\n+# where $COUNT is the number of commits whose messages have been\n+# written to the file so far (including the initial \"pick\" commit).\n+# Each time that a commit message is processed, this line is read and\n+# updated.  It is deleted just before the combined commit is made.\n SQUASH_MSG=\"$DOTEST\"/message-squash\n+\n+# $REWRITTEN is the name of a directory containing files for each\n+# commit that is reachable by at least one merge base of $HEAD and\n+# $UPSTREAM. They are not necessarily rewritten, but their children\n+# might be.  This ensures that commits on merged, but otherwise\n+# unrelated side branches are left alone. (Think \"X\" in the man page's\n+# example.)\n REWRITTEN=\"$DOTEST\"/rewritten\n+\n DROPPED=\"$DOTEST\"/dropped\n PRESERVE_MERGES=\n STRATEGY=\n@@ -738,13 +772,6 @@ first and then run 'git rebase --continue' again.\"\n \t\ttest t = \"$VERBOSE\" && : > \"$DOTEST\"/verbose\n \t\tif test t = \"$PRESERVE_MERGES\"\n \t\tthen\n-\t\t\t# $REWRITTEN contains files for each commit that is\n-\t\t\t# reachable by at least one merge base of $HEAD and\n-\t\t\t# $UPSTREAM. They are not necessarily rewritten, but\n-\t\t\t# their children might be.\n-\t\t\t# This ensures that commits on merged, but otherwise\n-\t\t\t# unrelated side branches are left alone. (Think \"X\"\n-\t\t\t# in the man page's example.)\n \t\t\tif test -z \"$REBASE_ROOT\"\n \t\t\tthen\n \t\t\t\tmkdir \"$REWRITTEN\" &&\n-- \n1.6.6\n"},{"id":"131601","messageId":"61d29b935d5c979df6eab9d8a69fd072577bc6b1.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 07/18] rebase -i: Introduce a constant AUTHOR_SCRIPT","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:46Z","receivedAt":"2010-01-14T05:54:46Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Add a constant AUTHOR_SCRIPT, holding the filename of the\n$DOTEST/author_script file, and document how this temporary file is\nused.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |   17 +++++++++++------\n 1 files changed, 11 insertions(+), 6 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 77e5773..6fcc00e 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -75,6 +75,12 @@ SQUASH_MSG=\"$DOTEST\"/message-squash\n REWRITTEN=\"$DOTEST\"/rewritten\n \n DROPPED=\"$DOTEST\"/dropped\n+\n+# A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n+# GIT_AUTHOR_DATE that will be used for the commit that is currently\n+# being rebased.\n+AUTHOR_SCRIPT=\"$DOTEST\"/author-script\n+\n PRESERVE_MERGES=\n STRATEGY=\n ONTO=\n@@ -167,8 +173,8 @@ make_patch () {\n \tesac > \"$DOTEST\"/patch\n \ttest -f \"$MSG\" ||\n \t\tgit cat-file commit \"$1\" | sed \"1,/^$/d\" > \"$MSG\"\n-\ttest -f \"$DOTEST\"/author-script ||\n-\t\tget_author_ident_from_commit \"$1\" > \"$DOTEST\"/author-script\n+\ttest -f \"$AUTHOR_SCRIPT\" ||\n+\t\tget_author_ident_from_commit \"$1\" > \"$AUTHOR_SCRIPT\"\n }\n \n die_with_patch () {\n@@ -377,8 +383,7 @@ peek_next_command () {\n }\n \n do_next () {\n-\trm -f \"$MSG\" \"$DOTEST\"/author-script \\\n-\t\t\"$DOTEST\"/amend || exit\n+\trm -f \"$MSG\" \"$AUTHOR_SCRIPT\" \"$DOTEST\"/amend || exit\n \tread command sha1 rest < \"$TODO\"\n \tcase \"$command\" in\n \t'#'*|''|noop)\n@@ -454,7 +459,7 @@ do_next () {\n \t\t\trm -f \"$GIT_DIR\"/MERGE_MSG || exit\n \t\t\t;;\n \t\tesac\n-\t\techo \"$author_script\" > \"$DOTEST\"/author-script\n+\t\techo \"$author_script\" > \"$AUTHOR_SCRIPT\"\n \t\tif test $failed = f\n \t\tthen\n \t\t\t# This is like --amend, but with a different message\n@@ -631,7 +636,7 @@ do\n \t\tthen\n \t\t\t: Nothing to commit -- skip this\n \t\telse\n-\t\t\t. \"$DOTEST\"/author-script ||\n+\t\t\t. \"$AUTHOR_SCRIPT\" ||\n \t\t\t\tdie \"Cannot find the author identity\"\n \t\t\tamend=\n \t\t\tif test -f \"$DOTEST\"/amend\n-- \n1.6.6\n"},{"id":"131588","messageId":"1c21ffc3b11bbba91822af52950056da8b6eff9a.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 08/18] rebase -i: Introduce a constant AMEND","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:47Z","receivedAt":"2010-01-14T05:54:47Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Add a constant AMEND holding the filename of the $DOTEST/amend file,\nand document how this temporary file is used.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |   16 ++++++++++++----\n 1 files changed, 12 insertions(+), 4 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 6fcc00e..2c7f3ec 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -81,6 +81,14 @@ DROPPED=\"$DOTEST\"/dropped\n # being rebased.\n AUTHOR_SCRIPT=\"$DOTEST\"/author-script\n \n+# When an \"edit\" rebase command is being processed, the SHA1 of the\n+# commit to be edited is recorded in this file.  When \"git rebase\n+# --continue\" is executed, if there are any staged changes then they\n+# will be amended to the HEAD commit, but only provided the HEAD\n+# commit is still the commit to be edited.  When any other rebase\n+# command is processed, this file is deleted.\n+AMEND=\"$DOTEST\"/amend\n+\n PRESERVE_MERGES=\n STRATEGY=\n ONTO=\n@@ -383,7 +391,7 @@ peek_next_command () {\n }\n \n do_next () {\n-\trm -f \"$MSG\" \"$AUTHOR_SCRIPT\" \"$DOTEST\"/amend || exit\n+\trm -f \"$MSG\" \"$AUTHOR_SCRIPT\" \"$AMEND\" || exit\n \tread command sha1 rest < \"$TODO\"\n \tcase \"$command\" in\n \t'#'*|''|noop)\n@@ -411,7 +419,7 @@ do_next () {\n \t\tpick_one $sha1 ||\n \t\t\tdie_with_patch $sha1 \"Could not apply $sha1... $rest\"\n \t\tmake_patch $sha1\n-\t\tgit rev-parse --verify HEAD > \"$DOTEST\"/amend\n+\t\tgit rev-parse --verify HEAD > \"$AMEND\"\n \t\twarn \"Stopped at $sha1... $rest\"\n \t\twarn \"You can amend the commit now, with\"\n \t\twarn\n@@ -639,10 +647,10 @@ do\n \t\t\t. \"$AUTHOR_SCRIPT\" ||\n \t\t\t\tdie \"Cannot find the author identity\"\n \t\t\tamend=\n-\t\t\tif test -f \"$DOTEST\"/amend\n+\t\t\tif test -f \"$AMEND\"\n \t\t\tthen\n \t\t\t\tamend=$(git rev-parse --verify HEAD)\n-\t\t\t\ttest \"$amend\" = $(cat \"$DOTEST\"/amend) ||\n+\t\t\t\ttest \"$amend\" = $(cat \"$AMEND\") ||\n \t\t\t\tdie \"\\\n You have uncommitted changes in your working tree. Please, commit them\n first and then run 'git rebase --continue' again.\"\n-- \n1.6.6\n"},{"id":"131602","messageId":"c3ec064944c4c5e6a3eba5c71e8956fe8bceb3ad.1263447037.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 09/18] t3404: Test the commit count in commit messages generated by \"rebase -i\"","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:48Z","receivedAt":"2010-01-14T05:54:48Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"The first line of commit messages generated for \"rebase -i\"\nsquash/fixup commits includes a count of the number of commits that\nare being combined.  Add machinery to check that this count is\ncorrect, and add such a check to some test cases.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n t/lib-rebase.sh               |    6 +++++-\n t/t3404-rebase-interactive.sh |    9 +++++++--\n 2 files changed, 12 insertions(+), 3 deletions(-)\n\ndiff --git a/t/lib-rebase.sh b/t/lib-rebase.sh\nindex 0db8250..2d922ae 100644\n--- a/t/lib-rebase.sh\n+++ b/t/lib-rebase.sh\n@@ -2,9 +2,10 @@\n \n # After setting the fake editor with this function, you can\n #\n-# - override the commit message with $FAKE_COMMIT_MESSAGE,\n+# - override the commit message with $FAKE_COMMIT_MESSAGE\n # - amend the commit message with $FAKE_COMMIT_AMEND\n # - check that non-commit messages have a certain line count with $EXPECT_COUNT\n+# - check the commit count in the commit message header with $EXPECT_HEADER_COUNT\n # - rewrite a rebase -i script as directed by $FAKE_LINES.\n #   $FAKE_LINES consists of a sequence of words separated by spaces.\n #   The following word combinations are possible:\n@@ -25,6 +26,9 @@ set_fake_editor () {\n \tcat >> fake-editor.sh <<\\EOF\n case \"$1\" in\n */COMMIT_EDITMSG)\n+\ttest -z \"$EXPECT_HEADER_COUNT\" ||\n+\t\ttest \"$EXPECT_HEADER_COUNT\" = $(sed -n '1s/^# This is a combination of \\(.*\\) commits\\./\\1/p' < \"$1\") ||\n+\t\texit\n \ttest -z \"$FAKE_COMMIT_MESSAGE\" || echo \"$FAKE_COMMIT_MESSAGE\" > \"$1\"\n \ttest -z \"$FAKE_COMMIT_AMEND\" || echo \"$FAKE_COMMIT_AMEND\" >> \"$1\"\n \texit\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex d9382e4..0335b78 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -135,7 +135,8 @@ test_expect_success 'squash' '\n \ttest_tick &&\n \tGIT_AUTHOR_NAME=\"Nitfol\" git commit -m \"nitfol\" file7 &&\n \techo \"******************************\" &&\n-\tFAKE_LINES=\"1 squash 2\" git rebase -i --onto master HEAD~2 &&\n+\tFAKE_LINES=\"1 squash 2\" EXPECT_HEADER_COUNT=two \\\n+\t\tgit rebase -i --onto master HEAD~2 &&\n \ttest B = $(cat file7) &&\n \ttest $(git rev-parse HEAD^) = $(git rev-parse master)\n '\n@@ -230,6 +231,7 @@ test_expect_success 'verbose flag is heeded, even after --continue' '\n test_expect_success 'multi-squash only fires up editor once' '\n \tbase=$(git rev-parse HEAD~4) &&\n \tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"1 squash 2 squash 3 squash 4\" \\\n+\t\tEXPECT_HEADER_COUNT=4 \\\n \t\tgit rebase -i $base &&\n \ttest $base = $(git rev-parse HEAD^) &&\n \ttest 1 = $(git show | grep ONCE | wc -l)\n@@ -239,6 +241,7 @@ test_expect_success 'multi-fixup only fires up editor once' '\n \tgit checkout -b multi-fixup E &&\n \tbase=$(git rev-parse HEAD~4) &&\n \tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"1 fixup 2 fixup 3 fixup 4\" \\\n+\t\tEXPECT_HEADER_COUNT=4 \\\n \t\tgit rebase -i $base &&\n \ttest $base = $(git rev-parse HEAD^) &&\n \ttest 1 = $(git show | grep ONCE | wc -l) &&\n@@ -258,6 +261,7 @@ test_expect_success 'squash and fixup generate correct log messages' '\n \tgit checkout -b squash-fixup E &&\n \tbase=$(git rev-parse HEAD~4) &&\n \tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"1 fixup 2 squash 3 fixup 4\" \\\n+\t\tEXPECT_HEADER_COUNT=4 \\\n \t\tgit rebase -i $base &&\n \tgit cat-file commit HEAD | sed -e 1,/^\\$/d > actual-squash-fixup &&\n \ttest_cmp expect-squash-fixup actual-squash-fixup &&\n@@ -297,7 +301,8 @@ test_expect_success 'squash works as expected' '\n \t\tgit commit -m $n\n \tdone &&\n \tone=$(git rev-parse HEAD~3) &&\n-\tFAKE_LINES=\"1 squash 3 2\" git rebase -i HEAD~3 &&\n+\tFAKE_LINES=\"1 squash 3 2\" EXPECT_HEADER_COUNT=two \\\n+\t\tgit rebase -i HEAD~3 &&\n \ttest $one = $(git rev-parse HEAD~2)\n '\n \n-- \n1.6.6\n"},{"id":"131598","messageId":"1e03c6ff51ca0e6da4c19da014523f01a27b1579.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 10/18] rebase -i: Improve consistency of commit count in generated commit messages","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:49Z","receivedAt":"2010-01-14T05:54:49Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Use the numeral \"2\" instead of the word \"two\" when two commits are\nbeing interactively squashed.  This makes the treatment consistent\nwith that for higher numbers of commits.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh    |    2 +-\n t/t3404-rebase-interactive.sh |    4 ++--\n 2 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 2c7f3ec..16e1990 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -362,7 +362,7 @@ make_squash_message () {\n \t\t}' <\"$SQUASH_MSG\"\n \telse\n \t\tCOUNT=2\n-\t\techo \"# This is a combination of two commits.\"\n+\t\techo \"# This is a combination of 2 commits.\"\n \t\techo \"# The first commit's message is:\"\n \t\techo\n \t\tgit cat-file commit HEAD | sed -e '1,/^$/d'\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 0335b78..0511709 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -135,7 +135,7 @@ test_expect_success 'squash' '\n \ttest_tick &&\n \tGIT_AUTHOR_NAME=\"Nitfol\" git commit -m \"nitfol\" file7 &&\n \techo \"******************************\" &&\n-\tFAKE_LINES=\"1 squash 2\" EXPECT_HEADER_COUNT=two \\\n+\tFAKE_LINES=\"1 squash 2\" EXPECT_HEADER_COUNT=2 \\\n \t\tgit rebase -i --onto master HEAD~2 &&\n \ttest B = $(cat file7) &&\n \ttest $(git rev-parse HEAD^) = $(git rev-parse master)\n@@ -301,7 +301,7 @@ test_expect_success 'squash works as expected' '\n \t\tgit commit -m $n\n \tdone &&\n \tone=$(git rev-parse HEAD~3) &&\n-\tFAKE_LINES=\"1 squash 3 2\" EXPECT_HEADER_COUNT=two \\\n+\tFAKE_LINES=\"1 squash 3 2\" EXPECT_HEADER_COUNT=2 \\\n \t\tgit rebase -i HEAD~3 &&\n \ttest $one = $(git rev-parse HEAD~2)\n '\n-- \n1.6.6\n"},{"id":"131599","messageId":"511d20b177b8ae6e978126da2af3880d2f7895e1.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 11/18] rebase -i: Simplify commit counting for generated commit messages","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:50Z","receivedAt":"2010-01-14T05:54:50Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Read the old count from the first line of the old commit message\nrather than counting the number of commit message blocks in the file.\nThis is simpler, faster, and more robust (e.g., it cannot be confused\nby strange commit message contents).\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |   11 +++--------\n 1 files changed, 3 insertions(+), 8 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 16e1990..5ed80b0 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -351,11 +351,9 @@ nth_string () {\n \n make_squash_message () {\n \tif test -f \"$SQUASH_MSG\"; then\n-\t\t# We want to be careful about matching only the commit\n-\t\t# message comment lines generated by this function.\n-\t\t# \"[snrt][tdh]\" matches the nth_string endings.\n-\t\tCOUNT=$(($(sed -n \"s/^# Th[^0-9]*\\([1-9][0-9]*\\)[snrt][tdh] commit message.*:/\\1/p\" \\\n-\t\t\t< \"$SQUASH_MSG\" | sed -ne '$p')+1))\n+\t\tCOUNT=$(($(sed -n \\\n+\t\t\t-e \"1s/^# This is a combination of \\(.*\\) commits\\./\\1/p\" \\\n+\t\t\t-e \"q\" < \"$SQUASH_MSG\")+1))\n \t\techo \"# This is a combination of $COUNT commits.\"\n \t\tsed -e 1d -e '2,/^./{\n \t\t\t/^$/d\n@@ -378,9 +376,6 @@ make_squash_message () {\n \t\techo\n \t\techo \"# The $(nth_string $COUNT) commit message will be skipped:\"\n \t\techo\n-\t\t# Comment the lines of the commit message out using\n-\t\t# \"#\t\" rather than \"# \" to make them less likely to\n-\t\t# confuse the sed regexp above.\n \t\tgit cat-file commit $2 | sed -e '1,/^$/d' -e 's/^/#\t/'\n \t\t;;\n \tesac\n-- \n1.6.6\n"},{"id":"131595","messageId":"846f72bfe9246c2ac1f776fa18bd7f75fa77292d.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 12/18] rebase -i: Extract a function \"commit_message\"","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:51Z","receivedAt":"2010-01-14T05:54:51Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"...instead of repeating the same short but slightly obscure blob of\ncode in several places.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |   15 ++++++++++-----\n 1 files changed, 10 insertions(+), 5 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 5ed80b0..04a1c3a 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -120,6 +120,11 @@ output () {\n \tesac\n }\n \n+# Output the commit message for the specified commit.\n+commit_message () {\n+\tgit cat-file commit \"$1\" | sed \"1,/^$/d\"\n+}\n+\n run_pre_rebase_hook () {\n \tif test -z \"$OK_TO_SKIP_PRE_REBASE\" &&\n \t   test -x \"$GIT_DIR/hooks/pre-rebase\"\n@@ -180,7 +185,7 @@ make_patch () {\n \t\t;;\n \tesac > \"$DOTEST\"/patch\n \ttest -f \"$MSG\" ||\n-\t\tgit cat-file commit \"$1\" | sed \"1,/^$/d\" > \"$MSG\"\n+\t\tcommit_message \"$1\" > \"$MSG\"\n \ttest -f \"$AUTHOR_SCRIPT\" ||\n \t\tget_author_ident_from_commit \"$1\" > \"$AUTHOR_SCRIPT\"\n }\n@@ -318,7 +323,7 @@ pick_one_preserving_merges () {\n \t\t\t# redo merge\n \t\t\tauthor_script=$(get_author_ident_from_commit $sha1)\n \t\t\teval \"$author_script\"\n-\t\t\tmsg=\"$(git cat-file commit $sha1 | sed -e '1,/^$/d')\"\n+\t\t\tmsg=\"$(commit_message $sha1)\"\n \t\t\t# No point in merging the first parent, that's HEAD\n \t\t\tnew_parents=${new_parents# $first_parent}\n \t\t\tif ! GIT_AUTHOR_NAME=\"$GIT_AUTHOR_NAME\" \\\n@@ -363,20 +368,20 @@ make_squash_message () {\n \t\techo \"# This is a combination of 2 commits.\"\n \t\techo \"# The first commit's message is:\"\n \t\techo\n-\t\tgit cat-file commit HEAD | sed -e '1,/^$/d'\n+\t\tcommit_message HEAD\n \tfi\n \tcase $1 in\n \tsquash)\n \t\techo\n \t\techo \"# This is the $(nth_string $COUNT) commit message:\"\n \t\techo\n-\t\tgit cat-file commit $2 | sed -e '1,/^$/d'\n+\t\tcommit_message $2\n \t\t;;\n \tfixup)\n \t\techo\n \t\techo \"# The $(nth_string $COUNT) commit message will be skipped:\"\n \t\techo\n-\t\tgit cat-file commit $2 | sed -e '1,/^$/d' -e 's/^/#\t/'\n+\t\tcommit_message $2 | sed -e 's/^/#\t/'\n \t\t;;\n \tesac\n }\n-- \n1.6.6\n"},{"id":"131592","messageId":"946239c2ed9c6bf1b536d96c6bf06788878c63b9.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 13/18] rebase -i: Handle the author script all in one place in do_next","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:52Z","receivedAt":"2010-01-14T05:54:52Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"This change has no practical effect but makes the code easier to\nfollow.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |    4 ++--\n 1 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 04a1c3a..15b8605 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -449,6 +449,8 @@ do_next () {\n \t\tmake_squash_message $squash_style $sha1 > \"$MSG\"\n \t\tfailed=f\n \t\tauthor_script=$(get_author_ident_from_commit HEAD)\n+\t\techo \"$author_script\" > \"$AUTHOR_SCRIPT\"\n+\t\teval \"$author_script\"\n \t\toutput git reset --soft HEAD^\n \t\tpick_one -n $sha1 || failed=t\n \t\tcase \"$(peek_next_command)\" in\n@@ -467,11 +469,9 @@ do_next () {\n \t\t\trm -f \"$GIT_DIR\"/MERGE_MSG || exit\n \t\t\t;;\n \t\tesac\n-\t\techo \"$author_script\" > \"$AUTHOR_SCRIPT\"\n \t\tif test $failed = f\n \t\tthen\n \t\t\t# This is like --amend, but with a different message\n-\t\t\teval \"$author_script\"\n \t\t\tGIT_AUTHOR_NAME=\"$GIT_AUTHOR_NAME\" \\\n \t\t\tGIT_AUTHOR_EMAIL=\"$GIT_AUTHOR_EMAIL\" \\\n \t\t\tGIT_AUTHOR_DATE=\"$GIT_AUTHOR_DATE\" \\\n-- \n1.6.6\n"},{"id":"131597","messageId":"fce97bc894f622fdc0ff26afab0986200ab42f5a.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 14/18] rebase -i: Extract function do_with_author","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:53Z","receivedAt":"2010-01-14T05:54:53Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Call it instead of repeating similar code blocks in several places.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |   27 +++++++++++++++------------\n 1 files changed, 15 insertions(+), 12 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 15b8605..2902644 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -205,6 +205,15 @@ has_action () {\n \tsane_grep '^[^#]' \"$1\" >/dev/null\n }\n \n+# Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n+# GIT_AUTHOR_DATE exported from the current environment.\n+do_with_author () {\n+\tGIT_AUTHOR_NAME=\"$GIT_AUTHOR_NAME\" \\\n+\tGIT_AUTHOR_EMAIL=\"$GIT_AUTHOR_EMAIL\" \\\n+\tGIT_AUTHOR_DATE=\"$GIT_AUTHOR_DATE\" \\\n+\t\"$@\"\n+}\n+\n pick_one () {\n \tno_ff=\n \tcase \"$1\" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac\n@@ -326,11 +335,8 @@ pick_one_preserving_merges () {\n \t\t\tmsg=\"$(commit_message $sha1)\"\n \t\t\t# No point in merging the first parent, that's HEAD\n \t\t\tnew_parents=${new_parents# $first_parent}\n-\t\t\tif ! GIT_AUTHOR_NAME=\"$GIT_AUTHOR_NAME\" \\\n-\t\t\t\tGIT_AUTHOR_EMAIL=\"$GIT_AUTHOR_EMAIL\" \\\n-\t\t\t\tGIT_AUTHOR_DATE=\"$GIT_AUTHOR_DATE\" \\\n-\t\t\t\toutput git merge $STRATEGY -m \"$msg\" \\\n-\t\t\t\t\t$new_parents\n+\t\t\tif ! do_with_author output \\\n+\t\t\t\tgit merge $STRATEGY -m \"$msg\" $new_parents\n \t\t\tthen\n \t\t\t\tprintf \"%s\\n\" \"$msg\" > \"$GIT_DIR\"/MERGE_MSG\n \t\t\t\tdie_with_patch $sha1 \"Error redoing merge $sha1\"\n@@ -472,11 +478,9 @@ do_next () {\n \t\tif test $failed = f\n \t\tthen\n \t\t\t# This is like --amend, but with a different message\n-\t\t\tGIT_AUTHOR_NAME=\"$GIT_AUTHOR_NAME\" \\\n-\t\t\tGIT_AUTHOR_EMAIL=\"$GIT_AUTHOR_EMAIL\" \\\n-\t\t\tGIT_AUTHOR_DATE=\"$GIT_AUTHOR_DATE\" \\\n-\t\t\t$USE_OUTPUT git commit --no-verify \\\n-\t\t\t\t$MSG_OPT \"$EDIT_OR_FILE\" || failed=t\n+\t\t\tdo_with_author $USE_OUTPUT git commit --no-verify \\\n+\t\t\t\t$MSG_OPT \"$EDIT_OR_FILE\" ||\n+\t\t\t\tfailed=t\n \t\tfi\n \t\tif test $failed = t\n \t\tthen\n@@ -657,8 +661,7 @@ first and then run 'git rebase --continue' again.\"\n \t\t\t\tgit reset --soft HEAD^ ||\n \t\t\t\tdie \"Cannot rewind the HEAD\"\n \t\t\tfi\n-\t\t\texport GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE &&\n-\t\t\tgit commit --no-verify -F \"$MSG\" -e || {\n+\t\t\tdo_with_author git commit --no-verify -F \"$MSG\" -e || {\n \t\t\t\ttest -n \"$amend\" && git reset --soft $amend\n \t\t\t\tdie \"Could not commit staged changes.\"\n \t\t\t}\n-- \n1.6.6\n"},{"id":"131593","messageId":"784d63d686a82b93a29531d3079aadbe83258d9f.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 15/18] rebase -i: Change function make_squash_message into update_squash_message","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:54Z","receivedAt":"2010-01-14T05:54:54Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Alter the file $SQUASH_MSG in place rather than outputting the new\nmessage then juggling it around.  Change the function name\naccordingly.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh |   35 ++++++++++++++++++++---------------\n 1 files changed, 20 insertions(+), 15 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 2902644..5a48fbf 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -360,21 +360,26 @@ nth_string () {\n \tesac\n }\n \n-make_squash_message () {\n+update_squash_message () {\n \tif test -f \"$SQUASH_MSG\"; then\n+\t\tmv \"$SQUASH_MSG\" \"$SQUASH_MSG\".bak || exit\n \t\tCOUNT=$(($(sed -n \\\n \t\t\t-e \"1s/^# This is a combination of \\(.*\\) commits\\./\\1/p\" \\\n-\t\t\t-e \"q\" < \"$SQUASH_MSG\")+1))\n-\t\techo \"# This is a combination of $COUNT commits.\"\n-\t\tsed -e 1d -e '2,/^./{\n-\t\t\t/^$/d\n-\t\t}' <\"$SQUASH_MSG\"\n+\t\t\t-e \"q\" < \"$SQUASH_MSG\".bak)+1))\n+\t\t{\n+\t\t\techo \"# This is a combination of $COUNT commits.\"\n+\t\t\tsed -e 1d -e '2,/^./{\n+\t\t\t\t/^$/d\n+\t\t\t}' <\"$SQUASH_MSG\".bak\n+\t\t} >$SQUASH_MSG\n \telse\n \t\tCOUNT=2\n-\t\techo \"# This is a combination of 2 commits.\"\n-\t\techo \"# The first commit's message is:\"\n-\t\techo\n-\t\tcommit_message HEAD\n+\t\t{\n+\t\t\techo \"# This is a combination of 2 commits.\"\n+\t\t\techo \"# The first commit's message is:\"\n+\t\t\techo\n+\t\t\tcommit_message HEAD\n+\t\t} >$SQUASH_MSG\n \tfi\n \tcase $1 in\n \tsquash)\n@@ -389,7 +394,7 @@ make_squash_message () {\n \t\techo\n \t\tcommit_message $2 | sed -e 's/^/#\t/'\n \t\t;;\n-\tesac\n+\tesac >>$SQUASH_MSG\n }\n \n peek_next_command () {\n@@ -452,7 +457,7 @@ do_next () {\n \t\t\tdie \"Cannot '$squash_style' without a previous commit\"\n \n \t\tmark_action_done\n-\t\tmake_squash_message $squash_style $sha1 > \"$MSG\"\n+\t\tupdate_squash_message $squash_style $sha1\n \t\tfailed=f\n \t\tauthor_script=$(get_author_ident_from_commit HEAD)\n \t\techo \"$author_script\" > \"$AUTHOR_SCRIPT\"\n@@ -462,16 +467,16 @@ do_next () {\n \t\tcase \"$(peek_next_command)\" in\n \t\tsquash|s|fixup|f)\n \t\t\tUSE_OUTPUT=output\n+\t\t\tcp \"$SQUASH_MSG\" \"$MSG\" || exit\n \t\t\tMSG_OPT=-F\n \t\t\tEDIT_OR_FILE=\"$MSG\"\n-\t\t\tcp \"$MSG\" \"$SQUASH_MSG\"\n \t\t\t;;\n \t\t*)\n \t\t\tUSE_OUTPUT=\n \t\t\tMSG_OPT=\n \t\t\tEDIT_OR_FILE=-e\n-\t\t\trm -f \"$SQUASH_MSG\" || exit\n-\t\t\tcp \"$MSG\" \"$GIT_DIR\"/SQUASH_MSG\n+\t\t\tcp \"$SQUASH_MSG\" \"$MSG\" || exit\n+\t\t\tmv \"$SQUASH_MSG\" \"$GIT_DIR\"/SQUASH_MSG || exit\n \t\t\trm -f \"$GIT_DIR\"/MERGE_MSG || exit\n \t\t\t;;\n \t\tesac\n-- \n1.6.6\n"},{"id":"131591","messageId":"6f72a672c95fd955508d9efa483cd4fa742a137e.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 16/18] rebase -i: For fixup commands without squashes, do not start editor","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:55Z","receivedAt":"2010-01-14T05:54:55Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"If the \"rebase -i\" commands include a series of fixup commands without\nany squash commands, then commit the combined commit using the commit\nmessage of the corresponding \"pick\" without starting up the\ncommit-message editor.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh    |   81 +++++++++++++++++++++++++++--------------\n t/t3404-rebase-interactive.sh |    7 ++--\n 2 files changed, 57 insertions(+), 31 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 5a48fbf..c9390cd 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -66,6 +66,13 @@ MSG=\"$DOTEST\"/message\n # updated.  It is deleted just before the combined commit is made.\n SQUASH_MSG=\"$DOTEST\"/message-squash\n \n+# If the current series of squash/fixups has not yet included a squash\n+# command, then this file exists and holds the commit message of the\n+# original \"pick\" commit.  (If the series ends without a \"squash\"\n+# command, then this can be used as the commit message of the combined\n+# commit without opening the editor.)\n+FIXUP_MSG=\"$DOTEST\"/message-fixup\n+\n # $REWRITTEN is the name of a directory containing files for each\n # commit that is reachable by at least one merge base of $HEAD and\n # $UPSTREAM. They are not necessarily rewritten, but their children\n@@ -360,7 +367,7 @@ nth_string () {\n \tesac\n }\n \n-update_squash_message () {\n+update_squash_messages () {\n \tif test -f \"$SQUASH_MSG\"; then\n \t\tmv \"$SQUASH_MSG\" \"$SQUASH_MSG\".bak || exit\n \t\tCOUNT=$(($(sed -n \\\n@@ -373,16 +380,18 @@ update_squash_message () {\n \t\t\t}' <\"$SQUASH_MSG\".bak\n \t\t} >$SQUASH_MSG\n \telse\n+\t\tcommit_message HEAD > \"$FIXUP_MSG\" || die \"Cannot write $FIXUP_MSG\"\n \t\tCOUNT=2\n \t\t{\n \t\t\techo \"# This is a combination of 2 commits.\"\n \t\t\techo \"# The first commit's message is:\"\n \t\t\techo\n-\t\t\tcommit_message HEAD\n+\t\t\tcat \"$FIXUP_MSG\"\n \t\t} >$SQUASH_MSG\n \tfi\n \tcase $1 in\n \tsquash)\n+\t\trm -f \"$FIXUP_MSG\"\n \t\techo\n \t\techo \"# This is the $(nth_string $COUNT) commit message:\"\n \t\techo\n@@ -457,7 +466,7 @@ do_next () {\n \t\t\tdie \"Cannot '$squash_style' without a previous commit\"\n \n \t\tmark_action_done\n-\t\tupdate_squash_message $squash_style $sha1\n+\t\tupdate_squash_messages $squash_style $sha1\n \t\tfailed=f\n \t\tauthor_script=$(get_author_ident_from_commit HEAD)\n \t\techo \"$author_script\" > \"$AUTHOR_SCRIPT\"\n@@ -466,34 +475,52 @@ do_next () {\n \t\tpick_one -n $sha1 || failed=t\n \t\tcase \"$(peek_next_command)\" in\n \t\tsquash|s|fixup|f)\n-\t\t\tUSE_OUTPUT=output\n-\t\t\tcp \"$SQUASH_MSG\" \"$MSG\" || exit\n-\t\t\tMSG_OPT=-F\n-\t\t\tEDIT_OR_FILE=\"$MSG\"\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\tif test $failed = f\n+\t\t\tthen\n+\t\t\t\tdo_with_author output git commit --no-verify -F \"$SQUASH_MSG\" ||\n+\t\t\t\t\tfailed=t\n+\t\t\tfi\n+\t\t\tif test $failed = t\n+\t\t\tthen\n+\t\t\t\tcp \"$SQUASH_MSG\" \"$MSG\" || exit\n+\t\t\t\t# After any kind of hiccup, prevent committing without\n+\t\t\t\t# opening the commit message editor:\n+\t\t\t\trm -f \"$FIXUP_MSG\"\n+\t\t\t\tcp \"$MSG\" \"$GIT_DIR\"/MERGE_MSG || exit\n+\t\t\t\twarn\n+\t\t\t\twarn \"Could not apply $sha1... $rest\"\n+\t\t\t\tdie_with_patch $sha1 \"\"\n+\t\t\tfi\n \t\t\t;;\n \t\t*)\n-\t\t\tUSE_OUTPUT=\n-\t\t\tMSG_OPT=\n-\t\t\tEDIT_OR_FILE=-e\n-\t\t\tcp \"$SQUASH_MSG\" \"$MSG\" || exit\n-\t\t\tmv \"$SQUASH_MSG\" \"$GIT_DIR\"/SQUASH_MSG || exit\n-\t\t\trm -f \"$GIT_DIR\"/MERGE_MSG || exit\n+\t\t\t# This is the final command of this squash/fixup group\n+\t\t\tif test $failed = f\n+\t\t\tthen\n+\t\t\t\tif test -f \"$FIXUP_MSG\"\n+\t\t\t\tthen\n+\t\t\t\t\tdo_with_author git commit --no-verify -F \"$FIXUP_MSG\" ||\n+\t\t\t\t\t\tfailed=t\n+\t\t\t\telse\n+\t\t\t\t\tcp \"$SQUASH_MSG\" \"$GIT_DIR\"/SQUASH_MSG || exit\n+\t\t\t\t\trm -f \"$GIT_DIR\"/MERGE_MSG\n+\t\t\t\t\tdo_with_author git commit --no-verify -e ||\n+\t\t\t\t\t\tfailed=t\n+\t\t\t\tfi\n+\t\t\tfi\n+\t\t\trm -f \"$FIXUP_MSG\"\n+\t\t\tif test $failed = t\n+\t\t\tthen\n+\t\t\t\tmv \"$SQUASH_MSG\" \"$MSG\" || exit\n+\t\t\t\tcp \"$MSG\" \"$GIT_DIR\"/MERGE_MSG || exit\n+\t\t\t\twarn\n+\t\t\t\twarn \"Could not apply $sha1... $rest\"\n+\t\t\t\tdie_with_patch $sha1 \"\"\n+\t\t\tfi\n+\t\t\trm -f \"$SQUASH_MSG\"\n \t\t\t;;\n \t\tesac\n-\t\tif test $failed = f\n-\t\tthen\n-\t\t\t# This is like --amend, but with a different message\n-\t\t\tdo_with_author $USE_OUTPUT git commit --no-verify \\\n-\t\t\t\t$MSG_OPT \"$EDIT_OR_FILE\" ||\n-\t\t\t\tfailed=t\n-\t\tfi\n-\t\tif test $failed = t\n-\t\tthen\n-\t\t\tcp \"$MSG\" \"$GIT_DIR\"/MERGE_MSG\n-\t\t\twarn\n-\t\t\twarn \"Could not apply $sha1... $rest\"\n-\t\t\tdie_with_patch $sha1 \"\"\n-\t\tfi\n \t\t;;\n \t*)\n \t\twarn \"Unknown command: $command $sha1 $rest\"\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 0511709..175a86c 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -237,14 +237,13 @@ test_expect_success 'multi-squash only fires up editor once' '\n \ttest 1 = $(git show | grep ONCE | wc -l)\n '\n \n-test_expect_success 'multi-fixup only fires up editor once' '\n+test_expect_success 'multi-fixup does not fire up editor' '\n \tgit checkout -b multi-fixup E &&\n \tbase=$(git rev-parse HEAD~4) &&\n-\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"1 fixup 2 fixup 3 fixup 4\" \\\n-\t\tEXPECT_HEADER_COUNT=4 \\\n+\tFAKE_COMMIT_AMEND=\"NEVER\" FAKE_LINES=\"1 fixup 2 fixup 3 fixup 4\" \\\n \t\tgit rebase -i $base &&\n \ttest $base = $(git rev-parse HEAD^) &&\n-\ttest 1 = $(git show | grep ONCE | wc -l) &&\n+\ttest 0 = $(git show | grep NEVER | wc -l) &&\n \tgit checkout to-be-rebased &&\n \tgit branch -D multi-fixup\n '\n-- \n1.6.6\n"},{"id":"131590","messageId":"9595024ceae4d013954092ed928a50fd887e5996.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 17/18] t3404: Set up more of the test repo in the \"setup\" step","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:56Z","receivedAt":"2010-01-14T05:54:56Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"...and reuse these pre-created branches in tests rather than creating\nduplicates.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n t/t3404-rebase-interactive.sh |   51 +++++++++++++++++++++--------------------\n 1 files changed, 26 insertions(+), 25 deletions(-)\n\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 175a86c..a119ce0 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -14,15 +14,20 @@ that the result still makes sense.\n \n set_fake_editor\n \n-# set up two branches like this:\n+# Set up the repository like this:\n #\n-# A - B - C - D - E     (master)\n+#     one - two - three - four (conflict-branch)\n+#   /\n+# A - B - C - D - E            (master)\n+# | \\\n+# |   F - G - H                (branch1)\n+# |     \\\n+#  \\      I                    (branch2)\n #   \\\n-#     F - G - H         (branch1)\n-#       \\\n-#         I             (branch2)\n+#     J - K - L - M            (no-conflict-branch)\n #\n-# where A, B, D and G touch the same file.\n+# where A, B, D and G all touch file1, and one, two, three, four all\n+# touch file \"conflict\".\n \n test_expect_success 'setup' '\n \ttest_commit A file1 &&\n@@ -36,9 +41,20 @@ test_expect_success 'setup' '\n \ttest_commit H file5 &&\n \tgit checkout -b branch2 F &&\n \ttest_commit I file6\n+\tgit checkout -b conflict-branch A &&\n+\tfor n in one two three four\n+\tdo\n+\t\ttest_commit $n conflict\n+\tdone &&\n+\tgit checkout -b no-conflict-branch A &&\n+\tfor n in J K L M\n+\tdo\n+\t\ttest_commit $n file$n\n+\tdone\n '\n \n test_expect_success 'no changes are a nop' '\n+\tgit checkout branch2 &&\n \tgit rebase -i F &&\n \ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/branch2\" &&\n \ttest $(git rev-parse I) = $(git rev-parse HEAD)\n@@ -97,7 +113,7 @@ cat > expect2 << EOF\n D\n =======\n G\n->>>>>>> 91201e5... G\n+>>>>>>> 51047de... G\n EOF\n \n test_expect_success 'stop on conflicting pick' '\n@@ -293,12 +309,7 @@ test_expect_success 'squash ignores blank lines' '\n '\n \n test_expect_success 'squash works as expected' '\n-\tfor n in one two three four\n-\tdo\n-\t\techo $n >> file$n &&\n-\t\tgit add file$n &&\n-\t\tgit commit -m $n\n-\tdone &&\n+\tgit checkout -b squash-works no-conflict-branch &&\n \tone=$(git rev-parse HEAD~3) &&\n \tFAKE_LINES=\"1 squash 3 2\" EXPECT_HEADER_COUNT=2 \\\n \t\tgit rebase -i HEAD~3 &&\n@@ -306,12 +317,7 @@ test_expect_success 'squash works as expected' '\n '\n \n test_expect_success 'interrupted squash works as expected' '\n-\tfor n in one two three four\n-\tdo\n-\t\techo $n >> conflict &&\n-\t\tgit add conflict &&\n-\t\tgit commit -m $n\n-\tdone &&\n+\tgit checkout -b interrupted-squash conflict-branch &&\n \tone=$(git rev-parse HEAD~3) &&\n \t(\n \t\tFAKE_LINES=\"1 squash 3 2\" &&\n@@ -328,12 +334,7 @@ test_expect_success 'interrupted squash works as expected' '\n '\n \n test_expect_success 'interrupted squash works as expected (case 2)' '\n-\tfor n in one two three four\n-\tdo\n-\t\techo $n >> conflict &&\n-\t\tgit add conflict &&\n-\t\tgit commit -m $n\n-\tdone &&\n+\tgit checkout -b interrupted-squash2 conflict-branch &&\n \tone=$(git rev-parse HEAD~3) &&\n \t(\n \t\tFAKE_LINES=\"3 squash 1 2\" &&\n-- \n1.6.6\n"},{"id":"131589","messageId":"41c3e65ab43be6b2f98f3c162e34c160c059bb5c.1263447038.git.mhagger@alum.mit.edu","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"[PATCH 18/18] rebase -i: Retain user-edited commit messages after squash/fixup conflicts","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T05:54:57Z","receivedAt":"2010-01-14T05:54:57Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"When a squash/fixup fails due to a conflict, the user is required to\nedit the commit message.  Previously, if further squash/fixup commands\nfollowed the conflicting squash/fixup, this user-edited message was\ndiscarded and a new automatically-generated commit message was\nsuggested.\n\nChange the handling of conflicts within squash/fixup command series:\nWhenever the user is required to intervene, consider the resulting\ncommit to be a new basis for the following squash/fixups and use its\ncommit message in later suggested combined commit messages.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n git-rebase--interactive.sh    |   66 +++++++++++++++++------------------------\n t/t3404-rebase-interactive.sh |   36 ++++++++++++++++++++++\n 2 files changed, 63 insertions(+), 39 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex c9390cd..e551906 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -410,6 +410,21 @@ peek_next_command () {\n \tsed -n -e \"/^#/d\" -e \"/^$/d\" -e \"s/ .*//p\" -e \"q\" < \"$TODO\"\n }\n \n+# A squash/fixup has failed.  Prepare the long version of the squash\n+# commit message, then die_with_patch.  This code path requires the\n+# user to edit the combined commit message for all commits that have\n+# been squashed/fixedup so far.  So also erase the old squash\n+# messages, effectively causing the combined commit to be used as the\n+# new basis for any further squash/fixups.  Args: sha1 rest\n+die_failed_squash() {\n+\tmv \"$SQUASH_MSG\" \"$MSG\" || exit\n+\trm -f \"$FIXUP_MSG\"\n+\tcp \"$MSG\" \"$GIT_DIR\"/MERGE_MSG || exit\n+\twarn\n+\twarn \"Could not apply $1... $2\"\n+\tdie_with_patch $1 \"\"\n+}\n+\n do_next () {\n \trm -f \"$MSG\" \"$AUTHOR_SCRIPT\" \"$AMEND\" || exit\n \tread command sha1 rest < \"$TODO\"\n@@ -467,58 +482,31 @@ do_next () {\n \n \t\tmark_action_done\n \t\tupdate_squash_messages $squash_style $sha1\n-\t\tfailed=f\n \t\tauthor_script=$(get_author_ident_from_commit HEAD)\n \t\techo \"$author_script\" > \"$AUTHOR_SCRIPT\"\n \t\teval \"$author_script\"\n \t\toutput git reset --soft HEAD^\n-\t\tpick_one -n $sha1 || failed=t\n+\t\tpick_one -n $sha1 || die_failed_squash $sha1 \"$rest\"\n \t\tcase \"$(peek_next_command)\" in\n \t\tsquash|s|fixup|f)\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\tif test $failed = f\n-\t\t\tthen\n-\t\t\t\tdo_with_author output git commit --no-verify -F \"$SQUASH_MSG\" ||\n-\t\t\t\t\tfailed=t\n-\t\t\tfi\n-\t\t\tif test $failed = t\n-\t\t\tthen\n-\t\t\t\tcp \"$SQUASH_MSG\" \"$MSG\" || exit\n-\t\t\t\t# After any kind of hiccup, prevent committing without\n-\t\t\t\t# opening the commit message editor:\n-\t\t\t\trm -f \"$FIXUP_MSG\"\n-\t\t\t\tcp \"$MSG\" \"$GIT_DIR\"/MERGE_MSG || exit\n-\t\t\t\twarn\n-\t\t\t\twarn \"Could not apply $sha1... $rest\"\n-\t\t\t\tdie_with_patch $sha1 \"\"\n-\t\t\tfi\n+\t\t\tdo_with_author output git commit --no-verify -F \"$SQUASH_MSG\" ||\n+\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n \t\t\t;;\n \t\t*)\n \t\t\t# This is the final command of this squash/fixup group\n-\t\t\tif test $failed = f\n+\t\t\tif test -f \"$FIXUP_MSG\"\n \t\t\tthen\n-\t\t\t\tif test -f \"$FIXUP_MSG\"\n-\t\t\t\tthen\n-\t\t\t\t\tdo_with_author git commit --no-verify -F \"$FIXUP_MSG\" ||\n-\t\t\t\t\t\tfailed=t\n-\t\t\t\telse\n-\t\t\t\t\tcp \"$SQUASH_MSG\" \"$GIT_DIR\"/SQUASH_MSG || exit\n-\t\t\t\t\trm -f \"$GIT_DIR\"/MERGE_MSG\n-\t\t\t\t\tdo_with_author git commit --no-verify -e ||\n-\t\t\t\t\t\tfailed=t\n-\t\t\t\tfi\n-\t\t\tfi\n-\t\t\trm -f \"$FIXUP_MSG\"\n-\t\t\tif test $failed = t\n-\t\t\tthen\n-\t\t\t\tmv \"$SQUASH_MSG\" \"$MSG\" || exit\n-\t\t\t\tcp \"$MSG\" \"$GIT_DIR\"/MERGE_MSG || exit\n-\t\t\t\twarn\n-\t\t\t\twarn \"Could not apply $sha1... $rest\"\n-\t\t\t\tdie_with_patch $sha1 \"\"\n+\t\t\t\tdo_with_author git commit --no-verify -F \"$FIXUP_MSG\" ||\n+\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n+\t\t\telse\n+\t\t\t\tcp \"$SQUASH_MSG\" \"$GIT_DIR\"/SQUASH_MSG || exit\n+\t\t\t\trm -f \"$GIT_DIR\"/MERGE_MSG\n+\t\t\t\tdo_with_author git commit --no-verify -e ||\n+\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n \t\t\tfi\n-\t\t\trm -f \"$SQUASH_MSG\"\n+\t\t\trm -f \"$SQUASH_MSG\" \"$FIXUP_MSG\"\n \t\t\t;;\n \t\tesac\n \t\t;;\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex a119ce0..4e35137 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -264,6 +264,42 @@ test_expect_success 'multi-fixup does not fire up editor' '\n \tgit branch -D multi-fixup\n '\n \n+test_expect_success 'commit message used after conflict' '\n+\tgit checkout -b conflict-fixup conflict-branch &&\n+\tbase=$(git rev-parse HEAD~4) &&\n+\t(\n+\t\tFAKE_LINES=\"1 fixup 3 fixup 4\" &&\n+\t\texport FAKE_LINES &&\n+\t\ttest_must_fail git rebase -i $base\n+\t) &&\n+\techo three > conflict &&\n+\tgit add conflict &&\n+\tFAKE_COMMIT_AMEND=\"ONCE\" EXPECT_HEADER_COUNT=2 \\\n+\t\tgit rebase --continue &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 1 = $(git show | grep ONCE | wc -l) &&\n+\tgit checkout to-be-rebased &&\n+\tgit branch -D conflict-fixup\n+'\n+\n+test_expect_success 'commit message retained after conflict' '\n+\tgit checkout -b conflict-squash conflict-branch &&\n+\tbase=$(git rev-parse HEAD~4) &&\n+\t(\n+\t\tFAKE_LINES=\"1 fixup 3 squash 4\" &&\n+\t\texport FAKE_LINES &&\n+\t\ttest_must_fail git rebase -i $base\n+\t) &&\n+\techo three > conflict &&\n+\tgit add conflict &&\n+\tFAKE_COMMIT_AMEND=\"TWICE\" EXPECT_HEADER_COUNT=2 \\\n+\t\tgit rebase --continue &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 2 = $(git show | grep TWICE | wc -l) &&\n+\tgit checkout to-be-rebased &&\n+\tgit branch -D conflict-squash\n+'\n+\n cat > expect-squash-fixup << EOF\n B\n \n-- \n1.6.6\n"},{"id":"131612","messageId":"4B4ECB76.3030009@viscovery.net","threadId":"22217","inReplyTo":"c3ec064944c4c5e6a3eba5c71e8956fe8bceb3ad.1263447037.git.mhagger@alum.mit.edu","subject":"Re: [PATCH 09/18] t3404: Test the commit count in commit messages generated by \"rebase -i\"","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-01-14T07:44:54Z","receivedAt":"2010-01-14T07:44:54Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Michael Haggerty schrieb:\n> +\ttest -z \"$EXPECT_HEADER_COUNT\" ||\n> +\t\ttest \"$EXPECT_HEADER_COUNT\" = $(sed -n '1s/^# This is a combination of \\(.*\\) commits\\./\\1/p' < \"$1\") ||\n> +\t\texit\n\nIs an empty $EXPECT_HEADER_COUNT an error? I suppose it isn't; therefore,\nyou must put the second 'test' and the 'exit' in a brace group.\n\nYou should also put the $(sed) in double-quotes.\n\n-- Hannes\n"},{"id":"131613","messageId":"4B4ECD9E.5000707@viscovery.net","threadId":"22217","inReplyTo":"1e03c6ff51ca0e6da4c19da014523f01a27b1579.1263447038.git.mhagger@alum.mit.edu","subject":"Re: [PATCH 10/18] rebase -i: Improve consistency of commit count in generated commit messages","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-01-14T07:54:06Z","receivedAt":"2010-01-14T07:54:06Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Michael Haggerty schrieb:\n> Use the numeral \"2\" instead of the word \"two\" when two commits are\n> being interactively squashed.  This makes the treatment consistent\n> with that for higher numbers of commits.\n\nHuh? This is just code churn: consistency is not an advantage here.\n\nOh...wait... The next patch needs it this way. Couldn't you have justified\nit with \"In a subsequent change, we will extract the numeral and use it in\nan expression.\"\n\n-- Hannes\n"},{"id":"131614","messageId":"4B4ED3BA.5080805@viscovery.net","threadId":"22217","inReplyTo":"784d63d686a82b93a29531d3079aadbe83258d9f.1263447038.git.mhagger@alum.mit.edu","subject":"Re: [PATCH 15/18] rebase -i: Change function make_squash_message into update_squash_message","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-01-14T08:20:10Z","receivedAt":"2010-01-14T08:20:10Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Michael Haggerty schrieb:\n> Alter the file $SQUASH_MSG in place rather than outputting the new\n> message then juggling it around.  Change the function name\n> accordingly.\n\nCode churn... Oh...wait... (You get the point ;)\n\n-- Hannes\n"},{"id":"131624","messageId":"4B4EDD02.70603@alum.mit.edu","threadId":"22217","inReplyTo":"4B4ECB76.3030009@viscovery.net","subject":"Re: [PATCH 09/18] t3404: Test the commit count in commit messages generated by \"rebase -i\"","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T08:59:46Z","receivedAt":"2010-01-14T08:59:46Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Johannes Sixt wrote:\n> Michael Haggerty schrieb:\n>> +\ttest -z \"$EXPECT_HEADER_COUNT\" ||\n>> +\t\ttest \"$EXPECT_HEADER_COUNT\" = $(sed -n '1s/^# This is a combination of \\(.*\\) commits\\./\\1/p' < \"$1\") ||\n>> +\t\texit\n> \n> Is an empty $EXPECT_HEADER_COUNT an error? I suppose it isn't; therefore,\n> you must put the second 'test' and the 'exit' in a brace group.\n\nTrue, an empty $EXPECT_HEADER_COUNT is not an error.  But I think the\nform (A || B || C) is correct anyway, because if $EXPECT_HEADER_COUNT is\nempty, then A is successful, and neither B nor C are executed, and\nexecution falls through to the later tests.\n\n> You should also put the $(sed) in double-quotes.\n\nYes, thanks.  I'll include it in the next version.\n\nMichael\n"},{"id":"131625","messageId":"4B4EDE6D.3070306@alum.mit.edu","threadId":"22217","inReplyTo":"4B4ECD9E.5000707@viscovery.net","subject":"Re: [PATCH 10/18] rebase -i: Improve consistency of commit count in generated commit messages","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-14T09:05:49Z","receivedAt":"2010-01-14T09:05:49Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Johannes Sixt wrote:\n> Michael Haggerty schrieb:\n>> Use the numeral \"2\" instead of the word \"two\" when two commits are\n>> being interactively squashed.  This makes the treatment consistent\n>> with that for higher numbers of commits.\n> \n> Huh? This is just code churn: consistency is not an advantage here.\n> \n> Oh...wait... The next patch needs it this way. Couldn't you have justified\n> it with \"In a subsequent change, we will extract the numeral and use it in\n> an expression.\"\n\nIn the non-git universe, consistency in the user interface *is*\nconsidered an advantage :-)  But I will be happy to add your suggested\n*second* justification for the change in v2.\n\nMichael\n"},{"id":"131627","messageId":"4B4EE0E3.1020207@viscovery.net","threadId":"22217","inReplyTo":"4B4EDD02.70603@alum.mit.edu","subject":"Re: [PATCH 09/18] t3404: Test the commit count in commit messages generated by \"rebase -i\"","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-01-14T09:16:19Z","receivedAt":"2010-01-14T09:16:19Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Michael Haggerty schrieb:\n> True, an empty $EXPECT_HEADER_COUNT is not an error.  But I think the\n> form (A || B || C) is correct anyway...\n\nVery true. I haven't had my morning coffee, yet...\n\n-- Hannes\n"},{"id":"131628","messageId":"7v6375hwpx.fsf@alter.siamese.dyndns.org","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"Re: [PATCH 00/18] rebase -i: For pure fixups, do not start log message editor","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-14T09:17:14Z","receivedAt":"2010-01-14T09:17:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Very nicely done and the series was a pleasure to read, even though I\ndidn't read some of them very deeply and might have missed some subtle\ndetails outside the context of the patch.\n\nThanks.\n"},{"id":"131654","messageId":"loom.20100114T164214-897@post.gmane.org","threadId":"22217","inReplyTo":"aa37ee8a68d460df172b23b4999fbe4ce7d77c1e.1263447037.git.mhagger@alum.mit.edu","subject":"Re: [PATCH 01/18] rebase -i: Make the condition for an &quot;if&quot; more transparent","fromName":"Eric Blake","fromEmail":"ebb9@byu.net","sentAt":"2010-01-14T15:42:22Z","receivedAt":"2010-01-14T15:42:22Z","isPatch":true,"sender":{"key":"eblake@redhat.com","avatar":"https://avatars.githubusercontent.com/u/32933908?v=4"},"body":"Michael Haggerty <mhagger <at> alum.mit.edu> writes:\n\n>  \tcurrent_sha1=$(git rev-parse --verify HEAD)\n> -\tif test \"$no_ff$current_sha1\" = \"$parent_sha1\"; then\n> +\tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n\n'test cond1 -a cond2' is not portable.  Use 'test cond1 && test cond2'.\n\n-- \nEric Blake\n"},{"id":"131657","messageId":"7v8wc0fuqw.fsf@alter.siamese.dyndns.org","threadId":"22217","inReplyTo":"loom.20100114T164214-897@post.gmane.org","subject":"Re: [PATCH 01/18] rebase -i: Make the condition for an &quot;if&quot; more transparent","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-14T17:42:47Z","receivedAt":"2010-01-14T17:42:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Blake <ebb9@byu.net> writes:\n\n> Michael Haggerty <mhagger <at> alum.mit.edu> writes:\n>\n>>  \tcurrent_sha1=$(git rev-parse --verify HEAD)\n>> -\tif test \"$no_ff$current_sha1\" = \"$parent_sha1\"; then\n>> +\tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n>\n> 'test cond1 -a cond2' is not portable.  Use 'test cond1 && test cond2'.\n\nI avoid \"test -a/-o\" myself without even thinking (I am from old-school),\nbut at the same time I thought the progress in the world made such caution\nobsolescent.\n\nNot so.  Even though POSIX.1 lists -a/-o as options to \"test\", they are\nmarked \"Obsolescent XSI\" (\"Strictly Conforming POSIX Applications and\nStrictly Conforming XSI Applications shall not use obsolescent features\").\n\nWe may want [PATCH -01/18] to clean up the existing code first.  Even\noutside git-rebase--interactive.sh there are quite a few of them.\n\n    $ git grep -n -e 'test .* -[ao] ' -- '*.sh' | wc -l\n    38\n"},{"id":"131707","messageId":"4B50173B.5030802@gnu.org","threadId":"22217","inReplyTo":"7v8wc0fuqw.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 01/18] rebase -i: Make the condition for an &quot;if&quot; more transparent","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2010-01-15T07:20:27Z","receivedAt":"2010-01-15T07:20:27Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"On 01/14/2010 06:42 PM, Junio C Hamano wrote:\n> Eric Blake<ebb9@byu.net>  writes:\n>\n>> Michael Haggerty<mhagger<at>  alum.mit.edu>  writes:\n>>\n>>>   \tcurrent_sha1=$(git rev-parse --verify HEAD)\n>>> -\tif test \"$no_ff$current_sha1\" = \"$parent_sha1\"; then\n>>> +\tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n>>\n>> 'test cond1 -a cond2' is not portable.  Use 'test cond1&&  test cond2'.\n>\n> I avoid \"test -a/-o\" myself without even thinking (I am from old-school),\n> but at the same time I thought the progress in the world made such caution\n> obsolescent.\n>\n> Not so.  Even though POSIX.1 lists -a/-o as options to \"test\", they are\n> marked \"Obsolescent XSI\" (\"Strictly Conforming POSIX Applications and\n> Strictly Conforming XSI Applications shall not use obsolescent features\").\n\nThe reason for this is that the precedence rules were never well \nspecified, and this made many sane-looking uses of \"test -a/-o\" problematic.\n\nFor example, if $x is \"=\", these work according to POSIX (it's not \nportable, but in practice it's okay):\n\n   $ test -z \"$x\"\n   $ test -z \"$x\" && test a = b\n\nbut this doesn't\n\n   $ test -z \"$x\" -a a = b\n   bash: test: too many arguments\n\nbecause it groups \"test -n = -a\" and is left with \"a = b\".\n\nSimilarly, if $x is \"-f\", these\n\n   $ test \"$x\"\n   $ test \"$x\" || test c = d\n\ncorrectly adds an implicit \"-n\", but this fails:\n\n   $ test \"$x\" -o c = d\n   bash: test: too many arguments\n\nIf anybody cleans up git's usage of test -a/-o, feel free to cut'n'paste \nthe above into the commit messages.\n\nPaolo\n"},{"id":"132575","messageId":"20100125033846.GX13942@dr-wily.mit.edu","threadId":"22217","inReplyTo":"ec177b9d2b2354c446793df42525b4f7377bc413.1263447037.git.mhagger@alum.mit.edu","subject":"Re: [PATCH 06/18] rebase -i: Document how temporary files are used","fromName":"Greg Price","fromEmail":"price@ksplice.com","sentAt":"2010-01-25T03:38:47Z","receivedAt":"2010-01-25T03:38:47Z","isPatch":true,"sender":{"key":"price@mit.edu","avatar":"https://avatars.githubusercontent.com/u/28173?v=4"},"body":"Michael Haggerty wrote:\n> Add documentation, inferred by reverse-engineering, about how\n> git-rebase--interactive.sh uses many of its temporary files.\n\nBrilliant!  I like the 'fixup' command and look forward to using it,\nbut this is probably my favorite commit in the series.  I did the same\nreverse-engineering a few months ago and didn't think to write it down\nand save you having to do it.  Now you have saved the next person from\ndoing so.\n\nThis and your refactoring commits will cause me some annoyance as I\nbring the rebase -i -p series up to date, but that just means I should\nhurry up and get it in shape for merge rather than continue to have to\nresolve conflicts.\n\nGreg\n"},{"id":"132619","messageId":"alpine.DEB.1.00.1001251927460.8733@intel-tinevez-2-302","threadId":"22217","inReplyTo":"aa37ee8a68d460df172b23b4999fbe4ce7d77c1e.1263447037.git.mhagger@alum.mit.edu","subject":"Re: [PATCH 01/18] rebase -i: Make the condition for an \"if\" more transparent","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-25T18:28:12Z","receivedAt":"2010-01-25T18:28:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 14 Jan 2010, Michael Haggerty wrote:\n\n> @@ -166,7 +166,8 @@ pick_one () {\n>  \tparent_sha1=$(git rev-parse --verify $sha1^) ||\n>  \t\tdie \"Could not get the parent of $sha1\"\n>  \tcurrent_sha1=$(git rev-parse --verify HEAD)\n> -\tif test \"$no_ff$current_sha1\" = \"$parent_sha1\"; then\n> +\tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n\nRather use &&, right?\n\nCiao,\nDscho\n"},{"id":"132621","messageId":"alpine.DEB.1.00.1001251937310.8733@intel-tinevez-2-302","threadId":"22217","inReplyTo":"cover.1263447037.git.mhagger@alum.mit.edu","subject":"Re: [PATCH 00/18] rebase -i: For pure fixups, do not start log message editor","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-25T18:38:23Z","receivedAt":"2010-01-25T18:38:23Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 14 Jan 2010, Michael Haggerty wrote:\n\n> This patch series is a successor to mh/rebase-fixup, which causes\n> \"rebase -i\" to skip opening the log message editor when processing a\n> block of \"fixup\" commands that does not include any \"squash\"es.\n\nI knew why I kept this patch series as the last thing I would do before \ngoing offline: it is real elegantly done.\n\nCiao,\nDscho\n"},{"id":"132674","messageId":"4B5EE257.8060204@alum.mit.edu","threadId":"22217","inReplyTo":"alpine.DEB.1.00.1001251927460.8733@intel-tinevez-2-302","subject":"Re: [PATCH 01/18] rebase -i: Make the condition for an \"if\" more transparent","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2010-01-26T12:38:47Z","receivedAt":"2010-01-26T12:38:47Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Johannes Schindelin wrote:\n> On Thu, 14 Jan 2010, Michael Haggerty wrote:\n> \n>> @@ -166,7 +166,8 @@ pick_one () {\n>>  \tparent_sha1=$(git rev-parse --verify $sha1^) ||\n>>  \t\tdie \"Could not get the parent of $sha1\"\n>>  \tcurrent_sha1=$(git rev-parse --verify HEAD)\n>> -\tif test \"$no_ff$current_sha1\" = \"$parent_sha1\"; then\n>> +\tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n> \n> Rather use &&, right?\n\nYes, that mistake was caused by my own ignorance about the portability\nissues.  This problem was already discussed [1] and the change has been\nintegrated into master.\n\nThanks,\nMichael\n\n[1] http://marc.info/?l=git&m=126344857120877&w=2\n"},{"id":"132676","messageId":"alpine.DEB.1.00.1001261410340.4641@intel-tinevez-2-302","threadId":"22217","inReplyTo":"4B5EE257.8060204@alum.mit.edu","subject":"Re: [PATCH 01/18] rebase -i: Make the condition for an \"if\" more transparent","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-26T13:11:03Z","receivedAt":"2010-01-26T13:11:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 26 Jan 2010, Michael Haggerty wrote:\n\n> Johannes Schindelin wrote:\n> > On Thu, 14 Jan 2010, Michael Haggerty wrote:\n> > \n> >> @@ -166,7 +166,8 @@ pick_one () {\n> >>  \tparent_sha1=$(git rev-parse --verify $sha1^) ||\n> >>  \t\tdie \"Could not get the parent of $sha1\"\n> >>  \tcurrent_sha1=$(git rev-parse --verify HEAD)\n> >> -\tif test \"$no_ff$current_sha1\" = \"$parent_sha1\"; then\n> >> +\tif test -z \"$no_ff\" -a \"$current_sha1\" = \"$parent_sha1\"\n> > \n> > Rather use &&, right?\n> \n> Yes, that mistake was caused by my own ignorance about the portability\n> issues.  This problem was already discussed [1] and the change has been\n> integrated into master.\n\nThanks for the clarification, and sorry for not reviewing your series \nbefore Junio applied it.\n\nCiao,\nDscho\n"}]}