{"thread":{"id":"19839","subject":"git rebase --interactive squash/squish/fold/rollup","startedAt":"2009-06-17T12:06:54Z","lastAt":"2009-06-20T01:46:40Z","messageCount":40,"participants":["Minty","John Tapsell","Junio C Hamano","Paolo Bonzini","John Koleszar","Clemens Buchacher","Nanako Shiraishi","Johannes Schindelin","Nicolas Sebrecht","Michael Haggerty","Jakub Narebski","Teemu Likonen","Matthieu Moy","Michael J Gruber","Alex Riesen","Miles Bader","Wincent Colaiuta"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"116466","messageId":"e1868cfe0906170506o37a75c35m47f9456bf8ae47c1@mail.gmail.com","threadId":"19839","inReplyTo":null,"subject":"git rebase --interactive squash/squish/fold/rollup","fromName":"Minty","fromEmail":"mintywalker@gmail.com","sentAt":"2009-06-17T12:06:54Z","receivedAt":"2009-06-17T12:06:54Z","isPatch":false,"sender":{"key":"mintywalker@gmail.com","avatar":null},"body":"I was wondering if there was a git rebase --interactive \"squash\"\nalternative, that instead of letting me edit and manually combine the\ncommit messages from multiple commits that I want squashed together,\ninstead simply used the first and folded the other commits into that?\n\nI often find myself in the following pattern:\n\nbranch, hack, commit.\nhack, commit, hack, commit\ngit rebase --interactive master\nsquash later commits into an earlier one\nrepeated [hack, commit]+, rebase, squash\nmerge\n\nAt which point, 99% of the time I want to fold the later commits into\nan earlier commit, keep the commit message of the first and throw the\nremaining commit messages into /dev/null.\n\nI understand this is just a matter of editting the commit messages,\nbut I'm lazy and I find myself repeatadly dumbly deleting the latter\ncommit messages again and again.\n\nA $EDITOR macro/extension might address this, but it seems (to me)\ncleaner to extend the rebase command set:\n\n< pick, edit, squash\n> pick, edit, squash, fold\n\n\"fold\" is perhaps the wrong word.  \"squish\" is perhaps too similar.\n\"rollup\" maybe?\n\nIn any event, functionally it would do exactly the same as \"squash\",\nexcept rather than let you edit the commit messages it would instead\nsimply use the commit message of the first commit.  And throw the\nother commit messages away.\n\nI'm not adverse at having a go at putting a patch together (although\nthis is not my forte), but I thought I'd check there wasn't prior art\nor a good reason why this would be a \"bad thing\" to have?\n\nMurray.\n"},{"id":"116468","messageId":"43d8ce650906170555m644564b3v3722168f7217c326@mail.gmail.com","threadId":"19839","inReplyTo":"e1868cfe0906170506o37a75c35m47f9456bf8ae47c1@mail.gmail.com","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"John Tapsell","fromEmail":"johnflux@gmail.com","sentAt":"2009-06-17T12:55:26Z","receivedAt":"2009-06-17T12:55:26Z","isPatch":false,"sender":{"key":"johnflux@gmail.com","avatar":"https://gravatar.com/avatar/25f70d4c0f96396b84a2e34bcd9bdc233462c7b4be29b5fdca8266fc53f30b0c?d=mp&s=160"},"body":"> branch, hack, commit.\n> hack, commit, hack, commit\n\nWhat if you used  commit --append  instead?\n\nThe trouble though of squashing all the commits into one is that it\nmakes it impossible to bisect later.  Are you really sure that your\nfinal commit cannot be broken into small commits?  Ideally each commit\nis small but self contained.  Squashing should be done only to fix\ncases where you introduced a bug then fixed it, or to fix a partial\nimplementation etc.\n\nJohn\n"},{"id":"116473","messageId":"e1868cfe0906170645h2629e6f5v6dfe10d0cb909f77@mail.gmail.com","threadId":"19839","inReplyTo":"43d8ce650906170555m644564b3v3722168f7217c326@mail.gmail.com","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"Minty","fromEmail":"mintywalker@gmail.com","sentAt":"2009-06-17T13:45:36Z","receivedAt":"2009-06-17T13:45:36Z","isPatch":false,"sender":{"key":"mintywalker@gmail.com","avatar":null},"body":"On Wed, Jun 17, 2009 at 1:55 PM, John Tapsell <johnflux@gmail.com> wrote:\n>\n> > branch, hack, commit.\n> > hack, commit, hack, commit\n>\n> What if you used  commit --append  instead?\n\nThat appears to be a switch I don't have, nor is documented\n\nhttp://www.kernel.org/pub/software/scm/git/docs/git-commit.html\n\nDid you perhaps mean --amend?  Or have I missed something?\n\n--amend is not really a solution for me - it is perhaps a quirk of my\nworking pattern, but I typically (on the branch) commit tiny tiny bits\nof a (possibly incomplete) feature, then want to merge them back into\na single \"feature commit\" to merge with trunk.  It's a case of\nbuilding up a feature commit one step at a time.\n\nPerhaps I'm not normal or going about it wrong, in that I'm happy to\ncommit (on a branch) an incomplete bit of code ... pop off to do\nsomething else, come back, hack a little more ... go off, come back\n... eventually ending up with a bunch of commits I want to merge down\ninto a smaller set of (combined) commits which to then merge with\nmaster/trunk.\n\nfwiw, I didn't set out with this pattern in mind, it's rather one I\nhave noticed myself being in frequently.  It seems quite natural to\nme, except for this repeated squashing mini commits down.  I'm not\nsquashing ALL commits down into one single commit.  Rather many\ncommits down into a few commits, which then get merged with\nmaster/trunk.\n"},{"id":"116485","messageId":"7vvdmurfao.fsf@alter.siamese.dyndns.org","threadId":"19839","inReplyTo":"43d8ce650906170555m644564b3v3722168f7217c326@mail.gmail.com","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-17T16:33:19Z","receivedAt":"2009-06-17T16:33:19Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Tapsell <johnflux@gmail.com> writes:\n\n>> branch, hack, commit.\n>> hack, commit, hack, commit\n>\n> What if you used  commit --append  instead?\n>\n> The trouble though of squashing all the commits into one is that it\n> makes it impossible to bisect later.  Are you really sure that your\n> final commit cannot be broken into small commits?  Ideally each commit\n> is small but self contained.  Squashing should be done only to fix\n> cases where you introduced a bug then fixed it, or to fix a partial\n> implementation etc.\n\nI think you meant --amend, but it often happens to me that after preparing\na three-patch series:\n\n\t[1/3] Clean up the surrounding code I will touch\n        [2/3] Lay the groundwork\n        [3/3] Implement a cool new feature\n\nI find that there are more clean-up that should have been done in [1/3].\nThe way \"rebase -i\" expects me to work is:\n\n\t$ edit ;# more clean-ups\n\t$ git commit -a -m 'squash to \"clean up\"'\n        $ git rebase -i HEAD~5\n\nwhich will give me\n        \n        pick 1/3 Clean up ...\n        pick 2/3 Lay the groundwork\n        pick 3/3 Implement\n        pick 4/3 squash to \"clean up\"\n\nthat I'll change to \n\n        pick 1/3 Clean up ...\n        squash 4/3 squash to \"clean up\"\n        pick 2/3 Lay the groundwork\n        pick 3/3 Implement\n\nand then I'll need to edit the commit message for the first two combined.\nMore than half of the time (but not necessarily all the time), the edit\ninvolves just removing the single-liner 'squash to \"clean up\"',\n\nYou _could_ work this way instead using \"amend\".  Immediately after\nfinishing the three-patch series:\n\n\t$ git rebase -i HEAD~4\n\nwhich gives me\n\n        pick 1/3 Clean up ...\n        pick 2/3 Lay the groundwork\n        pick 3/3 Implement\n\nthat I'll change to\n\n        edit 1/3 Clean up ...\n        pick 2/3 Lay the groundwork\n        pick 3/3 Implement\n\nand then perform extra clean-up when \"rebase -i\" let's me amend the first\none.\n\nBut this is much less convenient than being able to accumulate fix-ups as\nseparate commits on top of the mostly finished main series, and then being\nable to later insert these fix-ups into the main series to be squashed\nusing \"rebase -i\", if (and only if) what you need to do are many small\nfixups (imagine there are not just a single '[4/3] squash to \"clean up\"'\nbut a lot more fix-up commits in the above example).  Depending on the\nstyle you work, \"go back to amend\" is Ok, or you may even prefer to.  But\nsome people do not switch context as rapidly as others.  After finding a\nsmall \"missed piece\", having to go back to edit and come back is much more\nheavyweight operation than being able to make a small \"fix-up\" commit on\ntop and keep going.  The latter keeps your thought process less disrupted.\n\nAnd it is very likely that the \"small fixups\" won't change what the\noriginal commit log message of the commit in the main needs to say\n(otherwise they won't be \"small\").\n\nSo I can see why a variant of \"squash\" that does not change (nor even ask\nfor a replacement of) the commit log message from the one that is being\namended could be useful.  I am tempted to suggest calling that a \"fixup\"\noperation, but some people may expect \"fixup\" to mean a variant of \"edit\"\nthat does not bother you by dropping you back to the shell to touch the\ntree that is recorded (i.e. \"fixing up the commit log message only\"), so\nit is not a very good word.\n"},{"id":"116486","messageId":"43d8ce650906170940m17942793xe0cd88ae372ff8f2@mail.gmail.com","threadId":"19839","inReplyTo":"7vvdmurfao.fsf@alter.siamese.dyndns.org","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"John Tapsell","fromEmail":"johnflux@gmail.com","sentAt":"2009-06-17T16:40:06Z","receivedAt":"2009-06-17T16:40:06Z","isPatch":false,"sender":{"key":"johnflux@gmail.com","avatar":"https://gravatar.com/avatar/25f70d4c0f96396b84a2e34bcd9bdc233462c7b4be29b5fdca8266fc53f30b0c?d=mp&s=160"},"body":"2009/6/17 Junio C Hamano <gitster@pobox.com>:\n> John Tapsell <johnflux@gmail.com> writes:\n>\n>>> branch, hack, commit.\n>>> hack, commit, hack, commit\n>>\n>> What if you used  commit --append  instead?\n>>\n>> The trouble though of squashing all the commits into one is that it\n>> makes it impossible to bisect later.  Are you really sure that your\n>> final commit cannot be broken into small commits?  Ideally each commit\n>> is small but self contained.  Squashing should be done only to fix\n>> cases where you introduced a bug then fixed it, or to fix a partial\n>> implementation etc.\n>\n> I think you meant --amend, but it often happens to me that after preparing\n> a three-patch series:\n>\n>        [1/3] Clean up the surrounding code I will touch\n>        [2/3] Lay the groundwork\n>        [3/3] Implement a cool new feature\n>\n> I find that there are more clean-up that should have been done in [1/3].\n> The way \"rebase -i\" expects me to work is:\n>\n>        $ edit ;# more clean-ups\n>        $ git commit -a -m 'squash to \"clean up\"'\n>        $ git rebase -i HEAD~5\n>\n> which will give me\n>\n>        pick 1/3 Clean up ...\n>        pick 2/3 Lay the groundwork\n>        pick 3/3 Implement\n>        pick 4/3 squash to \"clean up\"\n>\n> that I'll change to\n>\n>        pick 1/3 Clean up ...\n>        squash 4/3 squash to \"clean up\"\n>        pick 2/3 Lay the groundwork\n>        pick 3/3 Implement\n\nYeah.  It would be nice to have a 'crush' or something here.\nIt's similar to the arguments to have a command to just edit the\ncommit message in a single go, rather than the rather long way of\nusing edit.\n"},{"id":"116488","messageId":"4A391E63.6000206@gmail.com","threadId":"19839","inReplyTo":"7vvdmurfao.fsf@alter.siamese.dyndns.org","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2009-06-17T16:48:35Z","receivedAt":"2009-06-17T16:48:35Z","isPatch":false,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n> So I can see why a variant of \"squash\" that does not change (nor even ask\n> for a replacement of) the commit log message from the one that is being\n> amended could be useful.\n\nOne way could be to have arguments to squash in a way that was proposed \nfor the sequencer GSOC project last year.  For example,\n\ncommit 123456\nsquash -C HEAD abcdef\n\nwould just proceed with the commit of HEAD, and since squash is \nbasically apply-to-index + commit, the HEAD would still be 123456.\n\nPaolo\n"},{"id":"116489","messageId":"1245258351.24610.32.camel@cp-jk-linux.corp.on2.com","threadId":"19839","inReplyTo":"7vvdmurfao.fsf@alter.siamese.dyndns.org","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"John Koleszar","fromEmail":"john.koleszar@on2.com","sentAt":"2009-06-17T17:05:51Z","receivedAt":"2009-06-17T17:05:51Z","isPatch":false,"sender":{"key":"john.koleszar@on2.com","avatar":null},"body":"On Wed, 2009-06-17 at 12:33 -0400, Junio C Hamano wrote:\n> So I can see why a variant of \"squash\" that does not change (nor even ask\n> for a replacement of) the commit log message from the one that is being\n> amended could be useful.  I am tempted to suggest calling that a \"fixup\"\n> operation, but some people may expect \"fixup\" to mean a variant of \"edit\"\n> that does not bother you by dropping you back to the shell to touch the\n> tree that is recorded (i.e. \"fixing up the commit log message only\"), so\n> it is not a very good word.\n\nI wonder if a better approach might be to add an operator to squash\nrather than another verb. \"squash!\" maybe? This has the nice property\nthat future verbs that have both interactive and non-interactive modes\ncould be made consistent with squash easily, rather than having to think\nof another synonym.\n"},{"id":"116494","messageId":"20090617182036.GA4500@localhost","threadId":"19839","inReplyTo":"7vvdmurfao.fsf@alter.siamese.dyndns.org","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"Clemens Buchacher","fromEmail":"drizzd@aon.at","sentAt":"2009-06-17T18:20:36Z","receivedAt":"2009-06-17T18:20:36Z","isPatch":false,"sender":{"key":"drizzd@gmx.net","avatar":"https://avatars.githubusercontent.com/u/59082?v=4"},"body":"On Wed, Jun 17, 2009 at 09:33:19AM -0700, Junio C Hamano wrote:\n> So I can see why a variant of \"squash\" that does not change (nor even ask\n> for a replacement of) the commit log message from the one that is being\n> amended could be useful.\n\nHow about deleting the commit message header?\n\npick c0ffee not to be modified commit message\npick 012345 squashme\n...\n\n=>\n\npick c0ffee not to be modified commit message\nsquash 012345\n...\n\nIt requires explicit removal the unwanted commit message, avoiding any\naccidents due to ambiguous keywords.\n"},{"id":"116501","messageId":"43d8ce650906171350l52256149m4e7f9cd5cd946ad8@mail.gmail.com","threadId":"19839","inReplyTo":"1245258351.24610.32.camel@cp-jk-linux.corp.on2.com","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"John Tapsell","fromEmail":"johnflux@gmail.com","sentAt":"2009-06-17T20:50:50Z","receivedAt":"2009-06-17T20:50:50Z","isPatch":false,"sender":{"key":"johnflux@gmail.com","avatar":"https://gravatar.com/avatar/25f70d4c0f96396b84a2e34bcd9bdc233462c7b4be29b5fdca8266fc53f30b0c?d=mp&s=160"},"body":"> I wonder if a better approach might be to add an operator to squash\n> rather than another verb. \"squash!\" maybe? This has the nice property\n> that future verbs that have both interactive and non-interactive modes\n> could be made consistent with squash easily, rather than having to think\n> of another synonym.\n\n\nWe could also have   edit!  to just straight the commit message stage,\nand then automatically continue.\n"},{"id":"116505","messageId":"20090618063348.6117@nanako3.lavabit.com","threadId":"19839","inReplyTo":"7vvdmurfao.fsf@alter.siamese.dyndns.org","subject":"[PATCH] rebase -i: auto-squash commits","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2009-06-17T21:33:48Z","receivedAt":"2009-06-17T21:33:48Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"When the commit log message begins with \"squash to ...\", and there\nis a commit whose title begins with the same ..., automatically\nmodify the todo list of rebase -i so that the commit marked for\nsquashing come right after the commit to be modified, and change\nthe action of the moved commit from pick to squash.\n\nSigned-off-by: Nanako Shiraishi <nanako3@lavabit.com>\n---\n\n  Quoting Junio C Hamano <gitster@pobox.com>:\n\n  I think you meant --amend, but it often happens to me that after preparing\n  a three-patch series:\n  \n      [1/3] Clean up the surrounding code I will touch\n      [2/3] Lay the groundwork\n      [3/3] Implement a cool new feature\n  \n  I find that there are more clean-up that should have been done in [1/3].\n  The way \"rebase -i\" expects me to work is:\n  \n      $ edit ;# more clean-ups\n      $ git commit -a -m 'squash to \"clean up\"'\n      $ git rebase -i HEAD~5\n  \n  which will give me\n          \n      pick 1/3 Clean up ...\n      pick 2/3 Lay the groundwork\n      pick 3/3 Implement\n      pick 4/3 squash to \"clean up\"\n  \n  that I'll change to \n  \n      pick 1/3 Clean up ...\n      squash 4/3 squash to \"clean up\"\n      pick 2/3 Lay the groundwork\n      pick 3/3 Implement\n  \n  and then I'll need to edit the commit message for the first two combined.\n\nHow about this patch?  It does not let you say 'squash to \"clean up\"'\nbut other people who are more skillfull than me can enhance such details.\n\n git-rebase--interactive.sh   |   31 +++++++++++++++++++++++++++++++\n t/t3414-rebase-autosquash.sh |   36 ++++++++++++++++++++++++++++++++++++\n 2 files changed, 67 insertions(+), 0 deletions(-)\n create mode 100755 t/t3414-rebase-autosquash.sh\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex f96d887..0832164 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -482,6 +482,35 @@ get_saved_options () {\n \ttest -f \"$DOTEST\"/rebase-root && REBASE_ROOT=t\n }\n \n+# Rearrange the todo list that has both \"pick sha1 msg\" and\n+# \"pick sha1 squash to msg\" in it, so that the latter comes\n+# immediately after the former, and change \"pick\" to \"squash\".\n+rearrange_squash () {\n+\tsed -n -e 's/^pick \\([0-9a-f]*\\) squash to /\\1 /p' \"$1\" >\"$1.sq\"\n+\ttest -s \"$1.sq\" || return\n+\n+\tused=\n+\twhile read pick sha1 message\n+\tdo\n+\t\tcase \" $used\" in\n+\t\t*\" $sha1 \"*) continue ;;\n+\t\tesac\n+\t\techo \"$pick $sha1 $message\"\n+\t\twhile read squash msg\n+\t\tdo\n+\t\t\tcase \"$message\" in\n+\t\t\t\"$msg\"*)\n+\t\t\t\techo \"squash $squash to $msg\"\n+\t\t\t\tused=\"$used$squash \"\n+\t\t\t\tbreak\n+\t\t\t\t;;\n+\t\t\tesac\n+\t\tdone <\"$1.sq\"\n+\tdone <\"$1\" >\"$1.rearranged\"\n+\n+\tcat \"$1.rearranged\" >\"$1\"\n+}\n+\n while test $# != 0\n do\n \tcase \"$1\" in\n@@ -746,6 +776,7 @@ first and then run 'git rebase --continue' again.\"\n \t\tfi\n \n \t\ttest -s \"$TODO\" || echo noop >> \"$TODO\"\n+\t\trearrange_squash \"$TODO\"\n \t\tcat >> \"$TODO\" << EOF\n \n # Rebase $SHORTREVISIONS onto $SHORTONTO\ndiff --git a/t/t3414-rebase-autosquash.sh b/t/t3414-rebase-autosquash.sh\nnew file mode 100755\nindex 0000000..ddb0daf\n--- /dev/null\n+++ b/t/t3414-rebase-autosquash.sh\n@@ -0,0 +1,36 @@\n+#!/bin/sh\n+\n+test_description='auto squash'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\techo 0 > file0\n+\tgit add .\n+\ttest_tick\n+\tgit commit -m \"initial commit\"\n+\techo 0 > file1\n+\techo 2 > file2\n+\tgit add .\n+\ttest_tick\n+\tgit commit -m \"first commit\"\n+\techo 3 > file3\n+\tgit add .\n+\ttest_tick\n+\tgit commit -m \"second commit\"\n+'\n+\n+test_expect_success 'auto squash' '\n+\techo 1 > file1\n+\tgit add -u\n+\ttest_tick\n+\tgit commit -m \"squash to first\"\n+\tgit tag final\n+\ttest_tick\n+\tgit rebase -i HEAD^^^\n+\tgit log --oneline >actual\n+\ttest 3 = $(wc -l <actual) &&\n+\tgit diff --exit-code final\n+'\n+\n+test_done\n-- \n1.6.2.GIT\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"116507","messageId":"alpine.DEB.1.00.0906180007370.26154@pacific.mpi-cbg.de","threadId":"19839","inReplyTo":"20090618063348.6117@nanako3.lavabit.com","subject":"Re: [PATCH] rebase -i: auto-squash commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-06-17T22:08:18Z","receivedAt":"2009-06-17T22:08:18Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 18 Jun 2009, Nanako Shiraishi wrote:\n\n> When the commit log message begins with \"squash to ...\", and there\n\nI do not like this at all.  It assumes that you never have valid commit \nmessages starting with \"squash to\".\n\nCiao,\nDscho\n"},{"id":"116515","messageId":"20090618001111.GB12954@vidovic","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906180007370.26154@pacific.mpi-cbg.de","subject":"[PATCH] Re: rebase -i: auto-squash commits","fromName":"Nicolas Sebrecht","fromEmail":"nicolas.s.dev@gmx.fr","sentAt":"2009-06-18T00:11:11Z","receivedAt":"2009-06-18T00:11:11Z","isPatch":true,"sender":{"key":"nicolas.s.dev@gmx.fr","avatar":null},"body":"The 18/06/09, Johannes Schindelin wrote:\n\n> > When the commit log message begins with \"squash to ...\", and there\n> \n> I do not like this at all.  It assumes that you never have valid commit \n> messages starting with \"squash to\".\n\nPlus, a commit message should not be anything else that a message about\na commit. Please, don't make the Git's behavior depends on the commit\nmessage itself.\n\nIf we need a program to have various behaviours, we have:\n- the compilation options;\n- the command line options;\n- the configuration files.\n\n\n-- \nNicolas Sebrecht\n"},{"id":"116521","messageId":"7v8wjq2kqc.fsf@alter.siamese.dyndns.org","threadId":"19839","inReplyTo":"20090618001111.GB12954@vidovic","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-18T05:07:23Z","receivedAt":"2009-06-18T05:07:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Sebrecht <nicolas.s.dev@gmx.fr> writes:\n\n> The 18/06/09, Johannes Schindelin wrote:\n>\n>> > When the commit log message begins with \"squash to ...\", and there\n>> \n>> I do not like this at all.  It assumes that you never have valid commit \n>> messages starting with \"squash to\".\n>\n> Plus, a commit message should not be anything else that a message about\n> a commit. Please, don't make the Git's behavior depends on the commit\n> message itself.\n>\n> If we need a program to have various behaviours, we have:\n> - the compilation options;\n> - the command line options;\n> - the configuration files.\n\nSorry, but I have to disagree to such a dogmatic statement.\n\nWe do want our commands to be able to act intelligently and/or differently\ndepending on what commit says in some cases.  It is does not make sense to\ninsist that the command line or configuration mechanism must be used.\n\nA really trivial example.  \"git log -p\" shows the patch text for non-merge\ncommits but not for merge commits.  \"git log --grep=foo\" shows only\ncommits that says \"foo\" and \"git log --author=Nicolas\" shows only commits\nwritten by you.  We used to leave an explicit note in the message part of\ncherry-picked commits where they were cherry-picked from; \"git merge\"\nand/or \"git rebase\" could have paid attention to it to act differently\n(i.e. \"ah, even though that commit is not in the ancestry, the moral\nequivalent patch is already applied\").\n\nBesides, if you as the end user want to tell this and that commit are\nspecial among other commits that are being rebased to the command, which\nis the scenario Nana's patch is about, how would you do that from the\ncommand line option?  \"rebase -i --move=4-to-2 --squash=2\"?\n\nI do not necessarily think the behaviour suggested by the patch should be\nthe default, but as an optional feature, it makes perfect sense for a\ncommand to pay attention to commit messages when deciding what to do.\n\nIOW, I understand Dscho's objection that there is a risk that this feature\nmay trigger when not wanted (but more on this later), and I'd be fine if\nit can fire only with an extra option, e.g. \"git rebase -i --autosquash\".\n\nBut from the workflow point of view, I think what the patch tries to do (I\nhaven't studied the actual implementation carefully, so it may not be what\nit actually _does_) makes perfect sense, and it matches what I often do\nvery well.  Accumulate changes as a series of basically sound commits,\nqueue some small \"fix this breakage in that commit\" commits on top of them\nwhile proofreading, and finish the series with \"rebase -i\" to reorder,\nsquash and typofix.\n\nNow, I initially had the same reaction as Dscho.  What happens if I really\nwant to write a commit message that begins with \"squash to \"?\n\nBut after thinking about it a bit more, I do not think it is as bad as it\nsounds anymore.\n\nThe commit not only must begin with \"squash to \" but also there has to be\na matching commit whose message begins with the remainder of the title of\nthe \"squash to\" commit _in the range you are rebasing INTERACTIVELY_.\n\nIn addition, the resulting rebase insn is presented in the editor, and in\na rare case where you do have such a commit, you can rearrange it back.\n"},{"id":"116520","messageId":"7vvdmu15j0.fsf@alter.siamese.dyndns.org","threadId":"19839","inReplyTo":"20090618063348.6117@nanako3.lavabit.com","subject":"Re: [PATCH] rebase -i: auto-squash commits","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-18T05:21:07Z","receivedAt":"2009-06-18T05:21:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nanako Shiraishi <nanako3@lavabit.com> writes:\n\n>       pick 1/3 Clean up ...\n>       pick 2/3 Lay the groundwork\n>       pick 3/3 Implement\n>       pick 4/3 squash to \"clean up\"\n>   \n>   that I'll change to \n>   \n>       pick 1/3 Clean up ...\n>       squash 4/3 squash to \"clean up\"\n>       pick 2/3 Lay the groundwork\n>       pick 3/3 Implement\n>   \n>   and then I'll need to edit the commit message for the first two combined.\n>\n> How about this patch?  It does not let you say 'squash to \"clean up\"'\n> but other people who are more skillfull than me can enhance such details.\n\nI have to admit that I wished to see something like this for more than\nonce.  It would have been nicer if the patch went one step further and did\n\"squash the patch, but use the log message from the commit that is\nsquashed into, without even asking for a consolidated message\", but I\nthink it is a reasonable start.\n\nBut as Dscho already objected to, this is a new feature that is\npotentially dangerous --- there is a risk of matching a commit that was\nnot intended for squashing, albeit small.  We may want an explicit option\nto enable it.  On the other hand, you may be able to argue that use of\n\"interactive\" rebase is already a sign that the user is likely to want\nsuch a convenience, though.\n\n>  git-rebase--interactive.sh   |   31 +++++++++++++++++++++++++++++++\n>  t/t3414-rebase-autosquash.sh |   36 ++++++++++++++++++++++++++++++++++++\n>  2 files changed, 67 insertions(+), 0 deletions(-)\n>  create mode 100755 t/t3414-rebase-autosquash.sh\n>\n> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\n> index f96d887..0832164 100755\n> --- a/git-rebase--interactive.sh\n> +++ b/git-rebase--interactive.sh\n> @@ -482,6 +482,35 @@ get_saved_options () {\n>  \ttest -f \"$DOTEST\"/rebase-root && REBASE_ROOT=t\n>  }\n>  \n> +# Rearrange the todo list that has both \"pick sha1 msg\" and\n> +# \"pick sha1 squash to msg\" in it, so that the latter comes\n> +# immediately after the former, and change \"pick\" to \"squash\".\n> +rearrange_squash () {\n> +\tsed -n -e 's/^pick \\([0-9a-f]*\\) squash to /\\1 /p' \"$1\" >\"$1.sq\"\n> +\ttest -s \"$1.sq\" || return\n> +\n> +\tused=\n> +\twhile read pick sha1 message\n> +\tdo\n> +\t\tcase \" $used\" in\n> +\t\t*\" $sha1 \"*) continue ;;\n> +\t\tesac\n> +\t\techo \"$pick $sha1 $message\"\n> +\t\twhile read squash msg\n> +\t\tdo\n> +\t\t\tcase \"$message\" in\n> +\t\t\t\"$msg\"*)\n\nI guess we could even loosen this \"must match the leading substring\nexactly\" restriction if we can expose Dscho's Levenstein to Porcelain\nwriters.\n\n> +\t\t\t\techo \"squash $squash to $msg\"\n> +\t\t\t\tused=\"$used$squash \"\n> +\t\t\t\tbreak\n> +\t\t\t\t;;\n\nDo you really want to break here?  What happens if I have more than one\nfixup patches to the same commit?\n\n> +\t\t\tesac\n> +\t\tdone <\"$1.sq\"\n> +\tdone <\"$1\" >\"$1.rearranged\"\n> +\n> +\tcat \"$1.rearranged\" >\"$1\"\n> +}\n> +\n>  while test $# != 0\n>  do\n>  \tcase \"$1\" in\n> @@ -746,6 +776,7 @@ first and then run 'git rebase --continue' again.\"\n>  \t\tfi\n>  \n>  \t\ttest -s \"$TODO\" || echo noop >> \"$TODO\"\n> +\t\trearrange_squash \"$TODO\"\n>  \t\tcat >> \"$TODO\" << EOF\n>  \n>  # Rebase $SHORTREVISIONS onto $SHORTONTO\n> diff --git a/t/t3414-rebase-autosquash.sh b/t/t3414-rebase-autosquash.sh\n> new file mode 100755\n> index 0000000..ddb0daf\n> --- /dev/null\n> +++ b/t/t3414-rebase-autosquash.sh\n> @@ -0,0 +1,36 @@\n> +#!/bin/sh\n> +\n> +test_description='auto squash'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success setup '\n> +\techo 0 > file0\n> +\tgit add .\n> +\ttest_tick\n> +\tgit commit -m \"initial commit\"\n> +\techo 0 > file1\n> +\techo 2 > file2\n> +\tgit add .\n> +\ttest_tick\n> +\tgit commit -m \"first commit\"\n> +\techo 3 > file3\n> +\tgit add .\n> +\ttest_tick\n> +\tgit commit -m \"second commit\"\n> +'\n\nThese tests want to be stringed together with && to catch possible\nbreakages during the setup.  The same for the real test below.\n\n> +test_expect_success 'auto squash' '\n> +\techo 1 > file1\n> +\tgit add -u\n> +\ttest_tick\n> +\tgit commit -m \"squash to first\"\n> +\tgit tag final\n> +\ttest_tick\n> +\tgit rebase -i HEAD^^^\n> +\tgit log --oneline >actual\n> +\ttest 3 = $(wc -l <actual) &&\n\nNot just count, but you would want to make sure that the rewritten \"first\ncommit\" now has the desired tree (\"1\" instead of \"0\" in file1, if I am\nreading the test correctly).\n\n> +\tgit diff --exit-code final\n> +'\n> +\n> +test_done\n"},{"id":"116526","messageId":"4A39EAAB.70402@alum.mit.edu","threadId":"19839","inReplyTo":"20090618063348.6117@nanako3.lavabit.com","subject":"Re: [PATCH] rebase -i: auto-squash commits","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2009-06-18T07:20:11Z","receivedAt":"2009-06-18T07:20:11Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Nanako Shiraishi wrote:\n> When the commit log message begins with \"squash to ...\", and there\n> is a commit whose title begins with the same ..., automatically\n> modify the todo list of rebase -i so that the commit marked for\n> squashing come right after the commit to be modified, and change\n> the action of the moved commit from pick to squash.\n\nIt seems to me that even this requires more steps than strictly\nnecessary, namely a commit then a rebase, and conveying the information\nfrom the commit step to the rebase step is somewhat awkward.  Since I\nhave to specify a magic commit message to trigger this behavior, I\nobviously know at the time of the commit that I want to squash the new\nchanges onto an older commit.  So why not implement this functionality\nas a variant of \"commit\"?  Something like:\n\ngit commit --fix=old-commit\n\nwhich would commit the changes in index as an amendment to the specified\nold-commit (requiring no new log message) and then rebase later commits\non top of the new (combined) commit.\n\nIf a conflict arises while applying the changes in index to old-commit,\nthen probably the whole process should be undone and aborted.  If a\nconflict arises while rebasing later commits on top of the combined\ncommit, then the usual rebase conflict-handling machinery would be invoked.\n\nMichael\n"},{"id":"116528","messageId":"7vws7ayo1k.fsf@alter.siamese.dyndns.org","threadId":"19839","inReplyTo":"4A39EAAB.70402@alum.mit.edu","subject":"Re: [PATCH] rebase -i: auto-squash commits","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-18T07:54:47Z","receivedAt":"2009-06-18T07:54:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> It seems to me that even this requires more steps than strictly\n> necessary, namely a commit then a rebase, and conveying the information\n> from the commit step to the rebase step is somewhat awkward.  Since I\n> have to specify a magic commit message to trigger this behavior, I\n> obviously know at the time of the commit that I want to squash the new\n> changes onto an older commit.  So why not implement this functionality\n> as a variant of \"commit\"?\n\nThat may be a good feature, but that won't work as well as the patch being\ndiscussed for _me_.\n\nIOW, I think what you are suggesting is a different feature.\n\nIt largely depends on how you work.  I do not function well when I get\ninterrupted and/or disrupted often, and I would prefer the convenience of\nbeing able to simply queue a trivial patch with a minimum amount of fuss\n(e.g. just leave a note that says \"to be squashed to that other one\" and\nnothing else) when I find a trivial breakage that is unrelated to what I\nam concentrating on.\n\nImagine the \"Clean up the surrounding code\" then \"Lay the groundwork\" and\nfinally \"Implement a cool new feature\" sequence I outlined in the message\nthe patch was response to.  When I thought I am finished cleaning up the\nsurrounding code and laid the groundwork, and finally concentrating on\nimplementing the new feature (which is the fun part), I may notice small\nbreakages and untidiness I could squash into earlier commits.\n\nIt is very distracting, however, if I have to go back to the state _before\nI wrote all the fun code for the new feature_ to fix the breakage right\nthere.  Once I go back, the surrounding code would look all different, and\nI may even be tempted to do the full test cycle before finishing your\n\"amend in the past\" operation.  The distraction will destroy my momentum\nand concentration.\n\nIt's much more easier on my brain to commit the fix-up to be later\nsquashed (use \"add -p then commit\" for that) and continue.  I can keep the\nmomentum going that way.\n\nBut that is how _I_ work.  You may well work differently, and for you\n\"stop, switch brain back to the state before all these fun work and amend,\nthen finally come back\" workflow may work better.\n\nWhat I am saying is that \"a variant of commit\" you talk may be good but it\nwon't be a _replacement_ for the effort to make squash easier to do while\nrunning \"rebase -i\".\n"},{"id":"116534","messageId":"alpine.DEB.1.00.0906181003300.4848@intel-tinevez-2-302","threadId":"19839","inReplyTo":"7v8wjq2kqc.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-06-18T08:06:07Z","receivedAt":"2009-06-18T08:06:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 17 Jun 2009, Junio C Hamano wrote:\n\n> Now, I initially had the same reaction as Dscho.  What happens if I \n> really want to write a commit message that begins with \"squash to \"?\n> \n> But after thinking about it a bit more, I do not think it is as bad as \n> it sounds anymore.\n> \n> The commit not only must begin with \"squash to \" but also there has to \n> be a matching commit whose message begins with the remainder of the \n> title of the \"squash to\" commit _in the range you are rebasing \n> INTERACTIVELY_.\n> \n> In addition, the resulting rebase insn is presented in the editor, and \n> in a rare case where you do have such a commit, you can rearrange it \n> back.\n\nWell, that really sounds pretty awkward to me.  I regularly call such \ncommits \"amend\".  If there is a risk I confuse myself as to which commit \nneeds to be amended, I use \"amend.<short-hint>\".\n\nI'd really rather stay with \"fixup\".  And as I use single-letter commands \nquite often, I'd also rather stay away from that magic \"!\".  And by \n\"magic\" I really mean that: people will not find that magic intuitive at \nall.\n\nMy vote is for \"fixup\".\n\nCiao,\nDscho\n"},{"id":"116535","messageId":"m3r5xigdvn.fsf@localhost.localdomain","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181003300.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-06-18T08:11:53Z","receivedAt":"2009-06-18T08:11:53Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"A bit off-topic: I wonder if there is an easy way to make rebase run\ntestsuite for the each commit it rebases, or even simple compile test,\nto not introduce untestable commits when rebasing by mistake...\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"116537","messageId":"87vdmuhs75.fsf@iki.fi","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181003300.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Teemu Likonen","fromEmail":"tlikonen@iki.fi","sentAt":"2009-06-18T08:17:02Z","receivedAt":"2009-06-18T08:17:02Z","isPatch":true,"sender":{"key":"tlikonen@iki.fi","avatar":null},"body":"On 2009-06-18 10:06 (+0200), Johannes Schindelin wrote:\n\n> I'd really rather stay with \"fixup\". And as I use single-letter\n> commands quite often, I'd also rather stay away from that magic \"!\".\n> And by \"magic\" I really mean that: people will not find that magic\n> intuitive at all.\n\nI don't know about people but I do find \"!\" intuitive. It is squash\nafter all so I like the idea of using small modifier character.\n\n> My vote is for \"fixup\".\n\nMine is for \"squash!\".\n"},{"id":"116538","messageId":"7vk53aymuz.fsf@alter.siamese.dyndns.org","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181003300.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-18T08:20:20Z","receivedAt":"2009-06-18T08:20:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> On Wed, 17 Jun 2009, Junio C Hamano wrote:\n> ...\n>> The commit not only must begin with \"squash to \" but also there has to \n>> be a matching commit whose message begins with the remainder of the \n>> title of the \"squash to\" commit _in the range you are rebasing \n>> INTERACTIVELY_.\n>> \n>> In addition, the resulting rebase insn is presented in the editor, and \n>> in a rare case where you do have such a commit, you can rearrange it \n>> back.\n>\n> Well, that really sounds pretty awkward to me.  I regularly call such \n> commits \"amend\".  If there is a risk I confuse myself as to which commit \n> needs to be amended, I use \"amend.<short-hint>\".\n>\n> I'd really rather stay with \"fixup\".  And as I use single-letter commands \n> quite often, I'd also rather stay away from that magic \"!\".  And by \n> \"magic\" I really mean that: people will not find that magic intuitive at \n> all.\n>\n> My vote is for \"fixup\".\n\nI am too tired to either make the final judgement nor proposal on this\ntopic now, but before I forget here is one tangent.\n\nI also often use \"magic\" commit log message in other occasions.  The most\nimportant is \"[DONTMERGE]\" prefix to somebody else's commit I queue to\n'pu' (or leave unmerged even to 'pu'---just keeping on a topic branch).  I\naccept a patch with \"am\" and then \"amend\" after review when I find that it\nneeds more work.  One day I am hoping to write a pre-merge hook that\nforbids commits marked with such magic to come into 'next' and down.\n\nThe point?\n\nEarlier somebody objected to a command that changes behaviour based on\nwhat is in the commit log message, but for the private commits the patch\nunder discussion deals with and the ones I mark with \"[DONTMERGE]\", the\ncommit log message _is_ the right place to leave a mark for commands to\ntake notice and act differently.\n\nOf course we _could_ use notes for that, but that won't play well with\nrebasing I suppose ...\n"},{"id":"116539","messageId":"7vfxdyymtd.fsf@alter.siamese.dyndns.org","threadId":"19839","inReplyTo":"m3r5xigdvn.fsf@localhost.localdomain","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-18T08:21:18Z","receivedAt":"2009-06-18T08:21:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> A bit off-topic: I wonder if there is an easy way to make rebase run\n> testsuite for the each commit it rebases, or even simple compile test,\n> to not introduce untestable commits when rebasing by mistake...\n\nI used to do that manually, i.e. s/^pick /edit /;\n"},{"id":"116541","messageId":"alpine.DEB.1.00.0906181025460.4848@intel-tinevez-2-302","threadId":"19839","inReplyTo":"7vfxdyymtd.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-06-18T08:26:23Z","receivedAt":"2009-06-18T08:26:23Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 18 Jun 2009, Junio C Hamano wrote:\n\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n> > A bit off-topic: I wonder if there is an easy way to make rebase run \n> > testsuite for the each commit it rebases, or even simple compile test, \n> > to not introduce untestable commits when rebasing by mistake...\n> \n> I used to do that manually, i.e. s/^pick /edit /;\n\nThis could be a command\n\n\trun-foreach (cd t && make)\n\nHmm?\n\nCiao,\nDscho\n"},{"id":"116542","messageId":"alpine.DEB.1.00.0906181028140.4848@intel-tinevez-2-302","threadId":"19839","inReplyTo":"87vdmuhs75.fsf@iki.fi","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-06-18T08:29:58Z","receivedAt":"2009-06-18T08:29:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 18 Jun 2009, Teemu Likonen wrote:\n\n> On 2009-06-18 10:06 (+0200), Johannes Schindelin wrote:\n> \n> > I'd really rather stay with \"fixup\". And as I use single-letter\n> > commands quite often, I'd also rather stay away from that magic \"!\".\n> > And by \"magic\" I really mean that: people will not find that magic\n> > intuitive at all.\n> \n> I don't know about people but I do find \"!\" intuitive. It is squash\n> after all so I like the idea of using small modifier character.\n\nMhm.\n\nSo let's just interpret the \"!\" in the most common meaning, namely to add \nan imperative.  Then it means \"yes, I do want to squash\".  Not \n\"squash, but oh, BTW, I want to lose the second commit message \ncompletely, and I do not want to edit the commit message either\".\n\nReally, I do not see how anybody could find this intuitive at all.  Maybe \nafter reading the manual, but kinda defeats the meaning of the word \n\"intuitive\".\n\nCiao,\nDscho\n"},{"id":"116543","messageId":"alpine.DEB.1.00.0906181030260.4848@intel-tinevez-2-302","threadId":"19839","inReplyTo":"7vk53aymuz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-06-18T08:33:43Z","receivedAt":"2009-06-18T08:33:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 18 Jun 2009, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > On Wed, 17 Jun 2009, Junio C Hamano wrote:\n> > ...\n> >> The commit not only must begin with \"squash to \" but also there has to \n> >> be a matching commit whose message begins with the remainder of the \n> >> title of the \"squash to\" commit _in the range you are rebasing \n> >> INTERACTIVELY_.\n> >> \n> >> In addition, the resulting rebase insn is presented in the editor, and \n> >> in a rare case where you do have such a commit, you can rearrange it \n> >> back.\n> >\n> > Well, that really sounds pretty awkward to me.  I regularly call such \n> > commits \"amend\".  If there is a risk I confuse myself as to which commit \n> > needs to be amended, I use \"amend.<short-hint>\".\n> >\n> > I'd really rather stay with \"fixup\".  And as I use single-letter commands \n> > quite often, I'd also rather stay away from that magic \"!\".  And by \n> > \"magic\" I really mean that: people will not find that magic intuitive at \n> > all.\n> >\n> > My vote is for \"fixup\".\n> \n> I am too tired to either make the final judgement nor proposal on this \n> topic now,\n\nOkay, I'll add another point that should convince you that the commit \nmessage is not the good place to trigger that behavior:\n\nInteractive rebasing is about having made a quite messy patch series, \nmaybe having a few fixup commits, and then deciding how to clean it up.\n\nThe decision how to clean it up is very much a rebase-time decision, not a \ncommit-time decision.\n\nFor example, it is very easy to decide that you want to squash one fixup \nafter all instead of leaving it stand-alone.\n\n> Of course we _could_ use notes for that, but that won't play well with\n> rebasing I suppose ...\n\nReminds me.  Nothing has happened on that front, right?\n\nCiao,\nDscho\n"},{"id":"116544","messageId":"vpqbpomey8c.fsf@bauges.imag.fr","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181003300.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2009-06-18T08:34:59Z","receivedAt":"2009-06-18T08:34:59Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> I'd really rather stay with \"fixup\".\n\nI like fixup. I'd say \"fixup: <message>\" so that the thing actually\nlooks like a program directive rather than natural language.\n\n(I disliked this at first, but I may actually like it if it gets into\nGit!)\n\n-- \nMatthieu\n"},{"id":"116547","messageId":"4A39FE56.8070808@drmicha.warpmail.net","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181030260.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2009-06-18T08:44:06Z","receivedAt":"2009-06-18T08:44:06Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Johannes Schindelin venit, vidit, dixit 18.06.2009 10:33:\n> Hi,\n> \n> On Thu, 18 Jun 2009, Junio C Hamano wrote:\n> \n>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>>\n>>> On Wed, 17 Jun 2009, Junio C Hamano wrote:\n>>> ...\n>>>> The commit not only must begin with \"squash to \" but also there has to \n>>>> be a matching commit whose message begins with the remainder of the \n>>>> title of the \"squash to\" commit _in the range you are rebasing \n>>>> INTERACTIVELY_.\n>>>>\n>>>> In addition, the resulting rebase insn is presented in the editor, and \n>>>> in a rare case where you do have such a commit, you can rearrange it \n>>>> back.\n>>>\n>>> Well, that really sounds pretty awkward to me.  I regularly call such \n>>> commits \"amend\".  If there is a risk I confuse myself as to which commit \n>>> needs to be amended, I use \"amend.<short-hint>\".\n>>>\n>>> I'd really rather stay with \"fixup\".  And as I use single-letter commands \n>>> quite often, I'd also rather stay away from that magic \"!\".  And by \n>>> \"magic\" I really mean that: people will not find that magic intuitive at \n>>> all.\n>>>\n>>> My vote is for \"fixup\".\n>>\n>> I am too tired to either make the final judgement nor proposal on this \n>> topic now,\n> \n> Okay, I'll add another point that should convince you that the commit \n> message is not the good place to trigger that behavior:\n> \n> Interactive rebasing is about having made a quite messy patch series, \n> maybe having a few fixup commits, and then deciding how to clean it up.\n> \n> The decision how to clean it up is very much a rebase-time decision, not a \n> commit-time decision.\n> \n> For example, it is very easy to decide that you want to squash one fixup \n> after all instead of leaving it stand-alone.\n> \n>> Of course we _could_ use notes for that, but that won't play well with\n>> rebasing I suppose ...\n> \n> Reminds me.  Nothing has happened on that front, right?\n\n<!--#if expr=\"$SARCASM_ON\" -->\nNo, but isn't that the true purpose of out-sourcing? You've got someone\nelse to blame now!\n<!--#endif -->\n\nCheers,\nMichael\n"},{"id":"116546","messageId":"87r5xihqxw.fsf@iki.fi","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181028140.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Teemu Likonen","fromEmail":"tlikonen@iki.fi","sentAt":"2009-06-18T08:44:11Z","receivedAt":"2009-06-18T08:44:11Z","isPatch":true,"sender":{"key":"tlikonen@iki.fi","avatar":null},"body":"On 2009-06-18 10:29 (+0200), Johannes Schindelin wrote:\n\n> So let's just interpret the \"!\" in the most common meaning, namely to\n> add an imperative. Then it means \"yes, I do want to squash\". Not\n> \"squash, but oh, BTW, I want to lose the second commit message\n> completely, and I do not want to edit the commit message either\".\n\nMy main point is the \"small modifier character\" for squash. Perhaps\n\"squash*\" is better? I'll repeat that it is still doing very much the\nsame thing as \"squash\" expect for one little thing. Hence it would be\nnice to use only small modifier character, not totally new word with\npossibly different connotations.\n\n    pick aaaa ...\n    squash* bbbb Small fix to be squashed\n    pick cccc ...\n    pick dddd ...\n"},{"id":"116548","messageId":"alpine.DEB.1.00.0906181042270.4848@intel-tinevez-2-302","threadId":"19839","inReplyTo":"vpqbpomey8c.fsf@bauges.imag.fr","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-06-18T08:44:36Z","receivedAt":"2009-06-18T08:44:36Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 18 Jun 2009, Matthieu Moy wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > I'd really rather stay with \"fixup\".\n> \n> I like fixup. I'd say \"fixup: <message>\" so that the thing actually\n> looks like a program directive rather than natural language.\n\nUmm...  The thing would be used like this:\n\noriginal edit list:\n\n\tpick b1ab1ab First commit\n\tpick deafbee Second commit\n\tpick 0123456 This is a fixup for the first commit\n\nedited edit list:\n\n\tpick b1ab1ab First commit\n\tfixup 0123456 This is a fixup for the first commit\n\tpick deafbee Second commit\n\nIt would squash the first two commits, forget about the second commit \nmessage and continue with the last commit.  No user interaction unless \nthere are merge conflicts.\n\nCiao,\nDscho\n"},{"id":"116549","messageId":"vpqws79c3yj.fsf@bauges.imag.fr","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181042270.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2009-06-18T08:59:32Z","receivedAt":"2009-06-18T08:59:32Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Hi,\n>\n> On Thu, 18 Jun 2009, Matthieu Moy wrote:\n>\n>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>> \n>> > I'd really rather stay with \"fixup\".\n>> \n>> I like fixup. I'd say \"fixup: <message>\" so that the thing actually\n>> looks like a program directive rather than natural language.\n\n[...]\n\n> edited edit list:\n>\n> \tpick b1ab1ab First commit\n> \tfixup 0123456 This is a fixup for the first commit\n> \tpick deafbee Second commit\n\nSorry, we were not talking about the same thing: I was still talking\nabout the dwimery in the commit message. So, yes, your \"fixup\" (that\ncould be abbreviated by \"f\") sounds good to me.\n\nBut some (optional) magic to get the edited list by default could be\nnice in addition, and that could be triggered by \"fixup: ...\" in the\ncommit message.\n\nI do often find myself commiting something knowing that the commit is\nmeant for rebase+squash-ing (i.e. I know that at commit time more\noften than at rebase time).\n\n(not yet 100% convinced myself, and I can sure do without)\n\n-- \nMatthieu\n"},{"id":"116556","messageId":"20090618105859.GA12924@vidovic","threadId":"19839","inReplyTo":"7v8wjq2kqc.fsf@alter.siamese.dyndns.org","subject":"[PATCH] Re: rebase -i: auto-squash commits","fromName":"Nicolas Sebrecht","fromEmail":"nicolas.s.dev@gmx.fr","sentAt":"2009-06-18T10:59:00Z","receivedAt":"2009-06-18T10:59:00Z","isPatch":true,"sender":{"key":"nicolas.s.dev@gmx.fr","avatar":null},"body":"The 17/06/09, Junio C Hamano wrote:\n\n> We do want our commands to be able to act intelligently and/or differently\n> depending on what commit says in some cases.  It is does not make sense to\n> insist that the command line or configuration mechanism must be used.\n> \n> A really trivial example.  \"git log -p\" shows the patch text for non-merge\n> commits but not for merge commits.  \"git log --grep=foo\" shows only\n> commits that says \"foo\" and \"git log --author=Nicolas\" shows only commits\n> written by you.  We used to leave an explicit note in the message part of\n> cherry-picked commits where they were cherry-picked from; \"git merge\"\n> and/or \"git rebase\" could have paid attention to it to act differently\n> (i.e. \"ah, even though that commit is not in the ancestry, the moral\n> equivalent patch is already applied\").\n\nBut I see a huge difference between a message added by the program\nitself to act well on possible comming cases and a message added by the\nuser to act differently at the commit time.\n\nThe latter case is exposed to the user mistakes (wrong typo,\nunintentional matching pattern, etc) which could leave the repository in\nunexpected states.\n\nGit is enough hard to learn. Please, don't make the learning curve even\nworse. Having the commit message possibly making git acts differently is\nnot usual or expected by most users.\n\n> Besides, if you as the end user want to tell this and that commit are\n> special among other commits that are being rebased to the command, which\n> is the scenario Nana's patch is about, how would you do that from the\n> command line option?  \"rebase -i --move=4-to-2 --squash=2\"?\n\nWell, as we always squash to one of the first direct ancestor and as\nsquashing to a merge is not usual (here at least), in most cases it just\ngives \"rebase -i --move=4-to-2\" wich sounds reasonable enough to me.\n\n\n-- \nNicolas Sebrecht\n"},{"id":"116558","messageId":"20090618111855.GB12924@vidovic","threadId":"19839","inReplyTo":"7vk53aymuz.fsf@alter.siamese.dyndns.org","subject":"[PATCH] Re: rebase -i: auto-squash commits","fromName":"Nicolas Sebrecht","fromEmail":"nicolas.s.dev@gmx.fr","sentAt":"2009-06-18T11:18:55Z","receivedAt":"2009-06-18T11:18:55Z","isPatch":true,"sender":{"key":"nicolas.s.dev@gmx.fr","avatar":null},"body":"The 18/06/09, Junio C Hamano wrote:\n\n> I also often use \"magic\" commit log message in other occasions.  The most\n> important is \"[DONTMERGE]\" prefix to somebody else's commit I queue to\n> 'pu' (or leave unmerged even to 'pu'---just keeping on a topic branch).  I\n> accept a patch with \"am\" and then \"amend\" after review when I find that it\n> needs more work.  One day I am hoping to write a pre-merge hook that\n> forbids commits marked with such magic to come into 'next' and down.\n> \n> The point?\n> \n> Earlier somebody objected to a command that changes behaviour based on\n> what is in the commit log message, but for the private commits the patch\n> under discussion deals with and the ones I mark with \"[DONTMERGE]\", the\n> commit log message _is_ the right place to leave a mark for commands to\n> take notice and act differently.\n> \n> Of course we _could_ use notes for that, but that won't play well with\n> rebasing I suppose ...\n\nNot for now; you're right. But what I see here is all about\ncommit/branch metadata to make our like with workflows easier.\n\nWhat about implementing a true metadata feature into Git? There are a\nlot of nice possible functionalities around metadata.\n\nFast, stupid and superficial thoughts on that:\n- have metadata to make git to act differently and/or for information\n  purpose;\n- let the user create its own metadata for his own purpose;\n- let the user have hooks script where appropriate.\n\n\n-- \nNicolas Sebrecht\n"},{"id":"116561","messageId":"alpine.DEB.1.00.0906181415520.4848@intel-tinevez-2-302","threadId":"19839","inReplyTo":"87r5xihqxw.fsf@iki.fi","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-06-18T12:16:33Z","receivedAt":"2009-06-18T12:16:33Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 18 Jun 2009, Teemu Likonen wrote:\n\n> On 2009-06-18 10:29 (+0200), Johannes Schindelin wrote:\n> \n> > So let's just interpret the \"!\" in the most common meaning, namely to \n> > add an imperative. Then it means \"yes, I do want to squash\". Not \n> > \"squash, but oh, BTW, I want to lose the second commit message \n> > completely, and I do not want to edit the commit message either\".\n> \n> My main point is the \"small modifier character\" for squash. Perhaps\n> \"squash*\" is better?\n\nIf you think that putting a special meaning to a special character is \nintuitive, I have to inform you that you are mistaken.\n\nCiao,\nDscho\n"},{"id":"116565","messageId":"m3my85hem2.fsf@localhost.localdomain","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181415520.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-06-18T13:10:41Z","receivedAt":"2009-06-18T13:10:41Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> On Thu, 18 Jun 2009, Teemu Likonen wrote:\n> \n> > On 2009-06-18 10:29 (+0200), Johannes Schindelin wrote:\n> > \n> > > So let's just interpret the \"!\" in the most common meaning, namely to \n> > > add an imperative. Then it means \"yes, I do want to squash\". Not \n> > > \"squash, but oh, BTW, I want to lose the second commit message \n> > > completely, and I do not want to edit the commit message either\".\n> > \n> > My main point is the \"small modifier character\" for squash. Perhaps\n> > \"squash*\" is better?\n> \n> If you think that putting a special meaning to a special character is \n> intuitive, I have to inform you that you are mistaken.\n\nNice bike-shedding... But UI is hard to change later, usually.\n\nYet another proposition would be to simply remove subject to mark\ncommit to be squashed without adding commit message to squashed result\ncommit message\n\n    pick aaaa ...\n    squash bbbb\n    pick cccc ...\n    pick dddd ...\n\n Just my 2 eurocents.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"116572","messageId":"1245333895.30640.28.camel@cp-jk-linux.corp.on2.com","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181028140.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"John Koleszar","fromEmail":"john.koleszar@on2.com","sentAt":"2009-06-18T14:04:55Z","receivedAt":"2009-06-18T14:04:55Z","isPatch":true,"sender":{"key":"john.koleszar@on2.com","avatar":null},"body":"On Thu, 2009-06-18 at 04:29 -0400, Johannes Schindelin wrote:\n> Hi,\n> \n> On Thu, 18 Jun 2009, Teemu Likonen wrote:\n> \n> > On 2009-06-18 10:06 (+0200), Johannes Schindelin wrote:\n> > \n> > > I'd really rather stay with \"fixup\". And as I use single-letter\n> > > commands quite often, I'd also rather stay away from that magic \"!\".\n> > > And by \"magic\" I really mean that: people will not find that magic\n> > > intuitive at all.\n> > \n> > I don't know about people but I do find \"!\" intuitive. It is squash\n> > after all so I like the idea of using small modifier character.\n> \n> Mhm.\n> \n> So let's just interpret the \"!\" in the most common meaning, namely to add \n> an imperative.  Then it means \"yes, I do want to squash\".  Not \n> \"squash, but oh, BTW, I want to lose the second commit message \n> completely, and I do not want to edit the commit message either\".\n> \n> Really, I do not see how anybody could find this intuitive at all.  Maybe \n> after reading the manual, but kinda defeats the meaning of the word \n> \"intuitive\".\n\nThe imperative is actually the reason I picked that modifier, as in\n\"yes, I /really/ do want to squash. Don't ask me, just do it!\" Something\nakin to -f. I think it makes sense here, but not in the case someone\nelse mentioned of a commit message only edit. (\"recommit\" for that\ncase?) \n\nIn any case, I think this non-interactive squash is orthagonal to being\nable to automatically rearrange the commits by \"squash to ...\". I think\nthat's a cool idea, but I know that I often don't remember the text of\nthe commit I want to squash into. So in my case I prefer rearranging\nmanually and squashing non-interactively. If I planned ahead, I could\npick a prefix for each \"class\" of commit, and then \"squash to prefix\",\nbut I'd want to be able to edit the original commit to remove the\nprefix. Sure, I could look at the log, but if I'm just writing a\nnonsense message to remind myself where to squash to, I think it would\nget in the way of my flow.\n"},{"id":"116602","messageId":"20090619065534.6117@nanako3.lavabit.com","threadId":"19839","inReplyTo":"7vvdmu15j0.fsf@alter.siamese.dyndns.org","subject":"[PATCH v2] rebase -i --autosquash: auto-squash commits","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2009-06-18T21:55:34Z","receivedAt":"2009-06-18T21:55:34Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Teach a new option, --autosquash, to the interactive rebase.\nWhen the commit log message begins with \"!fixup ...\", and there\nis a commit whose title begins with the same ..., automatically\nmodify the todo list of rebase -i so that the commit marked for\nsquashing come right after the commit to be modified, and change\nthe action of the moved commit from pick to squash.\n\nThis will help the use case outlined in\n\n    From: Junio C Hamano <gitster@pobox.com>\n    Date: Wed, 17 Jun 2009 09:33:19 -0700\n    Subject: Re: git rebase --interactive squash/squish/fold/rollup\n    Message-ID: <7vvdmurfao.fsf@alter.siamese.dyndns.org>\n\nand further explained in\n\n    From: Junio C Hamano <gitster@pobox.com>\n    Date: Thu, 18 Jun 2009 00:54:47 -0700\n    Subject: Re: [PATCH] rebase -i: auto-squash commits\n    Message-ID: <7vws7ayo1k.fsf@alter.siamese.dyndns.org>\n\nSigned-off-by: Nanako Shiraishi <nanako3@lavabit.com>\n---\n\nChanges from my yesterday's patch are as follows.\n\n * The feature is disabled by default; the user needs to explicitly ask for it with --autosquash option.\n * Squashing more than one commits to the same commit should work.\n * The commit message must begin with a more magic string \"!fixup\" instead of \"squash to\".\n * Commands in the test script are joined with &&.\n * The test examines the content of the file to verify that the commit was correctly squashed.\n * Add documentation.\n\n Documentation/git-rebase.txt |    9 +++++++++\n git-rebase--interactive.sh   |   35 +++++++++++++++++++++++++++++++++++\n t/t3414-rebase-autosquash.sh |   37 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 81 insertions(+), 0 deletions(-)\n create mode 100755 t/t3414-rebase-autosquash.sh\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 26f3b7b..0c2f99e 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -293,6 +293,15 @@ OPTIONS\n \troot commits will be rewritten to have <newbase> as parent\n \tinstead.\n \n+--autosquash::\n+\tWhen the commit log message begins with \"!fixup ...\", and there\n+\tis a commit whose title begins with the same ..., automatically\n+\tmodify the todo list of rebase -i so that the commit marked for\n+\tsquashing come right after the commit to be modified, and change\n+\tthe action of the moved commit from pick to squash.\n++\n+This option is only valid when '--interactive' option is used.\n+\n include::merge-strategies.txt[]\n \n NOTES\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex f96d887..6e223d5 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -28,6 +28,7 @@ abort              abort rebasing process and restore original branch\n skip               skip current patch and continue rebasing process\n no-verify          override pre-rebase hook from stopping the operation\n root               rebase all reachable commmits up to the root(s)\n+autosquash         automatically squash commits that begin with !fixup\n \"\n \n . git-sh-setup\n@@ -46,6 +47,7 @@ ONTO=\n VERBOSE=\n OK_TO_SKIP_PRE_REBASE=\n REBASE_ROOT=\n+AUTOSQUASH=\n \n GIT_CHERRY_PICK_HELP=\"  After resolving the conflicts,\n mark the corrected paths with 'git add <paths>', and\n@@ -482,6 +484,35 @@ get_saved_options () {\n \ttest -f \"$DOTEST\"/rebase-root && REBASE_ROOT=t\n }\n \n+# Rearrange the todo list that has both \"pick sha1 msg\" and\n+# \"pick sha1 !fixup msg\" appears in it so that the latter\n+# comes immediately after the former, and change \"pick\" to\n+# \"squash\".\n+rearrange_squash () {\n+\tsed -n -e 's/^pick \\([0-9a-f]*\\) !fixup /\\1 /p' \"$1\" >\"$1.sq\"\n+\ttest -s \"$1.sq\" || return\n+\n+\tused=\n+\twhile read pick sha1 message\n+\tdo\n+\t\tcase \" $used\" in\n+\t\t*\" $sha1 \"*) continue ;;\n+\t\tesac\n+\t\techo \"$pick $sha1 $message\"\n+\t\twhile read squash msg\n+\t\tdo\n+\t\t\tcase \"$message\" in\n+\t\t\t\"$msg\"*)\n+\t\t\t\techo \"squash $squash !fixup $msg\"\n+\t\t\t\tused=\"$used$squash \"\n+\t\t\t\t;;\n+\t\t\tesac\n+\t\tdone <\"$1.sq\"\n+\tdone <\"$1\" >\"$1.rearranged\"\n+\n+\tcat \"$1.rearranged\" >\"$1\"\n+}\n+\n while test $# != 0\n do\n \tcase \"$1\" in\n@@ -587,6 +618,9 @@ first and then run 'git rebase --continue' again.\"\n \t--root)\n \t\tREBASE_ROOT=t\n \t\t;;\n+\t--autosquash)\n+\t\tAUTOSQUASH=t\n+\t\t;;\n \t--onto)\n \t\tshift\n \t\tONTO=$(git rev-parse --verify \"$1\") ||\n@@ -746,6 +780,7 @@ first and then run 'git rebase --continue' again.\"\n \t\tfi\n \n \t\ttest -s \"$TODO\" || echo noop >> \"$TODO\"\n+\t\ttest -n \"$AUTOSQUASH\" && rearrange_squash \"$TODO\"\n \t\tcat >> \"$TODO\" << EOF\n \n # Rebase $SHORTREVISIONS onto $SHORTONTO\ndiff --git a/t/t3414-rebase-autosquash.sh b/t/t3414-rebase-autosquash.sh\nnew file mode 100755\nindex 0000000..161cab4\n--- /dev/null\n+++ b/t/t3414-rebase-autosquash.sh\n@@ -0,0 +1,37 @@\n+#!/bin/sh\n+\n+test_description='auto squash'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\techo 0 > file0 &&\n+\tgit add . &&\n+\ttest_tick &&\n+\tgit commit -m \"initial commit\" &&\n+\techo 0 > file1 &&\n+\techo 2 > file2 &&\n+\tgit add . &&\n+\ttest_tick &&\n+\tgit commit -m \"first commit\" &&\n+\techo 3 > file3 &&\n+\tgit add . &&\n+\ttest_tick &&\n+\tgit commit -m \"second commit\"\n+'\n+\n+test_expect_success 'auto squash' '\n+\techo 1 > file1 &&\n+\tgit add -u &&\n+\ttest_tick &&\n+\tgit commit -m \"!fixup first\"\n+\tgit tag final &&\n+\ttest_tick &&\n+\tgit rebase --autosquash -i HEAD^^^ &&\n+\tgit log --oneline >actual &&\n+\ttest 3 = $(wc -l <actual) &&\n+\tgit diff --exit-code final &&\n+\ttest 1 = \"$(git cat-file blob HEAD^:file1)\"\n+'\n+\n+test_done\n-- \n1.6.2.GIT\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"116603","messageId":"e1868cfe0906181531o2e4aa8fwd45477216ede98c1@mail.gmail.com","threadId":"19839","inReplyTo":"20090617182036.GA4500@localhost","subject":"Re: git rebase --interactive squash/squish/fold/rollup","fromName":"Minty","fromEmail":"mintywalker@gmail.com","sentAt":"2009-06-18T22:31:22Z","receivedAt":"2009-06-18T22:31:22Z","isPatch":false,"sender":{"key":"mintywalker@gmail.com","avatar":null},"body":"> On Wed, Jun 17, 2009 at 09:33:19AM -0700, Junio C Hamano wrote:\n>> So I can see why a variant of \"squash\" that does not change (nor even ask\n>> for a replacement of) the commit log message from the one that is being\n>> amended could be useful.\n>\n> How about deleting the commit message header?\n> [snip]\n> It requires explicit removal the unwanted commit message, avoiding any\n> accidents due to ambiguous keywords.\n\nI'm quite liking this idea, albeit a subtle feature.  Which is just fine.\n\n>From what a quick look suggests, git-rebase--interactive.sh is the\nfirst port of call.  Along with the documentation.\n\nI will see what I can put together, albeit not until next week now.\n\nThank you all for the input.\n"},{"id":"116604","messageId":"81b0412b0906181535w6f02d00bw3678b901a477e8e6@mail.gmail.com","threadId":"19839","inReplyTo":"20090619065534.6117@nanako3.lavabit.com","subject":"Re: [PATCH v2] rebase -i --autosquash: auto-squash commits","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2009-06-18T22:35:23Z","receivedAt":"2009-06-18T22:35:23Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"2009/6/18 Nanako Shiraishi <nanako3@lavabit.com>:\n> Teach a new option, --autosquash, to the interactive rebase.\n> When the commit log message begins with \"!fixup ...\", and there\n\nCan I suggest to rename it into \"--autofixup\"? Or even \"--auto=!fixup\"?\nJust so that people have one thing less to remember.\n"},{"id":"116612","messageId":"buo7hz8u1x2.fsf@dhlpc061.dev.necel.com","threadId":"19839","inReplyTo":"alpine.DEB.1.00.0906181030260.4848@intel-tinevez-2-302","subject":"Re: [PATCH] Re: rebase -i: auto-squash commits","fromName":"Miles Bader","fromEmail":"miles@gnu.org","sentAt":"2009-06-19T07:18:33Z","receivedAt":"2009-06-19T07:18:33Z","isPatch":true,"sender":{"key":"miles@gnu.org","avatar":"https://gravatar.com/avatar/01069b69593af7bff28e2f97afeb3644ae6fe2f5f56cb3a8cf34c5fb8c36efe5?d=mp&s=160"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> Okay, I'll add another point that should convince you that the commit \n> message is not the good place to trigger that behavior:\n>\n> Interactive rebasing is about having made a quite messy patch series, \n> maybe having a few fixup commits, and then deciding how to clean it up.\n>\n> The decision how to clean it up is very much a rebase-time decision, not a \n> commit-time decision.\n\nI agree.\n\nMagic commit messages are not good for this kind of thing.\n\n-Miles\n\n-- \nDo not taunt Happy Fun Ball.\n"},{"id":"116648","messageId":"18DDBEE4-8107-4E0D-B503-0F3BB0A81DC9@wincent.com","threadId":"19839","inReplyTo":"20090619065534.6117@nanako3.lavabit.com","subject":"Re: [PATCH v2] rebase -i --autosquash: auto-squash commits","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2009-06-19T23:07:04Z","receivedAt":"2009-06-19T23:07:04Z","isPatch":true,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"El 18/6/2009, a las 23:55, Nanako Shiraishi escribió:\n\n> Teach a new option, --autosquash, to the interactive rebase.\n> When the commit log message begins with \"!fixup ...\", and there\n> is a commit whose title begins with the same ..., automatically\n> modify the todo list of rebase -i so that the commit marked for\n> squashing come right after the commit to be modified, and change\n> the action of the moved commit from pick to squash.\n>\n> This will help the use case outlined in\n>\n>    From: Junio C Hamano <gitster@pobox.com>\n>    Date: Wed, 17 Jun 2009 09:33:19 -0700\n>    Subject: Re: git rebase --interactive squash/squish/fold/rollup\n>    Message-ID: <7vvdmurfao.fsf@alter.siamese.dyndns.org>\n\nDefinitely a fairly common workflow for me. Faced with a sequence like  \nthis:\n\n\t[1/3] Cleanup\n\t[2/3] Lay groundwork\n\t[3/3] Implement feature\n\t[4/4] Doh! more cleanup that should have gone in [1/3]\n\nI usually just let 4/4 stand as a separate commit with a message like:\n\n\tMore cleanup of XYZ\n\n\tIdeally this should have been included in commit abcd1234,\n\tbut wasn't noticed until too late.\n\nSeeing as I'm not perfect, I don't necessarily spend time manipulating  \nthe history to make it appear that I really am perfect.\n\nEven so, if asked to imagine an ideal workflow for this scenario, I  \ndon't really want a new switch for \"git rebase -i\", but rather the  \nability to do \"git commit --amend\" on a non-head commit. (I know this  \nhas come up on the list back in February under the subject \"FEATURE  \nsuggestion git commit --amend <ref>\".)\n\nBasically, if you do the following:\n\n\tedit\n\tgit add foo\n\tgit commit -m \"Cleanup\"\n\tedit\n\tgit add foo\n\tgit commit -m \"Lay groundwork\"\n\tedit\n\tgit add foo\n\tgit commit -m \"Implement feature\"\n\t# doh! found stuff that should have gone in in step one!\n\tedit\n\tgit add foo\n\tgit commit --amend HEAD~3\n\nMy intention would be for git to actually:\n\n\t1. Create a temporary throw-away commit (without updating the HEAD)\n\n\t2. Do the equivalent of using \"git rebase -i\" to squash that  \ntemporary commit into the HEAD~3 commit, providing you with the  \nopportunity to edit the adjust the commit message if necessary.\n\n\t3. In the event of failure to replay the other commits on top, you  \nwould want the process to dump you back where you started (same HEAD  \nas before, with same changes staged in the index) and an error message  \ninforming you that the changes didn't apply cleanly and that you  \nshould use \"git rebase -i\" instead to walk through the process manually.\n\nAt least for me that would be the ideal interface to this kind of  \nfeature. I can't really see myself using these magic commit messages  \nand the --autosquash switch.\n\nHowever, the \"FEATURE suggestion git commit --amend <ref>\" thread  \ncaused a lot of objections to be raised. Things like:\n\n\t- what if <ref> is a merge?\n\n\t- what if there are merges between <ref> and the current HEAD?\n\n\t- what if the amendment breaks reapplication of later commits?\n\n\t- what if <ref> is not an ancestor of the current HEAD?\n\n\t- what if <ref> is part of more than one branch? (and would the user  \nbe confused if it was only rewritten on one branch?)\n\nBasically as I see it, the kind of workflow being discussed here  \nshould only be for the simple case of amending really simple histories  \n(basic topic branches) and should bail loudly if pretty much any of  \nthe above conditions are true.\n\nCheers,\nWincent\n"},{"id":"116649","messageId":"20090620104640.6117@nanako3.lavabit.com","threadId":"19839","inReplyTo":"18DDBEE4-8107-4E0D-B503-0F3BB0A81DC9@wincent.com","subject":"Re: [PATCH v2] rebase -i --autosquash: auto-squash commits","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2009-06-20T01:46:40Z","receivedAt":"2009-06-20T01:46:40Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Quoting Wincent Colaiuta <win@wincent.com>:\n\n> El 18/6/2009, a las 23:55, Nanako Shiraishi escribió:\n> ...\n>> This will help the use case outlined in\n>>\n>>    From: Junio C Hamano <gitster@pobox.com>\n>>    Date: Wed, 17 Jun 2009 09:33:19 -0700\n>>    Subject: Re: git rebase --interactive squash/squish/fold/rollup\n>>    Message-ID: <7vvdmurfao.fsf@alter.siamese.dyndns.org>\n>\n> Definitely a fairly common workflow for me. Faced with a sequence like\n> this:\n>\n> \t[1/3] Cleanup\n> \t[2/3] Lay groundwork\n> \t[3/3] Implement feature\n> \t[4/4] Doh! more cleanup that should have gone in [1/3]\n>\n> I usually just let 4/4 stand as a separate commit with a message like:\n>\n> \tMore cleanup of XYZ\n>\n> \tIdeally this should have been included in commit abcd1234,\n> \tbut wasn't noticed until too late.\n>\n> Seeing as I'm not perfect, I don't necessarily spend time manipulating\n> the history to make it appear that I really am perfect.\n\nI don't think it is about pretending to be perfect.\nIf you are preparing a patch series to be reviewed, it is a minimum required courtesy to the reviewers to remove such earlier mistakes before submitting.\nIt is called \"making your series presentable.\"\n\n> Even so, if asked to imagine an ideal workflow for this scenario, I\n> don't really want a new switch for \"git rebase -i\", but rather the\n> ability to do \"git commit --amend\" on a non-head commit. (I know this\n> has come up on the list back in February under the subject \"FEATURE\n> suggestion git commit --amend <ref>\".)\n\nI think you didn't read the explanation by Junio (the second message I quoted) why that is only one of the options, and isn't a satisfying solution for him. He explicitly said that he doesn't want his momentum disrupted by having to go back before he finishes the series, while admitting that the way you suggest may fit other people's workflow better.\n\nAs to the extra option, I don't like it, either (my original patch didn't have it). I added it only because Johannes Schindelin objected to the patch that the feature can trigger unexpectedly.\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"}]}