{"thread":{"id":"18032","subject":"[RFH] rebase -i optimization","startedAt":"2009-02-26T14:55:41Z","lastAt":"2009-03-03T11:21:58Z","messageCount":16,"participants":["Sverre Rabbelier","Johannes Schindelin","Sitaram Chamarty","Junio C Hamano","Johannes Sixt"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"106331","messageId":"fabb9a1e0902260655g53fa1e1fg7e4aa76b0f3a80fc@mail.gmail.com","threadId":"18032","inReplyTo":null,"subject":"[RFH] rebase -i optimization","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-02-26T14:55:41Z","receivedAt":"2009-02-26T14:55:41Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nI am currently working on a large set of patches for Melange, and as\nsuch I'm using rebase -i a lot to polish things a bit. I do this\nmainly by 'git rebase -i master' from my topic branch, then change on\nof the 'pick' lines into an 'edit', and then fix up the commit and\n'git rebase --continue'. Now I notice I'm waiting a lot for 'rebase\n-i' to finish picking the first bunch of commits that I didn't change.\nNow obviously I couldof done 'git rebase -i <foo>', but then I have\nfirst figure out what the last commit I want to change is.\nWould there be a reason to not reset to the last 'pick' commit instead\nof to the 'based on' branch (as long as there history is linear)? If\nso, what would be the best way to go around and implement this?\n\n(to's based on who made the most changes to git-rebase--interactive.sh\nand cc-ed those involved with git-sequencer)\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"106332","messageId":"alpine.DEB.1.00.0902261557300.6258@intel-tinevez-2-302","threadId":"18032","inReplyTo":"fabb9a1e0902260655g53fa1e1fg7e4aa76b0f3a80fc@mail.gmail.com","subject":"Re: [RFH] rebase -i optimization","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-02-26T14:59:47Z","receivedAt":"2009-02-26T14:59:47Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 26 Feb 2009, Sverre Rabbelier wrote:\n\n> I am currently working on a large set of patches for Melange, and as\n> such I'm using rebase -i a lot to polish things a bit. I do this\n> mainly by 'git rebase -i master' from my topic branch, then change on\n> of the 'pick' lines into an 'edit', and then fix up the commit and\n> 'git rebase --continue'. Now I notice I'm waiting a lot for 'rebase\n> -i' to finish picking the first bunch of commits that I didn't change.\n> Now obviously I couldof done 'git rebase -i <foo>', but then I have\n> first figure out what the last commit I want to change is.\n> Would there be a reason to not reset to the last 'pick' commit instead\n> of to the 'based on' branch (as long as there history is linear)? If\n> so, what would be the best way to go around and implement this?\n\nThis code is supposed to do exactly what you want:\n\nhttp://repo.or.cz/w/git/dscho.git?a=blob;f=git-rebase--interactive.sh;h=532f161c1ddce351cf623b096899e0eb057180ca;hb=8394eb1ecee00c2aba9212f3445c42078b41614b#l198\n\nUnfortunately, it seems to be quite broken by all the different directions \nrebase -i was pulled to, but maybe you see the bug right away.  Otherwise, \nI'll try to reschedule my Git time budget later tonight.\n\nCiao,\nDscho\n"},{"id":"106338","messageId":"fabb9a1e0902260733k26e5c02i75a7866f9a67530b@mail.gmail.com","threadId":"18032","inReplyTo":"alpine.DEB.1.00.0902261557300.6258@intel-tinevez-2-302","subject":"Re: [RFH] rebase -i optimization","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-02-26T15:33:32Z","receivedAt":"2009-02-26T15:33:32Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Thu, Feb 26, 2009 at 15:59, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> This code is supposed to do exactly what you want:\n\nHmmm, I can't say I understand it 100%, but what I can see from\nreading the code and looking at the output of 'rebase -i -v' is that\nit does a 'git reset --hard' on each commit if it was already applied,\ninstead of figuring out beforehand what to reset to? If that is the\ncase, it might still take a long time to do the rebase if it takes\nlong to do the 'reset --hard' between the patches (say, if a big\nchange is made).\n\n> Unfortunately, it seems to be quite broken by all the different directions\n> rebase -i was pulled to, but maybe you see the bug right away.  Otherwise,\n> I'll try to reschedule my Git time budget later tonight.\n\nAfter reading the code and trying with -v, I don't think the current\ncode is broken, just that it might be optimized to be even faster?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"106387","messageId":"slrngqefbi.g56.sitaramc@sitaramc.homelinux.net","threadId":"18032","inReplyTo":"fabb9a1e0902260655g53fa1e1fg7e4aa76b0f3a80fc@mail.gmail.com","subject":"Re: [RFH] rebase -i optimization","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-27T01:10:10Z","receivedAt":"2009-02-27T01:10:10Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-26, Sverre Rabbelier <srabbelier@gmail.com> wrote:\n\n> I am currently working on a large set of patches for Melange, and as\n> such I'm using rebase -i a lot to polish things a bit. I do this\n> mainly by 'git rebase -i master' from my topic branch, then change on\n> of the 'pick' lines into an 'edit', and then fix up the commit and\n> 'git rebase --continue'. Now I notice I'm waiting a lot for 'rebase\n> -i' to finish picking the first bunch of commits that I didn't change.\n> Now obviously I couldof done 'git rebase -i <foo>', but then I have\n> first figure out what the last commit I want to change is.\n\nyou could, in theory, do it with a custom \"EDITOR\" variable\nthat actually points to a script you write.  This script\nwill invoke the normal editor just as now, but if it finds\nthat the resulting file has pick line(s) before the first\nedit line, it aborts the rebase by sending back an empty\nfile, and print out a suitable rebase command that you just\nclick-and-paste :-)\n\nAny other combination it just sends through as normal (like\nif the first non-pick line was a 'squash', for instance).\n\nYes this is a kludge but it gets your job done with a\nminimum of fuss asap.\n\nRegards,\n\nSitaram\n\nPS: Even more fun...\n\nI tested a script that looks like this:\n\n    #!/bin/bash\n\n    vim \"$@\"\n    # -- parse $1 (which will be # .git/rebase-merge/rebase-todo\n    # really) to pick the correct SHA you need --\n    unset EDITOR\n    git rebase --abort\n    git rebase -i the-SHA-you-picked\n\nWhen it finishes the inner rebase it does protest mildly\n(something about grep not finding that same file), a remnant\nof the outer rebase... but it seems to work fine.\n\nThis removes even the extra step of having the outer rebase\nprint something that you have to then copy/paste :-)\n"},{"id":"106423","messageId":"alpine.DEB.1.00.0902271146460.6600@intel-tinevez-2-302","threadId":"18032","inReplyTo":"fabb9a1e0902260733k26e5c02i75a7866f9a67530b@mail.gmail.com","subject":"Re: [RFH] rebase -i optimization","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-02-27T10:50:44Z","receivedAt":"2009-02-27T10:50:44Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 26 Feb 2009, Sverre Rabbelier wrote:\n\n> On Thu, Feb 26, 2009 at 15:59, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> > This code is supposed to do exactly what you want:\n> \n> Hmmm, I can't say I understand it 100%, but what I can see from\n> reading the code and looking at the output of 'rebase -i -v' is that\n> it does a 'git reset --hard' on each commit if it was already applied,\n> instead of figuring out beforehand what to reset to? If that is the\n> case, it might still take a long time to do the rebase if it takes\n> long to do the 'reset --hard' between the patches (say, if a big\n> change is made).\n\nRight.\n\nI am of two minds here:\n\nOn one hand, I could imagine that it is just a question of skipping those \n'pick' commands that do not contribute anything.  That would be a pretty \nsimple function that would be called at the very beginning.\n\nOn the other hand, this very simple strategy would fail pretty quickly \n(and badly) with -i -p.  And that is the stuff I am mostly spending my Git \ntime budget on these days.\n\nHaving said that, I think yours might be such a common case that it is \nworth optimizing for.\n\nCiao,\nDscho\n"},{"id":"106428","messageId":"fabb9a1e0902270429t5d31aaaet1e8c07e2b42751c3@mail.gmail.com","threadId":"18032","inReplyTo":"alpine.DEB.1.00.0902271146460.6600@intel-tinevez-2-302","subject":"Re: [RFH] rebase -i optimization","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-02-27T12:29:32Z","receivedAt":"2009-02-27T12:29:32Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Feb 27, 2009 at 11:50, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> On one hand, I could imagine that it is just a question of skipping those\n> 'pick' commands that do not contribute anything.  That would be a pretty\n> simple function that would be called at the very beginning.\n\nExactly, that's what I had in mind.\n\n> On the other hand, this very simple strategy would fail pretty quickly\n> (and badly) with -i -p.  And that is the stuff I am mostly spending my Git\n> time budget on these days.\n\nI would be fine with making this optimization optional (with a config\noption?), and barf if both the optimization and -p are supplied. We\ncould even automagically ignore the config option for -p, and only\nbarf if both -p and this option are specified explicitly?\n\n> Having said that, I think yours might be such a common case that it is\n> worth optimizing for.\n\nDoes this fit in your git time budget, or would you prefer I have a\nstab at it? If the latter, any hints on where to put such a call?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"106431","messageId":"alpine.DEB.1.00.0902271354130.6600@intel-tinevez-2-302","threadId":"18032","inReplyTo":"alpine.DEB.1.00.0902271146460.6600@intel-tinevez-2-302","subject":"[PATCH] rebase -i: avoid 'git reset' when possible","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-02-27T12:56:51Z","receivedAt":"2009-02-27T12:56:51Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When picking commits whose parents have not changed, we do not need to\nrewrite the commit.  We do not need to reset the working directory to\nthe parent's state, either.\n\nRequested by Sverre Rabbelier.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tOn Fri, 27 Feb 2009, Johannes Schindelin wrote:\n\n\t> Having said that, I think yours might be such a common case that\n\t> it is worth optimizing for.\n\n\tAnd so I did.\n\n git-rebase--interactive.sh    |   23 +++++++++++++++++++++++\n t/t3404-rebase-interactive.sh |   11 +++++++++++\n 2 files changed, 34 insertions(+), 0 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 3dc659d..a9617a2 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -442,6 +442,27 @@ do_rest () {\n \tdone\n }\n \n+# skip picking commits whose parents are unchanged\n+skip_unnecessary_picks () {\n+\tcurrent=$ONTO\n+\ti=0\n+\twhile read command sha1 rest\n+\tdo\n+\t\ttest pick = \"$command\" &&\n+\t\ttest $current = \"$(git rev-parse $sha1^)\" ||\n+\t\tbreak\n+\t\tcurrent=$(git rev-parse $sha1)\n+\t\ti=$(($i+1))\n+\tdone < \"$TODO\"\n+\ttest $i = 0 || {\n+\t\tsed -e \"${i}q\" < \"$TODO\" >> \"$DONE\" &&\n+\t\tsed -e \"1,${i}d\" < \"$TODO\" >> \"$TODO\".new &&\n+\t\tmv -f \"$TODO\".new \"$TODO\" &&\n+\t\tONTO=$current ||\n+\t\tdie \"Could not skip $i pick commands\"\n+\t}\n+}\n+\n # check if no other options are set\n is_standalone () {\n \ttest $# -eq 2 -a \"$2\" = '--' &&\n@@ -746,6 +767,8 @@ EOF\n \t\thas_action \"$TODO\" ||\n \t\t\tdie_abort \"Nothing to do\"\n \n+\t\ttest -d \"$REWRITTEN\" || skip_unnecessary_picks\n+\n \t\tgit update-ref ORIG_HEAD $HEAD\n \t\toutput git checkout $ONTO && do_rest\n \t\t;;\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 603b003..c32ff66 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -459,4 +459,15 @@ test_expect_success 'submodule rebase -i' '\n \tFAKE_LINES=\"1 squash 2 3\" git rebase -i A\n '\n \n+test_expect_success 'avoid unnecessary reset' '\n+\tgit checkout master &&\n+\ttest-chmtime =123456789 file3 &&\n+\tgit update-index --refresh &&\n+\tHEAD=$(git rev-parse HEAD) &&\n+\tgit rebase -i HEAD~4 &&\n+\ttest $HEAD = $(git rev-parse HEAD) &&\n+\tMTIME=$(test-chmtime -v +0 file3 | sed 's/[^0-9].*$//') &&\n+\ttest 123456789 = $MTIME\n+'\n+\n test_done\n-- \n1.6.2.rc1.350.g6caf6\n"},{"id":"106432","messageId":"fabb9a1e0902270503p4b769a48xaef5978f0f05797@mail.gmail.com","threadId":"18032","inReplyTo":"alpine.DEB.1.00.0902271354130.6600@intel-tinevez-2-302","subject":"Re: [PATCH] rebase -i: avoid 'git reset' when possible","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-02-27T13:03:21Z","receivedAt":"2009-02-27T13:03:21Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Feb 27, 2009 at 13:56, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> When picking commits whose parents have not changed, we do not need to\n> rewrite the commit.  We do not need to reset the working directory to\n> the parent's state, either.\n\nAwesome, I will give this a spin when I get home.\n\n>> Having said that, I think yours might be such a common case that\n>> it is worth optimizing for.\n>\n> And so I did.\n\nVery nice, I don't think I couldof done it anywhere near as fast ;).\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"106433","messageId":"alpine.DEB.1.00.0902271433100.6600@intel-tinevez-2-302","threadId":"18032","inReplyTo":"fabb9a1e0902270503p4b769a48xaef5978f0f05797@mail.gmail.com","subject":"Re: [PATCH] rebase -i: avoid 'git reset' when possible","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-02-27T13:33:52Z","receivedAt":"2009-02-27T13:33:52Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 27 Feb 2009, Sverre Rabbelier wrote:\n\n> On Fri, Feb 27, 2009 at 13:56, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> \n> >> Having said that, I think yours might be such a common case that it \n> >> is worth optimizing for.\n> >\n> > And so I did.\n> \n> Very nice, I don't think I couldof done it anywhere near as fast ;).\n\nHeh, the time I save now that I read less mails... :-)  It's more fun, \ntoo.\n\nCiao,\nDscho\n"},{"id":"106590","messageId":"7vvdqt8wob.fsf@gitster.siamese.dyndns.org","threadId":"18032","inReplyTo":"alpine.DEB.1.00.0902271354130.6600@intel-tinevez-2-302","subject":"Re: [PATCH] rebase -i: avoid 'git reset' when possible","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-01T08:38:44Z","receivedAt":"2009-03-01T08:38:44Z","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> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\n> index 3dc659d..a9617a2 100755\n> --- a/git-rebase--interactive.sh\n> +++ b/git-rebase--interactive.sh\n> @@ -442,6 +442,27 @@ do_rest () {\n>  \tdone\n>  }\n>  \n> +# skip picking commits whose parents are unchanged\n> +skip_unnecessary_picks () {\n> +\tcurrent=$ONTO\n> +\ti=0\n> +\twhile read command sha1 rest\n> +\tdo\n> +\t\ttest pick = \"$command\" &&\n> +\t\ttest $current = \"$(git rev-parse $sha1^)\" ||\n> +\t\tbreak\n> +\t\tcurrent=$(git rev-parse $sha1)\n> +\t\ti=$(($i+1))\n> +\tdone < \"$TODO\"\n> +\ttest $i = 0 || {\n> +\t\tsed -e \"${i}q\" < \"$TODO\" >> \"$DONE\" &&\n> +\t\tsed -e \"1,${i}d\" < \"$TODO\" >> \"$TODO\".new &&\n> +\t\tmv -f \"$TODO\".new \"$TODO\" &&\n> +\t\tONTO=$current ||\n> +\t\tdie \"Could not skip $i pick commands\"\n> +\t}\n> +}\n\nI do not think you have to count and then run two sed.\n\n\tthis=$ONTO\n\tskip_pick=t\n\twhile read command sha1 rest\n\tdo\n\t\tsha1=$(git rev-parse \"$sha1\")\n        \tcase \"$skip_pick,$command\" in\n                t,pick | t,p)\n\t\t\tif test \"$this\" = \"$sha1\"\n                        then\n\t\t\t\techo >&3 \"$command $sha1 $rest\"\n                        \tthis=\"$sha1\"\n\t\t\t\tcontinue\n\t\t\tfi\n\t\tesac                        \n\t\tskip_pick=f\n                echo \"$command $sha1 $rest\"\n\tdone <\"$TODO\" >\"$TODO.new\" 3>>\"$DONE\" &&\n\t...\n"},{"id":"106647","messageId":"alpine.DEB.1.00.0903012242180.10279@pacific.mpi-cbg.de","threadId":"18032","inReplyTo":"7vvdqt8wob.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] rebase -i: avoid 'git reset' when possible","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-01T21:57:11Z","receivedAt":"2009-03-01T21:57:11Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 1 Mar 2009, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\n> > index 3dc659d..a9617a2 100755\n> > --- a/git-rebase--interactive.sh\n> > +++ b/git-rebase--interactive.sh\n> > @@ -442,6 +442,27 @@ do_rest () {\n> >  \tdone\n> >  }\n> >  \n> > +# skip picking commits whose parents are unchanged\n> > +skip_unnecessary_picks () {\n> > +\tcurrent=$ONTO\n> > +\ti=0\n> > +\twhile read command sha1 rest\n> > +\tdo\n> > +\t\ttest pick = \"$command\" &&\n> > +\t\ttest $current = \"$(git rev-parse $sha1^)\" ||\n> > +\t\tbreak\n> > +\t\tcurrent=$(git rev-parse $sha1)\n> > +\t\ti=$(($i+1))\n> > +\tdone < \"$TODO\"\n> > +\ttest $i = 0 || {\n> > +\t\tsed -e \"${i}q\" < \"$TODO\" >> \"$DONE\" &&\n> > +\t\tsed -e \"1,${i}d\" < \"$TODO\" >> \"$TODO\".new &&\n> > +\t\tmv -f \"$TODO\".new \"$TODO\" &&\n> > +\t\tONTO=$current ||\n> > +\t\tdie \"Could not skip $i pick commands\"\n> > +\t}\n> > +}\n> \n> I do not think you have to count and then run two sed.\n> \n> \tthis=$ONTO\n> \tskip_pick=t\n> \twhile read command sha1 rest\n> \tdo\n> \t\tsha1=$(git rev-parse \"$sha1\")\n>         \tcase \"$skip_pick,$command\" in\n>                 t,pick | t,p)\n> \t\t\tif test \"$this\" = \"$sha1\"\n>                         then\n> \t\t\t\techo >&3 \"$command $sha1 $rest\"\n>                         \tthis=\"$sha1\"\n> \t\t\t\tcontinue\n> \t\t\tfi\n> \t\tesac                        \n> \t\tskip_pick=f\n>                 echo \"$command $sha1 $rest\"\n> \tdone <\"$TODO\" >\"$TODO.new\" 3>>\"$DONE\" &&\n> \t...\n\nOr even\n\n\tcurrent=$ONTO\n\tfd=3\n\twhile read command sha1 rest\n\tdo\n\t\tcase \"$fd,$command,$current\" in\n\t\t3,pick,\"$sha1\"*|t,p,\"$sha1\"*)\n\t\t\tcurrent=$sha1\n\t\t\t;;\n\t\t*)\n\t\t\tfd=1\n\t\t\t;;\n\t\tesac\n\t\techo \"$command $sha1 $rest\" >&$fd\n\tdone < \"$TODO\" > \"$TODO.new\" 3>> \"$DONE\" &&\n\tmv \"$TODO.new\" \"$TODO\"\n\nHmm?\n\nCiao,\nDscho\n"},{"id":"106749","messageId":"7v1vtfl8xi.fsf@gitster.siamese.dyndns.org","threadId":"18032","inReplyTo":"alpine.DEB.1.00.0903012242180.10279@pacific.mpi-cbg.de","subject":"Re: [PATCH] rebase -i: avoid 'git reset' when possible","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-03T00:57:45Z","receivedAt":"2009-03-03T00:57:45Z","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> Or even\n>\n> \tcurrent=$ONTO\n> \tfd=3\n> \twhile read command sha1 rest\n> \tdo\n> \t\tcase \"$fd,$command,$current\" in\n> \t\t3,pick,\"$sha1\"*|t,p,\"$sha1\"*)\n> \t\t\tcurrent=$sha1\n> \t\t\t;;\n> \t\t*)\n> \t\t\tfd=1\n> \t\t\t;;\n> \t\tesac\n> \t\techo \"$command $sha1 $rest\" >&$fd\n> \tdone < \"$TODO\" > \"$TODO.new\" 3>> \"$DONE\" &&\n> \tmv \"$TODO.new\" \"$TODO\"\n>\n> Hmm?\n\nCertainly.\n\nEven though \"3 means we haven't found a non-pick yet\" feels slightly\nhacky, the logic is contained in this small loop and I do not see it as a\nproblem.  As long as you are sure $ONTO and all sha1 can be compared\nwithout running them through rev-parse, avoiding rev-parse per iteration\nis a very attractive optimization.\n"},{"id":"106805","messageId":"alpine.DEB.1.00.0903031008580.6399@intel-tinevez-2-302","threadId":"18032","inReplyTo":"7v1vtfl8xi.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] rebase -i: avoid 'git reset' when possible","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-03T09:24:05Z","receivedAt":"2009-03-03T09:24:05Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 2 Mar 2009, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > Or even\n> >\n> > \tcurrent=$ONTO\n> > \tfd=3\n> > \twhile read command sha1 rest\n> > \tdo\n> > \t\tcase \"$fd,$command,$current\" in\n> > \t\t3,pick,\"$sha1\"*|t,p,\"$sha1\"*)\n> > \t\t\tcurrent=$sha1\n> > \t\t\t;;\n> > \t\t*)\n> > \t\t\tfd=1\n> > \t\t\t;;\n> > \t\tesac\n> > \t\techo \"$command $sha1 $rest\" >&$fd\n> > \tdone < \"$TODO\" > \"$TODO.new\" 3>> \"$DONE\" &&\n> > \tmv \"$TODO.new\" \"$TODO\"\n> >\n> > Hmm?\n> \n> Certainly.\n> \n> Even though \"3 means we haven't found a non-pick yet\" feels slightly\n> hacky, the logic is contained in this small loop and I do not see it as a\n> problem.\n\nI'll add a one line comment.\n\n> As long as you are sure $ONTO and all sha1 can be compared without \n> running them through rev-parse, avoiding rev-parse per iteration is a \n> very attractive optimization.\n\nYes, that is the beauty of abbreviated commit names: they are guaranteed \nto be unique, unless other objects were added since, which is not the case \nat this point.\n\nCiao,\nDscho\n"},{"id":"106808","messageId":"alpine.DEB.1.00.0903031024420.6399@intel-tinevez-2-302","threadId":"18032","inReplyTo":"alpine.DEB.1.00.0903031008580.6399@intel-tinevez-2-302","subject":"[PATCH v2] rebase -i: avoid 'git reset' when possible","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-03T09:55:31Z","receivedAt":"2009-03-03T09:55:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When picking commits whose parents have not changed, we do not need to\nrewrite the commit.  We do not need to reset the working directory to\nthe parent's state, either.\n\nRequested by Sverre Rabbelier.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tActually, I did not think things through.  Of _course_ we need\n\tthat rev-parse, to determine the parent of the to-be-picked\n\tcommit.\n\n\tChanges since v1: use only one loop instead of counting the number \n\tof skipped commits first, and then actually skipping them.\n\n git-rebase--interactive.sh    |   26 ++++++++++++++++++++++++++\n t/t3404-rebase-interactive.sh |   11 +++++++++++\n 2 files changed, 37 insertions(+), 0 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 3dc659d..72f7fc7 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -442,6 +442,30 @@ do_rest () {\n \tdone\n }\n \n+# skip picking commits whose parents are unchanged\n+skip_unnecessary_picks () {\n+\tfd=3\n+\twhile read command sha1 rest\n+\tdo\n+\t\t# fd=3 means we skip the command\n+\t\tcase \"$fd,$command,$(git rev-parse --verify --quiet $sha1^)\" in\n+\t\t3,pick,\"$ONTO\"*|t,p,\"$ONTO\"*)\n+\t\t\t# pick a commit whose parent is current $ONTO -> skip\n+\t\t\tONTO=$sha1\n+\t\t\t;;\n+\t\t3,#*|3,,*)\n+\t\t\t# copy comments\n+\t\t\t;;\n+\t\t*)\n+\t\t\tfd=1\n+\t\t\t;;\n+\t\tesac\n+\t\techo \"$command${sha1:+ }$sha1${rest:+ }$rest\" >&$fd\n+\tdone < \"$TODO\" > \"$TODO.new\" 3>> \"$DONE\" &&\n+\tmv -f \"$TODO\".new \"$TODO\" ||\n+\tdie \"Could not skip unnecessary pick commands\"\n+}\n+\n # check if no other options are set\n is_standalone () {\n \ttest $# -eq 2 -a \"$2\" = '--' &&\n@@ -746,6 +770,8 @@ EOF\n \t\thas_action \"$TODO\" ||\n \t\t\tdie_abort \"Nothing to do\"\n \n+\t\ttest -d \"$REWRITTEN\" || skip_unnecessary_picks\n+\n \t\tgit update-ref ORIG_HEAD $HEAD\n \t\toutput git checkout $ONTO && do_rest\n \t\t;;\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 603b003..c32ff66 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -459,4 +459,15 @@ test_expect_success 'submodule rebase -i' '\n \tFAKE_LINES=\"1 squash 2 3\" git rebase -i A\n '\n \n+test_expect_success 'avoid unnecessary reset' '\n+\tgit checkout master &&\n+\ttest-chmtime =123456789 file3 &&\n+\tgit update-index --refresh &&\n+\tHEAD=$(git rev-parse HEAD) &&\n+\tgit rebase -i HEAD~4 &&\n+\ttest $HEAD = $(git rev-parse HEAD) &&\n+\tMTIME=$(test-chmtime -v +0 file3 | sed 's/[^0-9].*$//') &&\n+\ttest 123456789 = $MTIME\n+'\n+\n test_done\n-- \n1.6.2.rc1.456.g3dbe7\n"},{"id":"106817","messageId":"49AD1250.4080708@viscovery.net","threadId":"18032","inReplyTo":"alpine.DEB.1.00.0903031024420.6399@intel-tinevez-2-302","subject":"Re: [PATCH v2] rebase -i: avoid 'git reset' when possible","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2009-03-03T11:19:44Z","receivedAt":"2009-03-03T11:19:44Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Johannes Schindelin schrieb:\n> +# skip picking commits whose parents are unchanged\n> +skip_unnecessary_picks () {\n> +\tfd=3\n> +\twhile read command sha1 rest\n> +\tdo\n> +\t\t# fd=3 means we skip the command\n> +\t\tcase \"$fd,$command,$(git rev-parse --verify --quiet $sha1^)\" in\n> +\t\t3,pick,\"$ONTO\"*|t,p,\"$ONTO\"*)\n\ns/t,/3,/\n\n> +\t\t\t# pick a commit whose parent is current $ONTO -> skip\n> +\t\t\tONTO=$sha1\n> +\t\t\t;;\n> +\t\t3,#*|3,,*)\n> +\t\t\t# copy comments\n> +\t\t\t;;\n> +\t\t*)\n> +\t\t\tfd=1\n> +\t\t\t;;\n> +\t\tesac\n> +\t\techo \"$command${sha1:+ }$sha1${rest:+ }$rest\" >&$fd\n> +\tdone < \"$TODO\" > \"$TODO.new\" 3>> \"$DONE\" &&\n> +\tmv -f \"$TODO\".new \"$TODO\" ||\n> +\tdie \"Could not skip unnecessary pick commands\"\n> +}\n\n-- Hannes\n"},{"id":"106819","messageId":"alpine.DEB.1.00.0903031221330.6399@intel-tinevez-2-302","threadId":"18032","inReplyTo":"49AD1250.4080708@viscovery.net","subject":"Re: [PATCH v2] rebase -i: avoid 'git reset' when possible","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-03T11:21:58Z","receivedAt":"2009-03-03T11:21:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 3 Mar 2009, Johannes Sixt wrote:\n\n> Johannes Schindelin schrieb:\n> > +# skip picking commits whose parents are unchanged\n> > +skip_unnecessary_picks () {\n> > +\tfd=3\n> > +\twhile read command sha1 rest\n> > +\tdo\n> > +\t\t# fd=3 means we skip the command\n> > +\t\tcase \"$fd,$command,$(git rev-parse --verify --quiet $sha1^)\" in\n> > +\t\t3,pick,\"$ONTO\"*|t,p,\"$ONTO\"*)\n> \n> s/t,/3,/\n\nBah!  Of course, I had to insert a typo there!\n\nThanks!\nDscho\n"}]}