{"thread":{"id":"13277","subject":"Use of tac in git-rebase--interactive","startedAt":"2008-04-27T06:24:18Z","lastAt":"2008-05-06T04:32:02Z","messageCount":30,"participants":["Brian Gernhardt","Jeff King","しらいしななこ","Johannes Sixt","Junio C Hamano","Paolo Bonzini","Andreas Ericsson","Jörg Sommer","Randal L. Schwartz","David Symonds","Johannes Schindelin","Avery Pennarun","Matthieu Moy"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"75265","messageId":"8D73338C-4EC3-4078-8A34-51DAC1842C2B@silverinsanity.com","threadId":"13277","inReplyTo":null,"subject":"Use of tac in git-rebase--interactive","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-04-27T06:24:18Z","receivedAt":"2008-04-27T06:24:18Z","isPatch":false,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"Commit d481bcc9: \"Do rebase with preserve merges with advanced TODO  \nlist\" uses the command tac, apparently to reverse the TODO command  \nlist.  (I don't use rebase -i much, if you can't tell.)\n\nThe problem is that tac doesn't exist on my OS X system.  I do appear  \nto have a rev command which does the same thing.  Simply posting a  \npatch that does 472s/tac/rev/ would fix the problem on my system, but  \nthe fact that this is an issue raises the question of the relative  \nportability of the two commands.  I don't think we have a declared  \ndependancy on GNU's coreutils, which is where Debian lists tac as  \ncoming from.\n\n~~ Brian\n"},{"id":"75267","messageId":"20080427064250.GA5455@sigill.intra.peff.net","threadId":"13277","inReplyTo":"8D73338C-4EC3-4078-8A34-51DAC1842C2B@silverinsanity.com","subject":"Re: Use of tac in git-rebase--interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-04-27T06:42:51Z","receivedAt":"2008-04-27T06:42:51Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Apr 27, 2008 at 02:24:18AM -0400, Brian Gernhardt wrote:\n\n> The problem is that tac doesn't exist on my OS X system.  I do appear to \n> have a rev command which does the same thing.  Simply posting a patch that \n> does 472s/tac/rev/ would fix the problem on my system, but the fact that \n> this is an issue raises the question of the relative portability of the \n> two commands.  I don't think we have a declared dependancy on GNU's \n> coreutils, which is where Debian lists tac as coming from.\n\nI know the list will be shocked to hear that Solaris has neither.\n\nAn easy perl replacement is:\n\n  perl -e 'print reverse <>'\n\nwhich should work fine for small-ish input (since it puts the whole\nthing in memory).\n\n-Peff\n"},{"id":"75269","messageId":"739FA851-F7F5-4CF9-B384-25AA7022B0C2@silverinsanity.com","threadId":"13277","inReplyTo":"20080427064250.GA5455@sigill.intra.peff.net","subject":"[PATCH] Use perl instead of tac","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-04-27T06:55:50Z","receivedAt":"2008-04-27T06:55:50Z","isPatch":true,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"Subject: [PATCH] Use perl instead of tac\n\ntac is part of GNU coreutils and not portable.  Use perl's reverse\nfunction instead, since we already require it.\n\nSigned-off-by: Brian Gernhardt <benji@silverinsanity.com>\n---\n\nOn Apr 27, 2008, at 2:42 AM, Jeff King wrote:\n\n> I know the list will be shocked to hear that Solaris has neither.\n\nI am shocked and horrified.  But then again, that's mostly just my  \nreaction to Solaris in general. ;-D\n\n> An easy perl replacement is:\n>\n>  perl -e 'print reverse <>'\n>\n> which should work fine for small-ish input (since it puts the whole\n> thing in memory).\n\nSomething like this?\n\nAnd I'm having problems with t3404.13 now (mark :0 invalid).  And it's  \ntoo late for me to track it down.\n\n  git-rebase--interactive.sh |    2 +-\n  1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 1751b08..303b754 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -469,7 +469,7 @@ create_extended_todo_list () {\n  \ttest -n \"${last_parent:-}\" -a \"${last_parent:-}\" != $SHORTUPSTREAM  \n&& \\\n  \t\techo reset $last_parent\n  \t) | \\\n-\ttac | \\\n+\tperl -e 'print reverse <>' | \\\n  \twhile read cmd args\n  \tdo\n  \t\t: ${commit_mark_list:=} ${last_commit:=000}\n-- \n1.5.5.111.g180d\n"},{"id":"75274","messageId":"200804270733.m3R7XW72012537@mi1.bluebottle.com","threadId":"13277","inReplyTo":"8D73338C-4EC3-4078-8A34-51DAC1842C2B@silverinsanity.com","subject":"Re: Use of tac in git-rebase--interactive","fromName":"しらいしななこ","fromEmail":"nanako3@bluebottle.com","sentAt":"2008-04-27T07:33:25Z","receivedAt":"2008-04-27T07:33:25Z","isPatch":false,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Quoting Brian Gernhardt <benji@silverinsanity.com> writes:\n\n> Commit d481bcc9: \"Do rebase with preserve merges with advanced TODO\n> list\" uses the command tac, apparently to reverse the TODO command\n> list.  (I don't use rebase -i much, if you can't tell.)\n\nThat is very sloppy job on Junio's part.  He usually is very picky about shell portability, and I remember that he earlier rewrote somebody else's commit that originally used tac command.\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n\n----------------------------------------------------------------------\nGet a free email address with REAL anti-spam protection.\nhttp://www.bluebottle.com/tag/1\n"},{"id":"75350","messageId":"48158070.7090007@viscovery.net","threadId":"13277","inReplyTo":"739FA851-F7F5-4CF9-B384-25AA7022B0C2@silverinsanity.com","subject":"[PATCH] rebase--interactive: Replace unportable 'tac' by a sed script.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-04-28T07:44:48Z","receivedAt":"2008-04-28T07:44:48Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Johannes Sixt <johannes.sixt@telecom.at>\n\nSigned-off-by: Johannes Sixt <johannes.sixt@telecom.at>\n---\nBrian Gernhardt schrieb:\n> -    tac | \\\n> +    perl -e 'print reverse <>' | \\\n\nHere's my try, which avoids the perl hammer. ;)\n\nSorry, I can't test this at the moment due to an unrelated breakage\nthat I first have to chase down.\n\n-- Hannes\n\nPS: I picked the sed script from this patch by Simon 'corecode' Schubert:\n\nhttp://article.gmane.org/gmane.comp.version-control.git/37074\n\n git-rebase--interactive.sh |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 1751b08..a9ac332 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -469,7 +469,7 @@ create_extended_todo_list () {\n \ttest -n \"${last_parent:-}\" -a \"${last_parent:-}\" != $SHORTUPSTREAM && \\\n \t\techo reset $last_parent\n \t) | \\\n-\ttac | \\\n+\tsed -ne '1!G;$p;h' | \\\n \twhile read cmd args\n \tdo\n \t\t: ${commit_mark_list:=} ${last_commit:=000}\n-- \n1.5.5.1.930.g66f94.dirty\n"},{"id":"75351","messageId":"7v7ieie6hm.fsf@gitster.siamese.dyndns.org","threadId":"13277","inReplyTo":"48158070.7090007@viscovery.net","subject":"Re: [PATCH] rebase--interactive: Replace unportable 'tac' by a sed script.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-04-28T08:19:49Z","receivedAt":"2008-04-28T08:19:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> From: Johannes Sixt <johannes.sixt@telecom.at>\n>\n> Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>\n> ---\n> Brian Gernhardt schrieb:\n>> -    tac | \\\n>> +    perl -e 'print reverse <>' | \\\n>\n> Here's my try, which avoids the perl hammer. ;)\n> ...\n> -\ttac | \\\n> +\tsed -ne '1!G;$p;h' | \\\n\nThanks for trying, but frankly, I'd prefer the Perl hammer, as any\nadvanced sed scripting tend to be far less portable.\n"},{"id":"75352","messageId":"4815919C.6060001@gnu.org","threadId":"13277","inReplyTo":"7v7ieie6hm.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] rebase--interactive: Replace unportable 'tac' by a sed script.","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2008-04-28T08:58:04Z","receivedAt":"2008-04-28T08:58:04Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"\n>> Here's my try, which avoids the perl hammer. ;)\n>> ...\n>> -\ttac | \\\n>> +\tsed -ne '1!G;$p;h' | \\\n> \n> Thanks for trying, but frankly, I'd prefer the Perl hammer, as any\n> advanced sed scripting tend to be far less portable.\n\nIn fact this script is not portable. :-(  Not so much because of its \n\"advanced-ness\", but because it loads the entire file in memory, and \nthus hits the limit on the buffer length of many seds.\n\nPaolo\n"},{"id":"75353","messageId":"20080428090417.GB16153@sigill.intra.peff.net","threadId":"13277","inReplyTo":"48158070.7090007@viscovery.net","subject":"Re: [PATCH] rebase--interactive: Replace unportable 'tac' by a sed script.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-04-28T09:04:17Z","receivedAt":"2008-04-28T09:04:17Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Apr 28, 2008 at 09:44:48AM +0200, Johannes Sixt wrote:\n\n>> +    perl -e 'print reverse <>' | \\\n> [...]\n> +\tsed -ne '1!G;$p;h' | \\\n\nWow, and people complain about perl being unreadable. ;)\n\n-Peff\n"},{"id":"75355","messageId":"481594B3.4020608@op5.se","threadId":"13277","inReplyTo":"20080428090417.GB16153@sigill.intra.peff.net","subject":"Re: [PATCH] rebase--interactive: Replace unportable 'tac' by a sed script.","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2008-04-28T09:11:15Z","receivedAt":"2008-04-28T09:11:15Z","isPatch":true,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Jeff King wrote:\n> On Mon, Apr 28, 2008 at 09:44:48AM +0200, Johannes Sixt wrote:\n> \n>>> +    perl -e 'print reverse <>' | \\\n>> [...]\n>> +\tsed -ne '1!G;$p;h' | \\\n> \n> Wow, and people complain about perl being unreadable. ;)\n> \n\nWell, the tmtowtdi dogma has its drawbacks. Here's another sed-script\nthat does the exact same thing:\n\n\tsed '1!G;h;$!d'\n\nThat being said, perl borrows most of its regex notation from sed, so\nit's not as if perl is easier. This is just the top-end of the scale\nthat things like \"sed s/foo/bar/\" is at the bottom of ;-)\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"75371","messageId":"slrng1be8l.25r.joerg@alea.gnuu.de","threadId":"13277","inReplyTo":"739FA851-F7F5-4CF9-B384-25AA7022B0C2@silverinsanity.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Jörg Sommer","fromEmail":"joerg@alea.gnuu.de","sentAt":"2008-04-28T11:46:29Z","receivedAt":"2008-04-28T11:46:29Z","isPatch":true,"sender":{"key":"joerg@alea.gnuu.de","avatar":null},"body":"Hi,\n\nBrian Gernhardt <benji@silverinsanity.com> wrote:\n> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\n> index 1751b08..303b754 100755\n> --- a/git-rebase--interactive.sh\n> +++ b/git-rebase--interactive.sh\n> @@ -469,7 +469,7 @@ create_extended_todo_list () {\n>   \ttest -n \"${last_parent:-}\" -a \"${last_parent:-}\" != $SHORTUPSTREAM  \n> && \\\n>   \t\techo reset $last_parent\n>   \t) | \\\n> -\ttac | \\\n> +\tperl -e 'print reverse <>' | \\\n\nWhat about using a shell function and a *big* variable or an intermediate\nfile?\n\ntac()\n{\n\twhile read line\n\tdo\n\t\treversed=\"$line\n$reversed\"\n\tdone\n\techo \"${reversed%\n}\"\n}\n\nBye, Jörg.\n-- \nIch halte ihn zwar für einen Schurken und das was er sagt für\nfalsch – aber ich bin bereit mein Leben dafür einzusetzen, daß\ner seine Meinung sagen kann.\t\t(Voletair)\n"},{"id":"75373","messageId":"86k5iib0g9.fsf@blue.stonehenge.com","threadId":"13277","inReplyTo":"slrng1be8l.25r.joerg@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2008-04-28T12:58:30Z","receivedAt":"2008-04-28T12:58:30Z","isPatch":true,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":">>>>> \"Jörg\" == Jörg Sommer <joerg@alea.gnuu.de> writes:\n\nJörg> What about using a shell function and a *big* variable or an intermediate\nJörg> file?\n\nWhat makes you think that's any more faster or efficient than calling Perl\nat this point?\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nPerl/Unix/security consulting, Technical writing, Comedy, etc. etc.\nSee PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!\n"},{"id":"75374","messageId":"ee77f5c20804280612o3db1fb86nf089e2201f688d2f@mail.gmail.com","threadId":"13277","inReplyTo":"86k5iib0g9.fsf@blue.stonehenge.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"David Symonds","fromEmail":"dsymonds@gmail.com","sentAt":"2008-04-28T13:12:43Z","receivedAt":"2008-04-28T13:12:43Z","isPatch":true,"sender":{"key":"dsymonds@gmail.com","avatar":"https://gravatar.com/avatar/b22f5051cbfc11836e36cf7a690e6cde4e225d835e13295ff98d15c7a9ee3c0f?d=mp&s=160"},"body":"On Mon, Apr 28, 2008 at 10:58 PM, Randal L. Schwartz\n<merlyn@stonehenge.com> wrote:\n> >>>>> \"Jörg\" == Jörg Sommer <joerg@alea.gnuu.de> writes:\n>\n>  Jörg> What about using a shell function and a *big* variable or an intermediate\n>  Jörg> file?\n>\n>  What makes you think that's any more faster or efficient than calling Perl\n>  at this point?\n\nI doubt Jörg suggested it for its speed, but it removes the dependency on Perl.\n\nBit ugly, still.\n\n\nDave.\n"},{"id":"75375","messageId":"4815D1A1.8020407@gnu.org","threadId":"13277","inReplyTo":"ee77f5c20804280612o3db1fb86nf089e2201f688d2f@mail.gmail.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2008-04-28T13:31:13Z","receivedAt":"2008-04-28T13:31:13Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"David Symonds wrote:\n> On Mon, Apr 28, 2008 at 10:58 PM, Randal L. Schwartz\n> <merlyn@stonehenge.com> wrote:\n>>>>>>> \"Jörg\" == Jörg Sommer <joerg@alea.gnuu.de> writes:\n>>  Jörg> What about using a shell function and a *big* variable or an intermediate\n>>  Jörg> file?\n>>\n>>  What makes you think that's any more faster or efficient than calling Perl\n>>  at this point?\n> \n> I doubt Jörg suggested it for its speed, but it removes the dependency on Perl.\n> \n> Bit ugly, still.\n\nAnd quadratic, unlike Perl (and unlike sed, if it worked portably).\n\nPaolo\n"},{"id":"75377","messageId":"alpine.DEB.1.00.0804281444320.5399@eeepc-johanness","threadId":"13277","inReplyTo":"slrng1be8l.25r.joerg@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-04-28T13:46:31Z","receivedAt":"2008-04-28T13:46:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 28 Apr 2008, Jörg Sommer wrote:\n\n> Brian Gernhardt <benji@silverinsanity.com> wrote:\n> > diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\n> > index 1751b08..303b754 100755\n> > --- a/git-rebase--interactive.sh\n> > +++ b/git-rebase--interactive.sh\n> > @@ -469,7 +469,7 @@ create_extended_todo_list () {\n> >   \ttest -n \"${last_parent:-}\" -a \"${last_parent:-}\" != $SHORTUPSTREAM  \n> > && \\\n> >   \t\techo reset $last_parent\n> >   \t) | \\\n> > -\ttac | \\\n> > +\tperl -e 'print reverse <>' | \\\n> \n> What about using a shell function and a *big* variable or an \n> intermediate file?\n\nHow about fixing the code to not need tac instead?  We went to great \nlengths to introduce the --reverse option to the rev-list command, in \norder to avoid tac in the original version of rebase -i.\n\nCiao,\nDscho\n"},{"id":"75378","messageId":"E58664C1-86E5-452A-A7CD-2007DD59A75E@silverinsanity.com","threadId":"13277","inReplyTo":"alpine.DEB.1.00.0804281444320.5399@eeepc-johanness","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-04-28T14:07:49Z","receivedAt":"2008-04-28T14:07:49Z","isPatch":true,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn Apr 28, 2008, at 9:46 AM, Johannes Schindelin wrote:\n\n> How about fixing the code to not need tac instead?  We went to great\n> lengths to introduce the --reverse option to the rev-list command, in\n> order to avoid tac in the original version of rebase -i.\n\nBecause this is reversing the output of a sub-shell (ll.395-471), not  \nrev-list.  And making the shell code insert commands before the lines  \nthe produce it would make the code complex at best.  (And it's not  \nsimple code either.)\n\nOr at least that's why I didn't do it.  Someone who understands it  \nbetter can feel free to make it work in reverse in the first place.\n\n~~ Brian\n"},{"id":"75379","messageId":"F205FBFD-99B1-45F5-9596-3FE8384A9268@silverinsanity.com","threadId":"13277","inReplyTo":"ee77f5c20804280612o3db1fb86nf089e2201f688d2f@mail.gmail.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-04-28T14:11:13Z","receivedAt":"2008-04-28T14:11:13Z","isPatch":true,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn Apr 28, 2008, at 9:12 AM, David Symonds wrote:\n\n> I doubt Jörg suggested it for its speed, but it removes the  \n> dependency on Perl.\n\nWe already depend on perl for git-add--interactive.perl in core git,  \nand for git-svn, git-cvs*, and git-send-email.  I don't think this one  \nline is going to make a big difference in our Perl dependency.\n\n~~ Brian"},{"id":"75380","messageId":"alpine.DEB.1.00.0804281520220.5399@eeepc-johanness","threadId":"13277","inReplyTo":"E58664C1-86E5-452A-A7CD-2007DD59A75E@silverinsanity.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-04-28T14:20:58Z","receivedAt":"2008-04-28T14:20:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 28 Apr 2008, Brian Gernhardt wrote:\n\n> On Apr 28, 2008, at 9:46 AM, Johannes Schindelin wrote:\n> \n> >How about fixing the code to not need tac instead?  We went to great \n> >lengths to introduce the --reverse option to the rev-list command, in \n> >order to avoid tac in the original version of rebase -i.\n> \n> Because this is reversing the output of a sub-shell (ll.395-471), not \n> rev-list.  And making the shell code insert commands before the lines \n> the produce it would make the code complex at best.  (And it's not \n> simple code either.)\n\nThat's my _point_: the code is way too complex for what it tries to \naccomplish, namely implement a sane syntax for rebase -i -p.\n\nCiao,\nDscho\n"},{"id":"75381","messageId":"alpine.DEB.1.00.0804281521140.5399@eeepc-johanness","threadId":"13277","inReplyTo":"F205FBFD-99B1-45F5-9596-3FE8384A9268@silverinsanity.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-04-28T14:22:52Z","receivedAt":"2008-04-28T14:22:52Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 28 Apr 2008, Brian Gernhardt wrote:\n\n> On Apr 28, 2008, at 9:12 AM, David Symonds wrote:\n> \n> >I doubt Jörg suggested it for its speed, but it removes the dependency \n> >on Perl.\n> \n> We already depend on perl for git-add--interactive.perl in core git, and \n> for git-svn, git-cvs*, and git-send-email.  I don't think this one line \n> is going to make a big difference in our Perl dependency.\n\nIt does.  It goes the wrong way.  And work on building in \ngit-add--interactive.perl has already begun, so that is not a strong \nargument.\n\nAs for git-svn and git-cvs* I agree, they will probably remain perl \nscripts.  But I think that they are not that important, since they are not \nstrictly _core_ parts of Git, being importers/exporters that not everybody \nneeds.\n\nCiao,\nDscho\n"},{"id":"75405","messageId":"slrng1bqhb.25r.joerg@alea.gnuu.de","threadId":"13277","inReplyTo":"86k5iib0g9.fsf@blue.stonehenge.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Jörg Sommer","fromEmail":"joerg@alea.gnuu.de","sentAt":"2008-04-28T15:15:55Z","receivedAt":"2008-04-28T15:15:55Z","isPatch":true,"sender":{"key":"joerg@alea.gnuu.de","avatar":null},"body":"Hallo Randal,\n\nRandal L. Schwartz <merlyn@stonehenge.com> wrote:\n>>>>>> \"Jörg\" == Jörg Sommer <joerg@alea.gnuu.de> writes:\n>\n> Jörg> What about using a shell function and a *big* variable or an intermediate\n> Jörg> file?\n>\n> What makes you think that's any more faster or efficient than calling Perl\n> at this point?\n\nNothing. My intention was not the speed, but the dependency on Perl. But\nyour are right. Except from the point that my suggestion is broken, it's\n*much* slower:\n\n% time dash -c 'while IFS= read -r line; do rev=\"$line\n$rev\"; done; printf \"%s\" \"$rev\"' < gitk-git/gitk-wish DN\ndash -c  < gitk-git/gitk-wish > /dev/null 2> /dev/null  17,89s user 2,68s system 96% cpu 21,352 total\n\n% time tac < gitk-git/gitk-wish DN\ntac < gitk-git/gitk-wish > /dev/null 2> /dev/null  0,01s user 0,01s system 91% cpu 0,017 total\n\n% time perl -e 'print reverse <>' < gitk-git/gitk-wish DN\nperl -e 'print reverse <>' < gitk-git/gitk-wish > /dev/null 2> /dev/null  0,07s user 0,01s system 59% cpu 0,141 total\n\nBut I doubt this hurts, because we don't have such a big input.\n\n% wc -l git.c\n390 git.c\n\n% time dash -c 'while IFS= read -r line; do rev=\"$line\n$rev\"; done; printf \"%s\" \"$rev\"' < git.c DN\ndash -c  < git.c > /dev/null 2> /dev/null  0,04s user 0,04s system 62% cpu 0,115 total\n\nAnd what about something like this: 'tac || rev || perl …'\n\nBye, Jörg.\n-- \nWas der Bauer nicht kennt, das frisst er nicht. Würde der Städter kennen,\nwas er frisst, er würde umgehend Bauer werden.\n                                                       Oliver Hassencamp\n"},{"id":"75410","messageId":"32541b130804281026n31dae2a3w30cd9c98a9a88e0a@mail.gmail.com","threadId":"13277","inReplyTo":"slrng1bqhb.25r.joerg@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2008-04-28T17:26:19Z","receivedAt":"2008-04-28T17:26:19Z","isPatch":true,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On 4/28/08, Jörg Sommer <joerg@alea.gnuu.de> wrote:\n>  And what about something like this: 'tac || rev || perl …'\n\nOr we could just add a git-tac.c and use that :)\n\nHave fun,\n\nAvery\n"},{"id":"75411","messageId":"vpqej8pnaru.fsf@bauges.imag.fr","threadId":"13277","inReplyTo":"slrng1bqhb.25r.joerg@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2008-04-28T17:34:45Z","receivedAt":"2008-04-28T17:34:45Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"Jörg Sommer <joerg@alea.gnuu.de> writes:\n\n> And what about something like this: 'tac || rev || perl …'\n\nBe careful: rev and tac are different. tac reverses lines, while rev\nreverses chars inside lines.\n\nMy 2 cents,\n\n-- \nMatthieu\n"},{"id":"75414","messageId":"6F09BF8D-BD4B-4A33-951C-7707A270803B@silverinsanity.com","threadId":"13277","inReplyTo":"vpqej8pnaru.fsf@bauges.imag.fr","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-04-28T17:50:56Z","receivedAt":"2008-04-28T17:50:56Z","isPatch":true,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn Apr 28, 2008, at 1:34 PM, Matthieu Moy wrote:\n\n> Jörg Sommer <joerg@alea.gnuu.de> writes:\n>\n>> And what about something like this: 'tac || rev || perl …'\n>\n> Be careful: rev and tac are different. tac reverses lines, while rev\n> reverses chars inside lines.\n\nIndeed you are correct.  This is a mistake I made in my original  \nemail, which people have been parroting.  My mistake, sorry.\n\n~~ Brian"},{"id":"75433","messageId":"04EB077D-CB35-4253-A9EA-2085890C3639@silverinsanity.com","threadId":"13277","inReplyTo":"slrng1bqhb.25r.joerg@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-04-28T19:13:19Z","receivedAt":"2008-04-28T19:13:19Z","isPatch":true,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn Apr 28, 2008, at 11:15 AM, Jörg Sommer wrote:\n\n> Nothing. My intention was not the speed, but the dependency on Perl.  \n> But\n> your are right. Except from the point that my suggestion is broken,  \n> it's\n> *much* slower:\n\n[snip]\n\n> And what about something like this: 'tac || rev || perl …'\n\nThis would actually be spelled something like:\n\n----- 8< -----\ntac=\"\"\n\ntac < /dev/null > /dev/null 2>&1\nif test $? != 127; then\n    tac=tac\nfi\n\nif test -z \"$tac\"; then\n    perl < /dev/null > /dev/null 2>&1\n    if test $? != 127; then\n       tac=\"perl -e 'print reverse <>'\"\n    fi\nfi\n\nif test -z \"$tac\"; then\n    die \"Couldn't find tac or perl.\"\nfi\n\n(subshell) | $tac | while loop\n----- 8< -----\n\nUgly, no?  Plus it adds a dependency on tac OR doesn't solve the perl  \ndependency.  I personally think using perl is better than this  \napproach.  Even if we're trying to reduce the perl dependency in core,  \nit's there right now so this has zero impact now.  The ideal solution  \nis to re-write the loop so that it doesn't need to be reversed in the  \nfirst place.  We can use perl until that rewrite is done.\n\nThis loop-reverse-loop construct is _extremely_ ugly, and I'm having  \nproblems following it.  None of what this function is doing is  \nimmediately obvious.  It's a good candidate for a comment or two.\n\nLooking over it, we should be able to do this with one loop over the  \nlist of commits, doing this for each of them:\n\nif more than one parent\n   other_parents=all but first, comma separated\n   print merge command (without marks)\nelse\n   print pick command\nfi\n\nif commit is tagged\n   print tag command\nfi\n\nI also dislike the large lists this is carrying around in shell  \nvariables.  If I'm reading it correctly, the tag list could be  \nreplaced by invocations of \"git describe --exact-match\".  The mark  \nlist appears to be unavoidable, but significantly smaller than the tag  \nlist.\n\nNow that I think about it, the generation of marks could be done by a  \nsecond loop over the list.  Notice what commits need to be marked in  \nloop 1, then add the mark commands in loop 2.  Both of these loops  \nwould function in the same direction, removing the need for either tac  \nor perl.\n\n~~ Brian"},{"id":"75616","messageId":"7vod7s429q.fsf@gitster.siamese.dyndns.org","threadId":"13277","inReplyTo":"200804270733.m3R7XW72012537@mi1.bluebottle.com","subject":"Re: Use of tac in git-rebase--interactive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-04-30T00:25:37Z","receivedAt":"2008-04-30T00:25:37Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"しらいしななこ  <nanako3@bluebottle.com> writes:\n\n> Quoting Brian Gernhardt <benji@silverinsanity.com> writes:\n>\n>> Commit d481bcc9: \"Do rebase with preserve merges with advanced TODO\n>> list\" uses the command tac, apparently to reverse the TODO command\n>> list.  (I don't use rebase -i much, if you can't tell.)\n>\n> That is very sloppy job on Junio's part.  He usually is very picky about shell portability, and I remember that he earlier rewrote somebody else's commit that originally used tac command.\n\nHeh, sorry about sloppiness.  I've been swamped lately outside git...\n"},{"id":"75675","messageId":"20080430090206.GA21826@alea.gnuu.de","threadId":"13277","inReplyTo":"04EB077D-CB35-4253-A9EA-2085890C3639@silverinsanity.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Jörg Sommer","fromEmail":"joerg@alea.gnuu.de","sentAt":"2008-04-30T09:02:06Z","receivedAt":"2008-04-30T09:02:06Z","isPatch":true,"sender":{"key":"joerg@alea.gnuu.de","avatar":null},"body":"Hi Brian,\n\nBrian Gernhardt schrieb am Mon 28. Apr, 15:13 (-0400):\n> This loop-reverse-loop construct is _extremely_ ugly, and I'm having  \n> problems following it.  None of what this function is doing is  \n> immediately obvious.  It's a good candidate for a comment or two.\n\nI write one.\n\n> I also dislike the large lists this is carrying around in shell  \n> variables.  If I'm reading it correctly, the tag list could be replaced \n> by invocations of \"git describe --exact-match\".\n\nYes. How to get all tags of a commit?\n\n% git tag foo v1.5.5\n% git describe --exact-match 9d831805195ba40b62f632acc6bb6e53d3\nwarning: tag 'v1.5.5' is really 'foo' here\nv1.5.5\n\n> Now that I think about it, the generation of marks could be done by a  \n> second loop over the list.  Notice what commits need to be marked in  \n> loop 1, then add the mark commands in loop 2.  Both of these loops would \n> function in the same direction, removing the need for either tac or perl.\n\nYou are right.\n\nThanks for your comments.\n\nBye, Jörg.\n-- \nDamit das Mögliche entsteht, muß immer wieder das Unmögliche versucht\nwerden.                                       (Hermann Hesse)\n"},{"id":"75674","messageId":"20080430093950.GA16806@alea.gnuu.de","threadId":"13277","inReplyTo":"20080430090206.GA21826@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Jörg Sommer","fromEmail":"joerg@alea.gnuu.de","sentAt":"2008-04-30T09:39:50Z","receivedAt":"2008-04-30T09:39:50Z","isPatch":true,"sender":{"key":"joerg@alea.gnuu.de","avatar":null},"body":"Hallo Brian,\n\nJörg Sommer schrieb am Wed 30. Apr, 11:02 (+0200):\n> Brian Gernhardt schrieb am Mon 28. Apr, 15:13 (-0400):\n> > Now that I think about it, the generation of marks could be done by a  \n> > second loop over the list.  Notice what commits need to be marked in  \n> > loop 1, then add the mark commands in loop 2.  Both of these loops would \n> > function in the same direction, removing the need for either tac or perl.\n> \n> You are right.\n\n… but I found the problem. I don't know how to pass the list from one\nsubshell to the other.\n\n% { echo pick; echo merge; a=12 } | { echo +$a+; while read line; do echo $line; done; }\n++\npick\nmerge\n\nThe only idea I have is a file. Do you have a better idea?\n\n% { echo pick; echo merge; a=12 } >/tmp/tmp; \\\n  { echo +$a+; while read line; do echo $line; done; } < /tmp/tmp\n+12+\npick\nmerge\n\nBye, Jörg.\n-- \nViele Leute glauben, dass sie denken, wenn sie lediglich\nihre Vorurteile neu ordnen.\n"},{"id":"75683","messageId":"5374CF8E-3E6E-480B-A23B-13BE85C7ABCF@silverinsanity.com","threadId":"13277","inReplyTo":"20080430090206.GA21826@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-04-30T15:25:38Z","receivedAt":"2008-04-30T15:25:38Z","isPatch":true,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn Apr 30, 2008, at 5:02 AM, Jörg Sommer wrote:\n\n>> I also dislike the large lists this is carrying around in shell\n>> variables.  If I'm reading it correctly, the tag list could be  \n>> replaced\n>> by invocations of \"git describe --exact-match\".\n>\n> Yes. How to get all tags of a commit?\n>\n> % git tag foo v1.5.5\n> % git describe --exact-match 9d831805195ba40b62f632acc6bb6e53d3\n> warning: tag 'v1.5.5' is really 'foo' here\n> v1.5.5\n\nI wish I could be clever and say I pointed this out as an obviously  \nwrong answer or similar.  But, no, I simply didn't think of that.  The  \nlong list may be required, despite my concerns about it..  :-(\n\nThose concerns being: overrunning the length of a shell variable, the  \nspeed of constructing and searching the list, over-complexity of the  \ncode.  But, of course, if there isn't another way to do it right then  \nthe list stays.\n\n~~ Brian"},{"id":"75686","messageId":"728C10C4-D51E-4FDD-BD15-B99882E10500@silverinsanity.com","threadId":"13277","inReplyTo":"20080430093950.GA16806@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-04-30T16:12:45Z","receivedAt":"2008-04-30T16:12:45Z","isPatch":true,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn Apr 30, 2008, at 5:39 AM, Jörg Sommer wrote:\n\n> … but I found the problem. I don't know how to pass the list from one\n> subshell to the other.\n>\n> % { echo pick; echo merge; a=12 } | { echo +$a+; while read line; do  \n> echo $line; done; }\n> ++\n> pick\n> merge\n>\n> The only idea I have is a file. Do you have a better idea?\n>\n> % { echo pick; echo merge; a=12 } >/tmp/tmp; \\\n>  { echo +$a+; while read line; do echo $line; done; } < /tmp/tmp\n> +12+\n> pick\n> merge\n\nNo, I don't.  But I think the resulting code will be easier to read,  \neven with the file.\n\n~~ Brian"},{"id":"76050","messageId":"20080504221319.GA14584@alea.gnuu.de","threadId":"13277","inReplyTo":"5374CF8E-3E6E-480B-A23B-13BE85C7ABCF@silverinsanity.com","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Jörg Sommer","fromEmail":"joerg@alea.gnuu.de","sentAt":"2008-05-04T22:13:20Z","receivedAt":"2008-05-04T22:13:20Z","isPatch":true,"sender":{"key":"joerg@alea.gnuu.de","avatar":null},"body":"Hallo Brian,\n\nBrian Gernhardt schrieb am Wed 30. Apr, 11:25 (-0400):\n> On Apr 30, 2008, at 5:02 AM, Jörg Sommer wrote:\n>\n>>> I also dislike the large lists this is carrying around in shell\n>>> variables.  If I'm reading it correctly, the tag list could be  \n>>> replaced\n>>> by invocations of \"git describe --exact-match\".\n>>\n>> Yes. How to get all tags of a commit?\n>>\n>> % git tag foo v1.5.5\n>> % git describe --exact-match 9d831805195ba40b62f632acc6bb6e53d3\n>> warning: tag 'v1.5.5' is really 'foo' here\n>> v1.5.5\n\nAnd how can I get only tags no annotated tags? We can't recreate\nannotated tags with git rebase.\n\n> Those concerns being: overrunning the length of a shell variable,\n\nAre you shure there is any such bounding? I didn't saw anything about the\nsize of a variables in IEEE 1003.1-2004, but didn't look very carfully.\nAll my shells (bash, dash, zsh) can handle more than 16777217 characters:\n\ndash -c 'a=a; while :; do a=$a$a; echo $a | wc -c; done'\n\nThis would be a new version of create_extended_todo_list() without tac.\nWhat do you think about it? Is it better readable? But there's a bug.\n\ncreate_extended_todo_list () {\n\t# The idea of this function is to\n\t# 1. build a list of tags\n\t# 2. go through the list and\n\t#    * issue a reset command to the parent of the commit, if the last\n\t#      commit was not the parent of the current commit,\n\t#    * issue a pick command for simple commits,\n\t#    * issue for each merge commit a merge command with the hashs of\n\t#      the parent commits,\n\t#    * register each parent of a merge and issue a mark command\n\t#      (without an ID) after the commit for each registered commit and\n\t#    * issue a tag command, if the commit is in the tag list.\n\t# 3. Then go through the created list and\n\t#    * add an ID to each mark command and\n\t#    * replace all occurences of the hash in reset and merge commands\n\t#      by the mark ID\n\ttest -e \"$DOTEST\"/cetl.tmp \\\n\t\t&& die \"Someone else uses our filename cetl.tmp.\" \\\n\t\t\t\"That's not nice\"\n\tif test t = \"${PRESERVE_TAGS:-}\"\n\tthen\n\t\ttag_list=$(git show-ref --abbrev=7 --tags | \\\n\t\t\t(\n\t\t\twhile read sha1 tag\n\t\t\tdo\n\t\t\t\ttag=${tag#refs/tags/}\n\t\t\t\tif test ${last_sha1:-0000} = $sha1\n\t\t\t\tthen\n\t\t\t\t\tsaved_tags=\"$saved_tags:$tag\"\n\t\t\t\telse\n\t\t\t\t\tprintf \"%s\" \"${last_sha1:+ $last_sha1#$saved_tags}\"\n\t\t\t\t\tlast_sha1=$sha1\n\t\t\t\t\tsaved_tags=$tag\n\t\t\t\tfi\n\t\t\tdone\n\t\t\techo \"${last_sha1:+ $last_sha1:$saved_tags}\"\n\t\t\t) )\n\telse\n\t\ttag_list=\n\tfi\n\tmark_these_commits=\n\twhile IFS=_ read commit parents subject\n\tdo\n\t\tfirst_parent=${parents%% *}\n\t\tif test \"${last_commit:-$SHORTUPSTREAM}\" != $first_parent\n\t\tthen\n\t\t\ttest \"$first_parent\" = $SHORTUPSTREAM &&\n\t\t\t\tfirst_parent=$SHORTONTO\n\t\t\techo reset $first_parent\n\t\tfi\n\t\tunset first_parent\n\t\tlast_commit=$commit\n\n\t\tcase \"$parents\" in\n\t\t*' '*)\n\t\t\tnew_parents=\n\t\t\tfor p in $parents\n\t\t\tdo\n\t\t\t\tmark_these_commits=$(insert_value_at_key_into_list \\\n\t\t\t\t\t\"$commit\" \"$p\" \"$mark_these_commits\")\n\t\t\t\tif test \"$p\" = $SHORTUPSTREAM\n\t\t\t\tthen\n\t\t\t\t\tnew_parents=\"$new_parents $SHORTONTO\"\n\t\t\t\telse\n\t\t\t\t\tnew_parents=\"$new_parents $p\"\n\t\t\t\tfi\n\t\t\tdone\n\t\t\tunset p\n\t\t\techo merge $commit ${new_parents# * }\n\t\t\tunset new_parents\n\t\t\t;;\n\t\t*)\n\t\t\techo \"pick $commit $subject\"\n\t\t\t;;\n\t\tesac\n\n\t\tif tmp=$(get_value_from_list $commit \"$tag_list\")\n\t\tthen\n\t\t\tfor t in $(echo $tmp | tr : ' ')\n\t\t\tdo\n\t\t\t\techo tag $t\n\t\t\tdone\n\t\tfi\n\tdone > \"$DOTEST\"/cetl.tmp\n\tunset commit parents subject\n\n\tcommit_mark_list=\n\tnext_mark=0\n\tlast_commit=\n\twhile read cmd args\n\tdo\n\t\tcase \"$cmd\" in\n\t\tpick)\n\t\t\tthis_commit=\"${args%% *}\"\n\t\t\t;;\n\t\treset)\n\t\t\tthis_commit=$args\n\t\t\tif tmp=$(get_value_from_list $args \"$commit_mark_list\")\n\t\t\tthen\n\t\t\t\targs=\":$tmp\"\n\t\t\tfi\n\t\t\t;;\n\t\tmerge)\n\t\t\tnew_args=\n\t\t\tfor i in ${args#* }\n\t\t\tdo\n\t\t\t\tif tmp=$(get_value_from_list $i \\\n\t\t\t\t\t\"$commit_mark_list\")\n\t\t\t\tthen\n\t\t\t\t\tnew_args=\"$new_args :$tmp\"\n\t\t\t\telse\n\t\t\t\t\tnew_args=\"$new_args $i\"\n\t\t\t\tfi\n\t\t\tdone\n\t\t\tthis_commit=\"${args%% *}\"\n\t\t\targs=\"$this_commit ${new_args# }\"\n\t\t\t;;\n\t\tesac\n\n\t\tif tmp=$(get_value_from_list \"$last_commit\" \\\n\t\t\t\"$mark_these_commits\") && \\\n\t\t\ttest \"${this_commit:-$last_commit}\" != $tmp\n\t\tthen\n\t\t\tif tmp=$(get_value_from_list \"$last_commit\" \\\n\t\t\t\t\"$commit_mark_list\")\n\t\t\tthen\n\t\t\t\ttest \"$last_cmd\" = reset -o \"$last_cmd\" = tag \\\n\t\t\t\t\t|| echo mark \":$tmp\"\n\t\t\telse\n\t\t\t\tcommit_mark_list=$(insert_value_at_key_into_list \\\n\t\t\t\t\t$next_mark $last_commit \"$commit_mark_list\")\n\t\t\t\techo mark \":$next_mark\"\n\t\t\t\tnext_mark=$(($next_mark + 1))\n\t\t\tfi\n\t\tfi\n\t\tlast_commit=${this_commit:-$last_commit}\n\t\tunset this_commit\n\n\t\techo \"$cmd $args\"\n\t\tlast_cmd=$cmd\n\tdone < \"$DOTEST\"/cetl.tmp\n\trm \"$DOTEST\"/cetl.tmp\n\tunset last_cmd last_commit next_mark cmd args tmp commit_mark_list \\\n\t\tmark_these_commits\n}\n\nThe problem is the mark command. If you walk from ONTO to HEAD trough the\nlist, you must know for a commit, if it is used _later_. But don't create\na mark if it is used immediately, e.g. pick; merge not pick; mark; merge.\n\nIf you walk from HEAD to ONTO, this is much easier. I delayed the mark\nfor the first head of a merge and checked if the next commit is this\ncommit. This way I keep the todo list clean and don't get something like\nthis for --first-parent:\n\npick abc\npick def\nmark :0\nmerge 012 foreign-branch\n\nBye, Jörg.\n-- \nEs ist außerdem ein weit verbreiteter Irrtum das USENET ‚helfen‘ soll.\nTatsächlich wurde USENET nachweislich zur persönlichen Belustigung\nseiner Erfinder geschaffen.\nJörg Klemenz <joerg@gmx.net>, <b4ai4o$1u8vmt$2@ID-21915.news.dfncis.de>\n"},{"id":"76171","messageId":"638987EF-5822-4CC6-A895-5650A3237603@silverinsanity.com","threadId":"13277","inReplyTo":"20080504221319.GA14584@alea.gnuu.de","subject":"Re: [PATCH] Use perl instead of tac","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2008-05-06T04:32:02Z","receivedAt":"2008-05-06T04:32:02Z","isPatch":true,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn May 4, 2008, at 6:13 PM, Jörg Sommer wrote:\n\n> Hallo Brian,\n>\n> Brian Gernhardt schrieb am Wed 30. Apr, 11:25 (-0400):\n>> On Apr 30, 2008, at 5:02 AM, Jörg Sommer wrote:\n>>> Yes. How to get all tags of a commit?\n>>>\n>>> % git tag foo v1.5.5\n>>> % git describe --exact-match 9d831805195ba40b62f632acc6bb6e53d3\n>>> warning: tag 'v1.5.5' is really 'foo' here\n>>> v1.5.5\n>\n> And how can I get only tags no annotated tags? We can't recreate\n> annotated tags with git rebase.\n\nYes, the tag list has to stay.  I had missed several bits of what it  \nwas trying to do.\n\n>> Those concerns being: overrunning the length of a shell variable,\n>\n> Are you shure there is any such bounding? I didn't saw anything  \n> about the\n> size of a variables in IEEE 1003.1-2004, but didn't look very  \n> carfully.\n> All my shells (bash, dash, zsh) can handle more than 16777217  \n> characters:\n>\n> dash -c 'a=a; while :; do a=$a$a; echo $a | wc -c; done'\n\nMy concern is that some shell somewhere (like the ever problematic  \nSolaris) would have a limit and it would silently fail.  It may be an  \nunfounded concern, but I thought I'd mention it to the list and see if  \nanyone agreed.\n\n> This would be a new version of create_extended_todo_list() without  \n> tac.\n> What do you think about it? Is it better readable? But there's a bug.\n\nI find it more readable and am pleased about the lack of perl and tac.\n\n> create_extended_todo_list () {\n> \t# The idea of this function is to\n> \t# 1. build a list of tags\n> \t# 2. go through the list and\n> \t#    * issue a reset command to the parent of the commit, if the last\n> \t#      commit was not the parent of the current commit,\n> \t#    * issue a pick command for simple commits,\n> \t#    * issue for each merge commit a merge command with the hashs of\n> \t#      the parent commits,\n> \t#    * register each parent of a merge and issue a mark command\n> \t#      (without an ID) after the commit for each registered commit  \n> and\n> \t#    * issue a tag command, if the commit is in the tag list.\n> \t# 3. Then go through the created list and\n> \t#    * add an ID to each mark command and\n> \t#    * replace all occurences of the hash in reset and merge commands\n> \t#      by the mark ID\n\nComment is excellent, although I'd prefer that the three parts were  \nsimply next to the code they're referring to.\n\n> \ttest -e \"$DOTEST\"/cetl.tmp \\\n> \t\t&& die \"Someone else uses our filename cetl.tmp.\" \\\n> \t\t\t\"That's not nice\"\n\nIs this just to catch a bug where another part of rebase -i uses the  \nsame file?  Or is there a way this could be triggered by user  \nactions?  (I am under the impression that we'd never get this far if  \n$DOTEST already existed.)\n\n> \tmark_these_commits=\n> \twhile IFS=_ read commit parents subject\n> \tdo\n> \t\tfirst_parent=${parents%% *}\n> \t\tif test \"${last_commit:-$SHORTUPSTREAM}\" != $first_parent\n> \t\tthen\n> \t\t\ttest \"$first_parent\" = $SHORTUPSTREAM &&\n> \t\t\t\tfirst_parent=$SHORTONTO\n> \t\t\techo reset $first_parent\n> \t\tfi\n> \t\tunset first_parent\n> \t\tlast_commit=$commit\n>\n> \t\tcase \"$parents\" in\n> \t\t*' '*)\n> \t\t\tnew_parents=\n> \t\t\tfor p in $parents\n> \t\t\tdo\n\nTo avoid unneeded marks, you need one more variable and an if  \nstatement.  Instead of unconditionally marking every parent, keep  \ntrack of the previous commit and add a line like this:\n\n                                if test \"$p\" != \"$prev_commit\"\n                                then\n> \t\t\t\tmark_these_commits=$(insert_value_at_key_into_list \\\n> \t\t\t\t\t\"$commit\" \"$p\" \"$mark_these_commits\")\n                                fi\n>\n> \t\t\t\tif test \"$p\" = $SHORTUPSTREAM\n> \t\t\t\tthen\n> \t\t\t\t\tnew_parents=\"$new_parents $SHORTONTO\"\n> \t\t\t\telse\n> \t\t\t\t\tnew_parents=\"$new_parents $p\"\n> \t\t\t\tfi\n> \t\t\tdone\n> \t\t\tunset p\n> \t\t\techo merge $commit ${new_parents# * }\n> \t\t\tunset new_parents\n> \t\t\t;;\n> \t\t*)\n> \t\t\techo \"pick $commit $subject\"\n> \t\t\t;;\n> \t\tesac\n>\n> \t\tif tmp=$(get_value_from_list $commit \"$tag_list\")\n> \t\tthen\n> \t\t\tfor t in $(echo $tmp | tr : ' ')\n> \t\t\tdo\n> \t\t\t\techo tag $t\n> \t\t\tdone\n> \t\tfi\n>\n> \tdone > \"$DOTEST\"/cetl.tmp\n> \tunset commit parents subject\n>\n> \tcommit_mark_list=\n> \tnext_mark=0\n> \tlast_commit=\n> \twhile read cmd args\n\nI'd personally do \"cat cetl.tmp | while\" instead of \"while .... done <  \ncetl.tmp\", just so that where we're reading from is obvious from the  \nstart.\n\n> The problem is the mark command. If you walk from ONTO to HEAD  \n> trough the\n> list, you must know for a commit, if it is used _later_. But don't  \n> create\n> a mark if it is used immediately, e.g. pick; merge not pick; mark;  \n> merge.\n>\n> If you walk from HEAD to ONTO, this is much easier. I delayed the mark\n> for the first head of a merge and checked if the next commit is this\n> commit. This way I keep the todo list clean and don't get something  \n> like\n> this for --first-parent:\n>\n> pick abc\n> pick def\n> mark :0\n> merge 012 foreign-branch\n\n(See above.)\n\n~~ Brian"}]}