{"thread":{"id":"24903","subject":"RFC: Adding an option to log-like commands to call an external command for each revision","startedAt":"2010-08-29T20:30:15Z","lastAt":"2010-09-12T22:44:41Z","messageCount":9,"participants":["Ævar Arnfjörð Bjarmason","Jonathan Nieder","Jeff King","Mark Lodato","Artur Skawina","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"149234","messageId":"AANLkTikh-KoWuPYE12pVszwduGTBOssKDxqk=4iF6QZT@mail.gmail.com","threadId":"24903","inReplyTo":null,"subject":"RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-29T20:30:15Z","receivedAt":"2010-08-29T20:30:15Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"I have this alias in my .gitconfig:\n\n    review = \"!f() { for rev in $(git rev-list --reverse \\\"$@\\\"); do\ngit show $rev; done; }; f\"\n\nI use it after I \"git pull\" to see what changed, e.g.:\n\n    git review 49ea7b8..e1ef3c1\n\nBut sometimes I find that I want to do that for other things too, so I\nhave these hacks:\n\n    review-grep = \"!f() { for rev in $(git log --reverse\n--pretty=format:%H --grep=\\\"$@\\\"); do git show $rev; done; }; f\"\n    review-file = \"!f() { for rev in $(git log --reverse\n--pretty=format:%H \\\"$@\\\"); do git show $rev; done; }; f\"\n\nBut just now I wanted to use -S instead of grep, but adding aliases\nlike this is a bit silly.\n\nMaybe we should have something like:\n\n    git log --for-each=less a..b\n\nTo call \"less\" for each commit, what do you think?\n"},{"id":"149235","messageId":"20100829203905.GA1890@burratino","threadId":"24903","inReplyTo":"AANLkTikh-KoWuPYE12pVszwduGTBOssKDxqk=4iF6QZT@mail.gmail.com","subject":"Re: RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-29T20:39:05Z","receivedAt":"2010-08-29T20:39:05Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi Ævar,\n\nÆvar Arnfjörð Bjarmason wrote:\n\n> I have this alias in my .gitconfig:\n> \n>     review = \"!f() { for rev in $(git rev-list --reverse \\\"$@\\\"); do\n> git show $rev; done; }; f\"\n> \n> I use it after I \"git pull\" to see what changed, e.g.:\n> \n>     git review 49ea7b8..e1ef3c1\n\nHmm,\n\n git show --reverse 49ea7b8..e1ef3c1\n\ndoesn't work because cmd_show() bypasses the get_revision() magic. :(\n"},{"id":"149276","messageId":"20100830030819.GA25415@sigill.intra.peff.net","threadId":"24903","inReplyTo":"AANLkTikh-KoWuPYE12pVszwduGTBOssKDxqk=4iF6QZT@mail.gmail.com","subject":"Re: RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-08-30T03:08:19Z","receivedAt":"2010-08-30T03:08:19Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Aug 29, 2010 at 08:30:15PM +0000, Ævar Arnfjörð Bjarmason wrote:\n\n> I have this alias in my .gitconfig:\n> \n>     review = \"!f() { for rev in $(git rev-list --reverse \\\"$@\\\"); do\n> git show $rev; done; }; f\"\n> \n> I use it after I \"git pull\" to see what changed, e.g.:\n> \n>     git review 49ea7b8..e1ef3c1\n\nIt took me a minute of reading this to see why you would want to call\n\"git show\" in a loop when you could have the same data from \"git log\"\nall at once (and much faster, too). But I guess you like having an\nindividual less invocation for each commit. Have you tried \"tig\", which\nmight suit your purpose even better?\n\n> But sometimes I find that I want to do that for other things too, so I\n> have these hacks:\n> \n>     review-grep = \"!f() { for rev in $(git log --reverse\n> --pretty=format:%H --grep=\\\"$@\\\"); do git show $rev; done; }; f\"\n>     review-file = \"!f() { for rev in $(git log --reverse\n> --pretty=format:%H \\\"$@\\\"); do git show $rev; done; }; f\"\n> \n> But just now I wanted to use -S instead of grep, but adding aliases\n> like this is a bit silly.\n\nI don't understand why you have these at all. Just use \"git log\n--format=%H\" in your git review above (instead of rev-list), and then\nyou can just do:\n\n  git review --grep=whatever\n  git review -Sfoo\n  git review file\n\nOr am I missing something subtle?\n\nYou wouldn't even need to switch to log over rev-list, except that\nrev-list misses log's useful \"default to HEAD if no revisions given\"\nbehavior.\n\n> Maybe we should have something like:\n> \n>     git log --for-each=less a..b\n> \n> To call \"less\" for each commit, what do you think?\n\nI think it is not very Unix-y. We already have many ways to to call a\ncommand once per commit, including:\n\n  - for i in `git rev-list \"$@\"`; do git show $i; done\n\n  - git rev-list \"$@\" | xargs -n 1 git show\n\n  - git log -z \"$@\" | perl -0ne 'open(LESS, \"|less\"); print LESS'\n\nWhat does your solution offer that the other do not? Because you are\nactually reinvoking git for each commit, it is more efficient than the\nfirst two (as you seem to assume that the --for-each command will\nreceive the entire log output). But the third one should be more or less\nequivalent to what you want (though note: if you want tty-ish things\nlike color on, you should set GIT_PAGER_IN_USE=1 so git knows output is\neventually going to a pager). Sure, yours is slightly less typing, but\nit's _way_ less flexible, and that typing should probably be hidden\nbehind an alias anyway.\n\n-Peff\n"},{"id":"150498","messageId":"AANLkTi=WokEQMDc92SoWXPJW67dy0q79WW9RajrBHRx3@mail.gmail.com","threadId":"24903","inReplyTo":"20100830030819.GA25415@sigill.intra.peff.net","subject":"Re: RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-09-11T15:56:13Z","receivedAt":"2010-09-11T15:56:13Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"`On Mon, Aug 30, 2010 at 03:08, Jeff King <peff@peff.net> wrote:\n\nSorry for not replying to this earlier.\n\n> On Sun, Aug 29, 2010 at 08:30:15PM +0000, Ævar Arnfjörð Bjarmason wrote:\n>\n>> I have this alias in my .gitconfig:\n>>\n>>     review = \"!f() { for rev in $(git rev-list --reverse \\\"$@\\\"); do\n>> git show $rev; done; }; f\"\n>>\n>> I use it after I \"git pull\" to see what changed, e.g.:\n>>\n>>     git review 49ea7b8..e1ef3c1\n>\n> It took me a minute of reading this to see why you would want to call\n> \"git show\" in a loop when you could have the same data from \"git log\"\n> all at once (and much faster, too).\n\nI just like the UI of having each commit \"pop up\" where I can either\npage up/down within the commit, or dismiss it with \"q\" and go to the\nnext one.\n\nYou can't do both of those in a pager, up/down goes across commits,\nand \"q\" quits the whole pager.\n\n> But I guess you like having an individual less invocation for each\n> commit. Have you tried \"tig\", which might suit your purpose even\n> better?\n\nI haven't tried tig, but \"git review\" as I implement it (below) is\nsufficient for my needs.\n\n>> But sometimes I find that I want to do that for other things too, so I\n>> have these hacks:\n>>\n>>     review-grep = \"!f() { for rev in $(git log --reverse\n>> --pretty=format:%H --grep=\\\"$@\\\"); do git show $rev; done; }; f\"\n>>     review-file = \"!f() { for rev in $(git log --reverse\n>> --pretty=format:%H \\\"$@\\\"); do git show $rev; done; }; f\"\n>>\n>> But just now I wanted to use -S instead of grep, but adding aliases\n>> like this is a bit silly.\n>\n> I don't understand why you have these at all. Just use \"git log\n> --format=%H\" in your git review above (instead of rev-list), and then\n> you can just do:\n>\n>  git review --grep=whatever\n>  git review -Sfoo\n>  git review file\n>\n> Or am I missing something subtle?\n\nYou're not missing something, my alias was silly because I brainfarted\nand didn't realize I could do $@, not \"$@\", so now it's:\n\n    review = \"!f() { for rev in $(git log --reverse --format=%H $@);\ndo git show $rev; done; }; f\"\n\nWhich means I can do all of the commands you suggested above, thanks!\n\n> You wouldn't even need to switch to log over rev-list, except that\n> rev-list misses log's useful \"default to HEAD if no revisions given\"\n> behavior.\n>\n>> Maybe we should have something like:\n>>\n>>     git log --for-each=less a..b\n>>\n>> To call \"less\" for each commit, what do you think?\n>\n> I think it is not very Unix-y. We already have many ways to to call a\n> command once per commit, including:\n>\n>  - for i in `git rev-list \"$@\"`; do git show $i; done\n>\n>  - git rev-list \"$@\" | xargs -n 1 git show\n>\n>  - git log -z \"$@\" | perl -0ne 'open(LESS, \"|less\"); print LESS'\n>\n> What does your solution offer that the other do not? Because you are\n> actually reinvoking git for each commit, it is more efficient than the\n> first two (as you seem to assume that the --for-each command will\n> receive the entire log output). But the third one should be more or less\n> equivalent to what you want (though note: if you want tty-ish things\n> like color on, you should set GIT_PAGER_IN_USE=1 so git knows output is\n> eventually going to a pager). Sure, yours is slightly less typing, but\n> it's _way_ less flexible, and that typing should probably be hidden\n> behind an alias anyway.\n\nYeah, it's not very Unixy, I just find it so useful that I thought\nthere might be interest in adding it to Git. It's easily in the list\nof top 5 git commands that I use.\n\nBut just using the pipe is more flexible I guess.\n"},{"id":"150502","messageId":"AANLkTikmCA2Cidz1UEDGH5j94_HucvJPGj27g8p_pcEi@mail.gmail.com","threadId":"24903","inReplyTo":"AANLkTi=WokEQMDc92SoWXPJW67dy0q79WW9RajrBHRx3@mail.gmail.com","subject":"Re: RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Mark Lodato","fromEmail":"lodatom@gmail.com","sentAt":"2010-09-11T17:09:04Z","receivedAt":"2010-09-11T17:09:04Z","isPatch":false,"sender":{"key":"lodatom@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58860?v=4"},"body":"On Sat, Sep 11, 2010 at 11:56 AM, Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> `On Mon, Aug 30, 2010 at 03:08, Jeff King <peff@peff.net> wrote:\n>> I think it is not very Unix-y. We already have many ways to to call a\n>> command once per commit, including:\n>>\n>>  - for i in `git rev-list \"$@\"`; do git show $i; done\n>>\n>>  - git rev-list \"$@\" | xargs -n 1 git show\n>>\n>>  - git log -z \"$@\" | perl -0ne 'open(LESS, \"|less\"); print LESS'\n>>\n>> [snip]\n>\n> Yeah, it's not very Unixy, I just find it so useful that I thought\n> there might be interest in adding it to Git. It's easily in the list\n> of top 5 git commands that I use.\n\nI also find myself wanting to walk through commits in a particular\norder.  In my case, I don't want to run a command per commit, but\ninstead I want to check them out a la \"git bisect.\" Let's pretend such\na command is called \"git walk\".  In in my case, I would run:\n\n    git walk start --reverse 49ea7b8..e1ef3c1\n    <compile, test, ...>\n    git walk next\n    <compile, test, ...>\n    git walk next\n    <...>\n    git walk reset\n\nIn Ævar's case, he would just want:\n\n    git walk start --reverse 49ea7b8..e1ef3c\n    git walk run git show\n    git walk reset\n\nOr perhaps a shortcut:\n\n    git walk start --reverse 49ea7b8..e1ef3c --run git show\n\nThere is already a simple implementation by August Lilleaas [1], but\nit would be nice to re-use the git-bisect machinery.\n\nMark\n\n[1] http://github.com/augustl/binbin/blob/master/git-walk\n"},{"id":"150514","messageId":"AANLkTi=p1ScGXAWprSYC6=K_FyNS3m2En-NZLtNU_ES_@mail.gmail.com","threadId":"24903","inReplyTo":"AANLkTi=WokEQMDc92SoWXPJW67dy0q79WW9RajrBHRx3@mail.gmail.com","subject":"Re: RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-09-11T19:07:49Z","receivedAt":"2010-09-11T19:07:49Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Sat, Sep 11, 2010 at 15:56, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n> `On Mon, Aug 30, 2010 at 03:08, Jeff King <peff@peff.net> wrote:\n\n>> I don't understand why you have these at all. Just use \"git log\n>> --format=%H\" in your git review above (instead of rev-list), and then\n>> you can just do:\n>>\n>>  git review --grep=whatever\n>>  git review -Sfoo\n>>  git review file\n>>\n>> Or am I missing something subtle?\n>\n> You're not missing something, my alias was silly because I brainfarted\n> and didn't realize I could do $@, not \"$@\", so now it's:\n>\n>    review = \"!f() { for rev in $(git log --reverse --format=%H $@);\n> do git show $rev; done; }; f\"\n>\n> Which means I can do all of the commands you suggested above, thanks!\n\nHrm, actually in the case of that alias doing:\n\n    git review -M ...\n\nWon't do what I want, because it's `git show` that has to be invoked\nby -M. An option like --for-each-invoke-pager (or something) could do\nthe right thing there.\n"},{"id":"150521","messageId":"4C8BFFEB.5090902@gmail.com","threadId":"24903","inReplyTo":"AANLkTi=WokEQMDc92SoWXPJW67dy0q79WW9RajrBHRx3@mail.gmail.com","subject":"Re: RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Artur Skawina","fromEmail":"art.08.09@gmail.com","sentAt":"2010-09-11T22:17:15Z","receivedAt":"2010-09-11T22:17:15Z","isPatch":false,"sender":{"key":"art.08.09@gmail.com","avatar":null},"body":"On 09/11/10 17:56, Ævar Arnfjörð Bjarmason wrote:\n>>> I have this alias in my .gitconfig:\n>>>\n>>>     review = \"!f() { for rev in $(git rev-list --reverse \\\"$@\\\"); do\n>>> git show $rev; done; }; f\"\n>>>\n>>> I use it after I \"git pull\" to see what changed, e.g.:\n>>>\n>>>     git review 49ea7b8..e1ef3c1\n\n> I just like the UI of having each commit \"pop up\" where I can either\n> page up/down within the commit, or dismiss it with \"q\" and go to the\n> next one.\n\nSomething like\n\n$ LESS=\"$LESS +/^commit \" git whatchanged -p --reverse ORIG_HEAD..\n\nwill let you jump between the commits using 'n' for next, 'N' for\nprevious.\n\nNot 100% the same, i know, but much faster than your solution.\n(mostly because of pipelining; while you're reviewing one change\nthe next commits are already being prepared. For deep, but filtered\nqueries, i often do it more explicitly as \"git..|bag|less +/^commit\"\nto avoid the stalls.)\n\nartur\n"},{"id":"150560","messageId":"7vmxrmd57r.fsf@alter.siamese.dyndns.org","threadId":"24903","inReplyTo":"AANLkTi=WokEQMDc92SoWXPJW67dy0q79WW9RajrBHRx3@mail.gmail.com","subject":"Re: RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-09-12T21:25:44Z","receivedAt":"2010-09-12T21:25:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> I just like the UI of having each commit \"pop up\" where I can either\n> page up/down within the commit, or dismiss it with \"q\" and go to the\n> next one.\n>\n> You can't do both of those in a pager, up/down goes across commits,\n> and \"q\" quits the whole pager.\n\nI would throw this not into the incomplete scriptability category but into\nthe \"user does not know how to use his pager\" category.  With \"/^commit .*\"\nyou can not only advance to the next commit with \"/<RET>\", you can go back\nto the previous one with \"?<RET>\", and keep going in the same direction\nwith \"n\".\n\n>>> Maybe we should have something like:\n>>>\n>>>     git log --for-each=less a..b\n\nIf anything that shouldn't be an option to \"log\", but to \"rev-list\", as\nyou are aiming for scriptability.  But\n\n    git rev-list --for-each='cmd that takes commit as its argument'\n\nwouldn't be much of an improvement over \"git rev-list | xargs -n1 'cmd'\"\npipeline from the _scriptability_ point of view.\n\nSo no.\n"},{"id":"150564","messageId":"AANLkTi=0S=fAosE6Ejp=cJiMuMsi6o-cS023tQTL5MC1@mail.gmail.com","threadId":"24903","inReplyTo":"7vmxrmd57r.fsf@alter.siamese.dyndns.org","subject":"Re: RFC: Adding an option to log-like commands to call an external command for each revision","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-09-12T22:44:41Z","receivedAt":"2010-09-12T22:44:41Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Sun, Sep 12, 2010 at 21:25, Junio C Hamano <gitster@pobox.com> wrote:\n> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>\n>> I just like the UI of having each commit \"pop up\" where I can either\n>> page up/down within the commit, or dismiss it with \"q\" and go to the\n>> next one.\n>>\n>> You can't do both of those in a pager, up/down goes across commits,\n>> and \"q\" quits the whole pager.\n>\n> I would throw this not into the incomplete scriptability category but into\n> the \"user does not know how to use his pager\" category.  With \"/^commit .*\"\n> you can not only advance to the next commit with \"/<RET>\", you can go back\n> to the previous one with \"?<RET>\", and keep going in the same direction\n> with \"n\".\n\nThat was already suggested, but I prefer not to see anything else in\nthe pager myself. E.g. if I have a large terminal window I want to see\n*only* the pertinent commit in that entire window, nothing else.\n\nWhich is why I still use my git-review alias.\n\n> wouldn't be much of an improvement over \"git rev-list | xargs -n1 'cmd'\"\n> pipeline from the _scriptability_ point of view.\n>\n> So no.\n\nFine, I don't think it should be in core either after this\ndiscussion. So we're in agreement.\n\nThe problem I was trying to solve was solved with Jeff's suggestion.\n"}]}