{"thread":{"id":"9002","subject":"Volume of commits","startedAt":"2007-07-12T13:16:47Z","lastAt":"2007-07-21T17:12:03Z","messageCount":14,"participants":["Fredrik Tolf","VMiklos","Karl Hasselström","Johannes Schindelin","Joshua N Pritikin","Linus Torvalds","Jakub Narebski","Sven Verdoolaege","Alex Riesen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"47158","messageId":"m3ps2xu5hc.fsf@pc7.dolda2000.com","threadId":"9002","inReplyTo":null,"subject":"Volume of commits","fromName":"Fredrik Tolf","fromEmail":"fredrik@dolda2000.com","sentAt":"2007-07-12T13:16:47Z","receivedAt":"2007-07-12T13:16:47Z","isPatch":false,"sender":{"key":"fredrik@dolda2000.com","avatar":null},"body":"Hi List,\n\nI was wondering -- whenever I see Git patches committed to projects\nlike the Linux kernel or Git itself, the commits always seems to be\ncommitting rather large changes and be rather well-defined in terms of\nwhat they change.\n\nWhen I develop for myself, I usually commit incrementally quite a\nbit, if for no other reason because Git won't let me switch between\nbranches if I don't commit first. I usually try to keep my commits\nwell-defined, but I don't manage to get anywhere close to what I see\nwhen I look at the history of Linux or Git.\n\nSo what I'm wondering is how you people manage to do this? Do you\nactually always commit changes this way (and, in that case, how do you\nswitch between branches)? Or do you somehow aggregate the smaller\ncommits into larger patches and recommit them? Or is there some third\npossibility that I'm missing?\n\nFredrik Tolf\n"},{"id":"47159","messageId":"20070712132937.GQ19386@genesis.frugalware.org","threadId":"9002","inReplyTo":"m3ps2xu5hc.fsf@pc7.dolda2000.com","subject":"Re: Volume of commits","fromName":"VMiklos","fromEmail":"vmiklos@frugalware.org","sentAt":"2007-07-12T13:29:37Z","receivedAt":"2007-07-12T13:29:37Z","isPatch":false,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"Hello,\n\nNa Thu, Jul 12, 2007 at 03:16:47PM +0200, Fredrik Tolf <fredrik@dolda2000.com> pisal(a):\n> So what I'm wondering is how you people manage to do this? Do you\n> actually always commit changes this way (and, in that case, how do you\n> switch between branches)? Or do you somehow aggregate the smaller\n> commits into larger patches and recommit them? Or is there some third\n> possibility that I'm missing?\n\nyou can cherry-pick the relevan patches to a separate branch and commit\nthen at once (cherry-pick -n), or can merge --squash to archive\nsomething similar\n\n- VMiklos\n"},{"id":"47162","messageId":"20070712134958.GA28310@diana.vm.bytemark.co.uk","threadId":"9002","inReplyTo":"m3ps2xu5hc.fsf@pc7.dolda2000.com","subject":"Re: Volume of commits","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-07-12T13:49:58Z","receivedAt":"2007-07-12T13:49:58Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-07-12 15:16:47 +0200, Fredrik Tolf wrote:\n\n> When I develop for myself, I usually commit incrementally quite a\n> bit, if for no other reason because Git won't let me switch between\n> branches if I don't commit first.\n\nYou can switch branches even if you have local modifications if you\nuse the -m flag to git-checkout.\n\n> I usually try to keep my commits well-defined, but I don't manage to\n> get anywhere close to what I see when I look at the history of Linux\n> or Git.\n>\n> So what I'm wondering is how you people manage to do this? Do you\n> actually always commit changes this way (and, in that case, how do\n> you switch between branches)? Or do you somehow aggregate the\n> smaller commits into larger patches and recommit them? Or is there\n> some third possibility that I'm missing?\n\nWhen it's time to post patches for review on the mailing list, people\nclean up the history so that it'll be easier for the reviewers to read\n(and to make the permanent history easier to read in case the patches\nare accepted). Of course, with practice one can write clean patches to\nbegin with, at least for simpler changes, but the conceptual workflow\nis along the lines of:\n\n  1. Do the changes, and make sure everything works.\n\n  2. Rewrite your changes as a series of easy-to-read and mostly\n     independent patches, and make sure that everything compiles and\n     just generally makes sense at all intermediate steps. The\n     maintainer might very well accept some of your patches but not\n     all!\n\n  3. Repeat until you're satisfied with the result.\n\nThe rationale for spending time making history legible is the same as\nfor making the end result code legible: stuff is written once by one\nperson, and read many times by many people.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"47163","messageId":"Pine.LNX.4.64.0707121451290.4516@racer.site","threadId":"9002","inReplyTo":"20070712132937.GQ19386@genesis.frugalware.org","subject":"Re: Volume of commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-07-12T13:59:53Z","receivedAt":"2007-07-12T13:59:53Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 12 Jul 2007, VMiklos wrote:\n\n> Na Thu, Jul 12, 2007 at 03:16:47PM +0200, Fredrik Tolf <fredrik@dolda2000.com> pisal(a):\n> > So what I'm wondering is how you people manage to do this? Do you \n> > actually always commit changes this way (and, in that case, how do you \n> > switch between branches)? Or do you somehow aggregate the smaller \n> > commits into larger patches and recommit them? Or is there some third \n> > possibility that I'm missing?\n> \n> you can cherry-pick the relevan patches to a separate branch and commit \n> then at once (cherry-pick -n), or can merge --squash to archive \n> something similar\n\nWhat I do these days is committing early, and often, and then rearrange \nwith \"git rebase -i\".  Beware: this is a 1.5.3 feature!  But IMHO it is \nreally something you can look forward to.\n\nA little diagram hopefully explains what you can do with it:\n\n- upstream\n \\\n   A - B - C - D - E - F - G - HEAD with a messy history\n\nIn this case, \"messy history\" means that there are tiny patches which are \noften in the wrong order, or should be squashed into one commit.  \"git \nrebase -i upstream\" presents you with the list of A - HEAD, and you can \nreorder the patches.  If you want to, you can combine (\"squash\") some \ninto one commit, or you can skip it, by removing the corresponding line.\n\nThe result can look like this:\n\n- upstream\n \\\n   B+C+F - A - G+E\n\nNote that D is missing, which can be desirable, for example when you made \na commit only introducing lots and lots of debug output.  See, nobody has \nto know what you did.  The end result will look elegant.\n\nThis demonstration of why distributed SCM is good (\"it lowers the \nembarrasment factor\") was brought to you by Git.\n \nCiao,\nDscho\n"},{"id":"47164","messageId":"20070712140304.GB28310@diana.vm.bytemark.co.uk","threadId":"9002","inReplyTo":"m3ps2xu5hc.fsf@pc7.dolda2000.com","subject":"Re: Volume of commits","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-07-12T14:03:04Z","receivedAt":"2007-07-12T14:03:04Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-07-12 15:16:47 +0200, Fredrik Tolf wrote:\n\n> Or do you somehow aggregate the smaller commits into larger patches\n> and recommit them? Or is there some third possibility that I'm\n> missing?\n\nAggregating commits and recommitting is easy, so that's a common tool,\nI'd say. But it's equally possible to take a large commit and pick it\napart, for example by editing the patch by hand and reapplying it, or\nby using the hunk selection feature of git-gui.\n\nFor example, if you have just committed several changes as one big\ncommit, you can do\n\n  $ git reset HEAD^\n\nto undo the commit but retain the changes in your working tree, and\nthen use git-gui to select a subset of the changes and commit them,\nthen select another subset and commit that, and so on.\n\nIf you need to edit a commit that isn't HEAD, you can use git-reset to\ngo back to the commit you want to edit, do the editing, and then use\ngit-rebase to reapply the other commits on top of the changed commit.\n\nIn general, there are a thousand ways to use git to rewrite history,\neither \"by hand\" or by using tools such as StGIT. (StGIT is what I\npersonally use most of the time. I find it a good tool for producing\nreadable patch series.)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"47166","messageId":"m3ir8pu133.fsf@pc7.dolda2000.com","threadId":"9002","inReplyTo":"20070712140304.GB28310@diana.vm.bytemark.co.uk","subject":"Re: Volume of commits","fromName":"Fredrik Tolf","fromEmail":"fredrik@dolda2000.com","sentAt":"2007-07-12T14:51:44Z","receivedAt":"2007-07-12T14:51:44Z","isPatch":false,"sender":{"key":"fredrik@dolda2000.com","avatar":null},"body":"Karl Hasselström <kha@treskal.com> writes:\n\n> On 2007-07-12 15:16:47 +0200, Fredrik Tolf wrote:\n>\n>> Or do you somehow aggregate the smaller commits into larger patches\n>> and recommit them? Or is there some third possibility that I'm\n>> missing?\n>\n> Aggregating commits and recommitting is easy, so that's a common tool,\n> I'd say. But it's equally possible to take a large commit and pick it\n> apart, for example by editing the patch by hand and reapplying it, or\n> by using the hunk selection feature of git-gui.\n\nI see. Initially, it sounds like a lot of work, but the more I think\nabout it, the more I realize that it probably isn't that bad.\n\n> [...]\n> If you need to edit a commit that isn't HEAD, you can use git-reset to\n> go back to the commit you want to edit, do the editing, and then use\n> git-rebase to reapply the other commits on top of the changed commit.\n\ngit-rebase is one of those tools I haven't been looking at so far (I'm\nstill rather new to Git), so I should probably read through its\nmanpage.\n\n> In general, there are a thousand ways to use git to rewrite history,\n> either \"by hand\" or by using tools such as StGIT. (StGIT is what I\n> personally use most of the time. I find it a good tool for producing\n> readable patch series.)\n\nI hadn't heard of StGIT, but it looks interesting.\n\nThanks for all the suggestions! I'll be needing some time to look them\nthrough. :)\n\nFredrik Tolf\n"},{"id":"47173","messageId":"20070712160906.GP23840@always.joy.eth.net","threadId":"9002","inReplyTo":"m3ir8pu133.fsf@pc7.dolda2000.com","subject":"Re: Volume of commits","fromName":"Joshua N Pritikin","fromEmail":"jpritikin@pobox.com","sentAt":"2007-07-12T16:09:06Z","receivedAt":"2007-07-12T16:09:06Z","isPatch":false,"sender":{"key":"jpritikin@pobox.com","avatar":"https://gravatar.com/avatar/3f2561fdd7efac4e127dc65ac7e06f044069c115dcc94d0ac540f4126d47759d?d=mp&s=160"},"body":"On Thu, Jul 12, 2007 at 04:51:44PM +0200, Fredrik Tolf wrote:\n> git-rebase is one of those tools I haven't been looking at so far (I'm\n> still rather new to Git), so I should probably read through its\n> manpage.\n\nI was in your shoes but I recently learned rebase. If you want to edit a \ncommit then find the SHA-1 in git log. Then assuming you are on master:\n\n1. git checkout -b tmp SHA-1\n2. git commit --amend\n3. git checkout master\n4. git rebase --onto tmp SHA-1\n\nBoth times, use the same SHA-1.\n"},{"id":"47172","messageId":"20070712162147.GA31743@diana.vm.bytemark.co.uk","threadId":"9002","inReplyTo":"m3ir8pu133.fsf@pc7.dolda2000.com","subject":"Re: Volume of commits","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-07-12T16:21:47Z","receivedAt":"2007-07-12T16:21:47Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-07-12 16:51:44 +0200, Fredrik Tolf wrote:\n\n> I see. Initially, it sounds like a lot of work, but the more I think\n> about it, the more I realize that it probably isn't that bad.\n\nYou're right that it isn't that much work, but it still is work. The\npoint is that just like investing time in making code nice and\nreadable, investing time in making the history nice and readable is a\nnet win. Others can follow what you do, which makes reviewing the\nchanges much cheaper, and you can look back six months and actually\nunderstand what you were thinking back then.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"47177","messageId":"alpine.LFD.0.999.0707120933120.20061@woody.linux-foundation.org","threadId":"9002","inReplyTo":"m3ps2xu5hc.fsf@pc7.dolda2000.com","subject":"Re: Volume of commits","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-12T16:46:40Z","receivedAt":"2007-07-12T16:46:40Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 12 Jul 2007, Fredrik Tolf wrote:\n> \n> I was wondering -- whenever I see Git patches committed to projects\n> like the Linux kernel or Git itself, the commits always seems to be\n> committing rather large changes and be rather well-defined in terms of\n> what they change.\n\nWell, people already talked about how to do it using git, but I'd like to \npoint out that one of the reasons you see this kind of pattern is that \nwhen you push patches around by email for commentary (which is what both \ngit and the kernel do a _lot_), that very much inherently encourages a \nsetup where each patch makes sense on its own, and I think it causes \n*much* better code cleanliness behaviour.\n\nWhen people make changes that they know will be shown as patches, they \njust tend to make more sure that the changes make logical sense. Part of \nit is cleanups after-the-fact, but part of it is that when you get used to \ndoing it, after a while you start _thinking_ in those terms when you make \nthe changes, and that's also a good thing!\n\nWhen I do any bigger changes, I usually tend to commit at points where it \nstarts working, but then before I actually would send it to Junio, I'd go \nback and clean up the series (by creating a new branch, and \ncherry-picking, and doing diffs between the branch and applying the parts \nI want to).\n\nBut I do that only for stuff where I can't see the end result as a clean \nseries of steps from the beginning. If I know exactly what I'm doing, I'll \njust do it the clean way from the get-go, and I don't need to clean up the \nseries after-the-fact.\n\n(Most of the time I actually try to get it right the first time. It's \nactually become a challenge to me to notice when some change needs a \ncleanup first in order to make the later changes much easier, so I really \n*like* trying to actually do the actual development in a logical order: \nfirst re-organize the code, and verify that the re-organized code works \nidentically to the old one, then commit that, then start actually working \non the new feature with the now cleaner code-base).\n\nAnd no, I didn't start out programming that way. But when you get used to \nlooking at changes as a nice series of independent commits in emails, you \nreally start _working_ that way yourself. And I'm 100% convinced that it \nactually makes you a better programmer too.\n\n> When I develop for myself, I usually commit incrementally quite a\n> bit, if for no other reason because Git won't let me switch between\n> branches if I don't commit first. I usually try to keep my commits\n> well-defined, but I don't manage to get anywhere close to what I see\n> when I look at the history of Linux or Git.\n\nThe stuff you see in git or the kernel has mostly been discussed as \nemails, or at least been sent out that way (and if it didn't cause any \ndiscussion, it was probably \"obviously clean and correct\"). And that whole \nflow really *does* end up causing people to write cleaner patches.\n\nIt's absolutely worth emulating it, but in some respect, if it's just your \nown project, I suspect you'll just never have the incentive to have your \nhistory be quite as clean as the kernel/git development itself has.\n\n\t\tLinus\n"},{"id":"47223","messageId":"f76hm5$fde$1@sea.gmane.org","threadId":"9002","inReplyTo":"m3ps2xu5hc.fsf@pc7.dolda2000.com","subject":"Re: Volume of commits","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-07-13T00:40:41Z","receivedAt":"2007-07-13T00:40:41Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Fredrik Tolf wrote:\n\n\n> When I develop for myself, I usually commit incrementally quite a\n> bit, if for no other reason because Git won't let me switch between\n> branches if I don't commit first. I usually try to keep my commits\n> well-defined, but I don't manage to get anywhere close to what I see\n> when I look at the history of Linux or Git.\n\nFirst, if you commit only to switch branches you can always instead\nof adding commit on top of whis WIP commit, just --amend it.\n\nSecond, there is git-stash just created for saving state to go back\nto it.\n\nThird, I guess that the neat patch series are result of reworking\nexisting series using tools like StGIT (which I use and find very\nnice to work with, going and correcting back and forth between patches\nin series), or guilt (similar to StGIT), or git-gui, or new interactive mode\nof git-rebase, or git-cherry-pick...\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"47253","messageId":"20070713103025.GR1528MdfPADPa@greensroom.kotnet.org","threadId":"9002","inReplyTo":"Pine.LNX.4.64.0707121451290.4516@racer.site","subject":"Re: Volume of commits","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-07-13T10:30:25Z","receivedAt":"2007-07-13T10:30:25Z","isPatch":false,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Thu, Jul 12, 2007 at 02:59:53PM +0100, Johannes Schindelin wrote:\n> In this case, \"messy history\" means that there are tiny patches which are \n> often in the wrong order, or should be squashed into one commit.  \"git \n> rebase -i upstream\" presents you with the list of A - HEAD, and you can \n> reorder the patches.  If you want to, you can combine (\"squash\") some \n> into one commit, or you can skip it, by removing the corresponding line.\n\nIf I squash a whole series of commits, how do I prevent git-rebase -i\nfrom firing up an editor after every single commit in the series?\n\nAlso, if I do the following:\n\nbash-3.00$ git init\nInitialized empty Git repository in .git/\nbash-3.00$ for i in a b c; do touch $i; git add $i; git commit -m $i -a; done\nCreated initial commit 19a8485: a\n 0 files changed, 0 insertions(+), 0 deletions(-)\n create mode 100644 a\nCreated commit 4a00f85: b\n 0 files changed, 0 insertions(+), 0 deletions(-)\n create mode 100644 b\nCreated commit defe3b5: c\n 0 files changed, 0 insertions(+), 0 deletions(-)\n create mode 100644 c\nbash-3.00$ git rebase -i  HEAD~2\n\nand then replace the second \"pick\" by \"squash\", then I get presented\na commit message that contains the commit message of \"c\" twice and\nafter the rebase there are still three commits in the history.\nThis is with git version 1.5.3.rc1.10.gae1ae\n(on top of v1.5.3-rc1-4-gaf83bed).\n\nskimo\n"},{"id":"47259","messageId":"81b0412b0707130546j5ee34fach1b0db1549f039e25@mail.gmail.com","threadId":"9002","inReplyTo":"20070713103025.GR1528MdfPADPa@greensroom.kotnet.org","subject":"Re: Volume of commits","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-07-13T12:46:32Z","receivedAt":"2007-07-13T12:46:32Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 7/13/07, Sven Verdoolaege <skimo@kotnet.org> wrote:\n> If I squash a whole series of commits, how do I prevent git-rebase -i\n> from firing up an editor after every single commit in the series?\n\nIt is started only for squashed commits. But you can set VISUAL to true or \":\".\n\n> a commit message that contains the commit message of \"c\" twice and\n> after the rebase there are still three commits in the history.\n\nKnown, fixed (but not yet approved) in\n[PATCH] Fix git-rebase -i to allow squashing of fast-forwardable commits\n"},{"id":"48045","messageId":"Pine.LNX.4.64.0707211807430.14781@racer.site","threadId":"9002","inReplyTo":"20070713103025.GR1528MdfPADPa@greensroom.kotnet.org","subject":"[PATCH] rebase -i: call editor just once for a multi-squash","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-07-21T17:09:41Z","receivedAt":"2007-07-21T17:09:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nSometimes you want to squash more than two commits.  Before this patch,\nthe editor was fired up for each squash command.  Now the editor is\nstarted only with the last squash command.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tOn Fri, 13 Jul 2007, Sven Verdoolaege wrote:\n\n\t> If I squash a whole series of commits, how do I prevent \n\t> git-rebase -i from firing up an editor after every single commit \n\t> in the series?\n\n\tBy applying this patch ;-)\n\n git-rebase--interactive.sh    |   56 +++++++++++++++++++++++++++++++++-------\n t/t3404-rebase-interactive.sh |    9 ++++++\n 2 files changed, 55 insertions(+), 10 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex a2d4d09..579a45e 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -19,6 +19,8 @@ require_work_tree\n DOTEST=\"$GIT_DIR/.dotest-merge\"\n TODO=\"$DOTEST\"/todo\n DONE=\"$DOTEST\"/done\n+MSG=\"$DOTEST\"/message\n+SQUASH_MSG=\"$DOTEST\"/message-squash\n REWRITTEN=\"$DOTEST\"/rewritten\n PRESERVE_MERGES=\n STRATEGY=\n@@ -158,6 +160,38 @@ pick_one_preserving_merges () {\n \tesac\n }\n \n+nth_string () {\n+\tcase \"$1\" in\n+\t*1[0-9]|*[04-9]) echo \"$1\"th;;\n+\t*1) echo \"$1\"st;;\n+\t*2) echo \"$1\"nd;;\n+\t*3) echo \"$1\"rd;;\n+\tesac\n+}\n+\n+make_squash_message () {\n+\tif [ -f \"$SQUASH_MSG\" ]; then\n+\t\tCOUNT=$(($(sed -n \"s/^# This is [^0-9]*\\([0-9]\\+\\).*/\\1/p\" \\\n+\t\t\t< \"$SQUASH_MSG\" | tail -n 1)+1))\n+\t\techo \"# This is a combination of $COUNT commits.\"\n+\t\tsed -n \"2,\\$p\" < \"$SQUASH_MSG\"\n+\telse\n+\t\tCOUNT=2\n+\t\techo \"# This is a combination of two 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\techo\n+\tfi\n+\techo \"# This is the $(nth_string $COUNT) commit message:\"\n+\techo\n+\tgit cat-file commit $1 | sed -e '1,/^$/d'\n+}\n+\n+peek_next_command () {\n+\tsed -n \"1s/ .*$//p\" < \"$TODO\"\n+}\n+\n do_next () {\n \ttest -f \"$DOTEST\"/message && rm \"$DOTEST\"/message\n \ttest -f \"$DOTEST\"/author-script && rm \"$DOTEST\"/author-script\n@@ -194,17 +228,19 @@ do_next () {\n \t\t\tdie \"Cannot 'squash' without a previous commit\"\n \n \t\tmark_action_done\n-\t\tMSG=\"$DOTEST\"/message\n-\t\techo \"# This is a combination of two commits.\" > \"$MSG\"\n-\t\techo \"# The first commit's message is:\" >> \"$MSG\"\n-\t\techo >> \"$MSG\"\n-\t\tgit cat-file commit HEAD | sed -e '1,/^$/d' >> \"$MSG\"\n-\t\techo >> \"$MSG\"\n+\t\tmake_squash_message $sha1 > \"$MSG\"\n+\t\tcase \"$(peek_next_command)\" in\n+\t\tsquash)\n+\t\t\tEDIT_COMMIT=\n+\t\t\tcp \"$MSG\" \"$SQUASH_MSG\"\n+\t\t;;\n+\t\t*)\n+\t\t\tEDIT_COMMIT=-e\n+\t\t\ttest -f \"$SQUASH_MSG\" && rm \"$SQUASH_MSG\"\n+\t\tesac\n+\n \t\tfailed=f\n \t\tpick_one -n $sha1 || failed=t\n-\t\techo \"# And this is the 2nd commit message:\" >> \"$MSG\"\n-\t\techo >> \"$MSG\"\n-\t\tgit cat-file commit $sha1 | sed -e '1,/^$/d' >> \"$MSG\"\n \t\tgit reset --soft HEAD^\n \t\tauthor_script=$(get_author_ident_from_commit $sha1)\n \t\techo \"$author_script\" > \"$DOTEST\"/author-script\n@@ -213,7 +249,7 @@ do_next () {\n \t\t\t# This is like --amend, but with a different message\n \t\t\teval \"$author_script\"\n \t\t\texport GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE\n-\t\t\tgit commit -F \"$MSG\" -e\n+\t\t\tgit commit -F \"$MSG\" $EDIT_COMMIT\n \t\t\t;;\n \t\tt)\n \t\t\tcp \"$MSG\" \"$GIT_DIR\"/MERGE_MSG\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 43a6675..8206436 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -65,6 +65,7 @@ cat > fake-editor.sh << EOF\n #!/bin/sh\n test \"\\$1\" = .git/COMMIT_EDITMSG && {\n \ttest -z \"\\$FAKE_COMMIT_MESSAGE\" || echo \"\\$FAKE_COMMIT_MESSAGE\" > \"\\$1\"\n+\ttest -z \"\\$FAKE_COMMIT_AMEND\" || echo \"\\$FAKE_COMMIT_AMEND\" >> \"\\$1\"\n \texit\n }\n test -z \"\\$FAKE_LINES\" && exit\n@@ -212,4 +213,12 @@ test_expect_success 'verbose flag is heeded, even after --continue' '\n \tgrep \"^ file1 |    2 +-$\" output\n '\n \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\tgit rebase -i $base &&\n+\ttest $base = $(git rev-parse HEAD^) &&\n+\ttest 1 = $(git show | grep ONCE | wc -l)\n+'\n+\n test_done\n-- \n1.5.3.rc1.16.g9d6f-dirty\n"},{"id":"48046","messageId":"Pine.LNX.4.64.0707211811280.14781@racer.site","threadId":"9002","inReplyTo":"20070713103025.GR1528MdfPADPa@greensroom.kotnet.org","subject":"Re: Volume of commits","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-07-21T17:12:03Z","receivedAt":"2007-07-21T17:12:03Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 13 Jul 2007, Sven Verdoolaege wrote:\n\n> [...] if I do the following:\n> \n> bash-3.00$ git init\n> Initialized empty Git repository in .git/\n> bash-3.00$ for i in a b c; do touch $i; git add $i; git commit -m $i -a; done\n> Created initial commit 19a8485: a\n>  0 files changed, 0 insertions(+), 0 deletions(-)\n>  create mode 100644 a\n> Created commit 4a00f85: b\n>  0 files changed, 0 insertions(+), 0 deletions(-)\n>  create mode 100644 b\n> Created commit defe3b5: c\n>  0 files changed, 0 insertions(+), 0 deletions(-)\n>  create mode 100644 c\n> bash-3.00$ git rebase -i  HEAD~2\n> \n> and then replace the second \"pick\" by \"squash\", then I get presented\n> a commit message that contains the commit message of \"c\" twice and\n> after the rebase there are still three commits in the history.\n> This is with git version 1.5.3.rc1.10.gae1ae\n> (on top of v1.5.3-rc1-4-gaf83bed).\n\nIt no longer reproduces, which probably means that I inadvertently fixed \nthe bug ;-)\n\nCiao,\nDscho\n"}]}