{"thread":{"id":"23732","subject":"git log -M -- filename is not working?","startedAt":"2010-05-07T18:07:53Z","lastAt":"2010-05-14T05:05:10Z","messageCount":26,"participants":["Eugene Sajine","Jacob Helwig","Eli Barzilay","Matthieu Moy","Jakub Narebski","Jeff King","Junio C Hamano","Bo Yang"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"141135","messageId":"z2w76c5b8581005071107w79d30963g725269febe746f0@mail.gmail.com","threadId":"23732","inReplyTo":null,"subject":"git log -M -- filename is not working?","fromName":"Eugene Sajine","fromEmail":"euguess@gmail.com","sentAt":"2010-05-07T18:07:53Z","receivedAt":"2010-05-07T18:07:53Z","isPatch":false,"sender":{"key":"euguess@gmail.com","avatar":null},"body":"Hi!\n\nI tried it in both git 1.6.5.6 and git 1.7.0.5\n\nThe file has been moved:\n\nFrom\nSrc/folder1/folder2/File.java\n\nTo src/main/java/folder1/folder2/File.java\n\nI don’t think it is relevant but just in case: The author has\ncommitted the new file first, then the commit was amended with the\ndeletion of the source file.\nSo we ended up with the rename correctly detected.\n\nNow\n$ git log –M -- src/main/java/folder1/folder2/File.java\n\nShows only one last commit and doesn’t show the history when the file\nwas in source folder. Same thing happens with\n\n$ git log –C  -- src/main/java/folder1/folder2/File.java\n\nWhat gives?\n\nThanks,\nEugene\n"},{"id":"141136","messageId":"h2m8c9a061005071110nf7e63220ked03598bfa66fbc9@mail.gmail.com","threadId":"23732","inReplyTo":"z2w76c5b8581005071107w79d30963g725269febe746f0@mail.gmail.com","subject":"Re: git log -M -- filename is not working?","fromName":"Jacob Helwig","fromEmail":"jacob.helwig@gmail.com","sentAt":"2010-05-07T18:10:44Z","receivedAt":"2010-05-07T18:10:44Z","isPatch":false,"sender":{"key":"jacob.helwig@gmail.com","avatar":"https://avatars.githubusercontent.com/u/14557?v=4"},"body":"On Fri, May 7, 2010 at 11:07, Eugene Sajine <euguess@gmail.com> wrote:\n> Hi!\n>\n> I tried it in both git 1.6.5.6 and git 1.7.0.5\n>\n> The file has been moved:\n>\n> From\n> Src/folder1/folder2/File.java\n>\n> To src/main/java/folder1/folder2/File.java\n>\n> I don’t think it is relevant but just in case: The author has\n> committed the new file first, then the commit was amended with the\n> deletion of the source file.\n> So we ended up with the rename correctly detected.\n>\n> Now\n> $ git log –M -- src/main/java/folder1/folder2/File.java\n>\n> Shows only one last commit and doesn’t show the history when the file\n> was in source folder. Same thing happens with\n>\n> $ git log –C  -- src/main/java/folder1/folder2/File.java\n>\n> What gives?\n>\n> Thanks,\n> Eugene\n>\n\nYou want the --follow flag, too.\n"},{"id":"141138","messageId":"z2r76c5b8581005071131q15524cb8td6711dbb9142b28e@mail.gmail.com","threadId":"23732","inReplyTo":"h2m8c9a061005071110nf7e63220ked03598bfa66fbc9@mail.gmail.com","subject":"Re: git log -M -- filename is not working?","fromName":"Eugene Sajine","fromEmail":"euguess@gmail.com","sentAt":"2010-05-07T18:31:23Z","receivedAt":"2010-05-07T18:31:23Z","isPatch":false,"sender":{"key":"euguess@gmail.com","avatar":null},"body":"On Fri, May 7, 2010 at 2:10 PM, Jacob Helwig <jacob.helwig@gmail.com> wrote:\n> On Fri, May 7, 2010 at 11:07, Eugene Sajine <euguess@gmail.com> wrote:\n>> Hi!\n>>\n>> I tried it in both git 1.6.5.6 and git 1.7.0.5\n>>\n>> The file has been moved:\n>>\n>> From\n>> Src/folder1/folder2/File.java\n>>\n>> To src/main/java/folder1/folder2/File.java\n>>\n>> I don’t think it is relevant but just in case: The author has\n>> committed the new file first, then the commit was amended with the\n>> deletion of the source file.\n>> So we ended up with the rename correctly detected.\n>>\n>> Now\n>> $ git log –M -- src/main/java/folder1/folder2/File.java\n>>\n>> Shows only one last commit and doesn’t show the history when the file\n>> was in source folder. Same thing happens with\n>>\n>> $ git log –C  -- src/main/java/folder1/folder2/File.java\n>>\n>> What gives?\n>>\n>> Thanks,\n>> Eugene\n>>\n>\n> You want the --follow flag, too.\n>\n\nThanks! I missed this guy. By the way it seems that --follow flag\nworks without -M or -C.\n\nAre those deprecated or I'm missing the difference between three of them??\n\nThanks,\nEugene\n"},{"id":"141139","messageId":"19428.24021.324557.517627@winooski.ccs.neu.edu","threadId":"23732","inReplyTo":"z2r76c5b8581005071131q15524cb8td6711dbb9142b28e@mail.gmail.com","subject":"Re: git log -M -- filename is not working?","fromName":"Eli Barzilay","fromEmail":"eli@barzilay.org","sentAt":"2010-05-07T18:37:09Z","receivedAt":"2010-05-07T18:37:09Z","isPatch":false,"sender":{"key":"eli@barzilay.org","avatar":"https://avatars.githubusercontent.com/u/185905?v=4"},"body":"On May  7, Eugene Sajine wrote:\n> On Fri, May 7, 2010 at 2:10 PM, Jacob Helwig <jacob.helwig@gmail.com> wrote:\n> > You want the --follow flag, too.\n> \n> Thanks! I missed this guy. By the way it seems that --follow flag\n> works without -M or -C.\n> \n> Are those deprecated or I'm missing the difference between three of\n> them??\n\nBTW, I've had at least 4 people now who got confused by this.  Is\nthere any use for -M/-C without --follow?  In any case, it will be\nvery helpful if the -M/-C descriptions said \"see also --follow\".\n\nAlso, is there a way to set this as the default for `git log'?\n\n-- \n          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:\n                    http://barzilay.org/                   Maze is Life!\n"},{"id":"141176","messageId":"vpqfx23wjb4.fsf@bauges.imag.fr","threadId":"23732","inReplyTo":"19428.24021.324557.517627@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2010-05-07T20:25:35Z","receivedAt":"2010-05-07T20:25:35Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Eli Barzilay <eli@barzilay.org> writes:\n\n> On May  7, Eugene Sajine wrote:\n>> On Fri, May 7, 2010 at 2:10 PM, Jacob Helwig <jacob.helwig@gmail.com> wrote:\n>> > You want the --follow flag, too.\n>> \n>> Thanks! I missed this guy. By the way it seems that --follow flag\n>> works without -M or -C.\n>> \n>> Are those deprecated or I'm missing the difference between three of\n>> them??\n>\n> BTW, I've had at least 4 people now who got confused by this.  Is\n> there any use for -M/-C without --follow?  In any case, it will be\n> very helpful if the -M/-C descriptions said \"see also --follow\".\n>\n> Also, is there a way to set this as the default for `git log'?\n\nI guess -M and -C are here because log accepts all options that diff\naccepts, in case you run \"git log -p\". Then, -M and -C control what\ndiff is displayed to the user.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"141177","messageId":"m3ocgre9ul.fsf@localhost.localdomain","threadId":"23732","inReplyTo":"19428.24021.324557.517627@winooski.ccs.neu.edu","subject":"Re: git log -M -- filename is not working?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-07T20:28:07Z","receivedAt":"2010-05-07T20:28:07Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Eli Barzilay <eli@barzilay.org> writes:\n\n> On May  7, Eugene Sajine wrote:\n> > On Fri, May 7, 2010 at 2:10 PM, Jacob Helwig <jacob.helwig@gmail.com> wrote:\n> > > You want the --follow flag, too.\n> > \n> > Thanks! I missed this guy. By the way it seems that --follow flag\n> > works without -M or -C.\n> > \n> > Are those deprecated or I'm missing the difference between three of\n> > them??\n> \n> BTW, I've had at least 4 people now who got confused by this.  Is\n> there any use for -M/-C without --follow?  In any case, it will be\n> very helpful if the -M/-C descriptions said \"see also --follow\".\n\nYes, '-M/-C' is useful with \"git diff\" _without_ pathspec, including\ne.g. \"git show -C\".\n\nThe problem with \"git log -M -- <filename>\" is that history simplification,\nwhich is required for good performance, happens before diff mechanism has a\nchance to perform rename detection.  Before there was '--follow' option to\ngit-log (which supports only the case of single file, and doesn't work that\nwell with more complicated history), you were forced to do\n\n  $ git log -M -- <filename> <oldname> <oldername>...\n\n> \n> Also, is there a way to set this as the default for `git log'?\n\nI don't think so.  Note also that '--follow' works only with single file,\nand does not work for example (currently) with directory pathspec.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"141223","messageId":"20100508044434.GC14998@coredump.intra.peff.net","threadId":"23732","inReplyTo":"19428.24021.324557.517627@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-08T04:44:34Z","receivedAt":"2010-05-08T04:44:34Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, May 07, 2010 at 02:37:09PM -0400, Eli Barzilay wrote:\n\n> BTW, I've had at least 4 people now who got confused by this.  Is\n> there any use for -M/-C without --follow?  In any case, it will be\n> very helpful if the -M/-C descriptions said \"see also --follow\".\n\nYes, it detects renames when doing diffs.\n\nDocumentation patch is below.\n\n> Also, is there a way to set this as the default for `git log'?\n\nIf you mean --follow, then no. Nor would you probably want to, because\nthe --follow mechanism (as currently implemented) is pretty restricted.\nIt can only take a single path currently.\n\n-- >8 --\nSubject: [PATCH] docs: clarify meaning of -M for git-log\n\nAs an option to the \"diff\" family, it is fairly obvious what\n\"detect renames\" means. However, for revision traversal, the\n\"-M\" option is just included in the long list of options,\nwith no indication that it is about showing renames in diffs\nversus following renames. Let's make it more explicit.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nThe only other revision traversal manpage that includes diff-options\nseems to be format-patch. Should it get the same treatment?\n\n Documentation/diff-options.txt |    7 +++++++\n 1 files changed, 7 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\nindex c9c6c2b..3070ddd 100644\n--- a/Documentation/diff-options.txt\n+++ b/Documentation/diff-options.txt\n@@ -177,7 +177,14 @@ endif::git-format-patch[]\n \tBreak complete rewrite changes into pairs of delete and create.\n \n -M::\n+ifndef::git-log[]\n \tDetect renames.\n+endif::git-log[]\n+ifdef::git-log[]\n+\tIf generating diffs, detect and report renames for each commit.\n+\tFor following files across renames while traversing history, see\n+\t`--follow`.\n+endif::git-log[]\n \n -C::\n \tDetect copies as well as renames.  See also `--find-copies-harder`.\n-- \n1.7.1.176.gcff095.dirty\n"},{"id":"141226","messageId":"19428.62170.654092.308682@winooski.ccs.neu.edu","threadId":"23732","inReplyTo":"20100508044434.GC14998@coredump.intra.peff.net","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Eli Barzilay","fromEmail":"eli@barzilay.org","sentAt":"2010-05-08T05:12:58Z","receivedAt":"2010-05-08T05:12:58Z","isPatch":false,"sender":{"key":"eli@barzilay.org","avatar":"https://avatars.githubusercontent.com/u/185905?v=4"},"body":"On May  8, Jeff King wrote:\n> On Fri, May 07, 2010 at 02:37:09PM -0400, Eli Barzilay wrote:\n> \n> > BTW, I've had at least 4 people now who got confused by this.  Is\n> > there any use for -M/-C without --follow?  In any case, it will be\n> > very helpful if the -M/-C descriptions said \"see also --follow\".\n> \n> Yes, it detects renames when doing diffs.\n\nOK, so just to clear this up: -C and -M (and --find-copies-harder) are\nfor `diff', and --follow is for `log' with a single file (and each\nwill pass it on to the other)?\n\n\n> Documentation patch is below.\n\nThanks!  (It would also be nice to mention it in -C, but not critical\nsince it's right after -M.)\n\n\n> > Also, is there a way to set this as the default for `git log'?\n> \n> If you mean --follow, then no. Nor would you probably want to,\n> because the --follow mechanism (as currently implemented) is pretty\n> restricted.  It can only take a single path currently.\n\nWell, the \"algorithm\" I used was probably one that is very popular:\n\n* use `git log some-file' with something that got renamed recently\n* be horrified that all history is gone\n* remember something vague about git detecting renames => go look at\n  the man page\n* Find -M, add it, try it, still doesn't work\n* Go back to scanning the man page, repeat\n* At the end I end up with:\n    -C -M --find-copies-harder --follow\n\nSo if there was some single\n\n  --do-whatever-you-can-as-much-as-you-can-to-find-all-renames\n\noption that would just turn everything on for all commands (eg, -M and\n-C and --find-copies harder for diffs, --follow for log for a single\nfile, and in some future when it's implemented, --follow for multiple\nfiles and directories), I'd happily jump on that.  For any command\nthat can accept it.  If there was a way to make it the default, I'd\nlove to turn it on.\n\nEven with the chain of more flags with descriptions that sound like\nthey're trying to scare me away by promising that my machine will work\nfor a REALLY LONG TIME, I'd still want to turn it on -- if it got\nsomething slower I sure didn't notice it so far, and that's on a real\nrepository which is not that small (but with git's reputation I won't\nbe surprised if \"slower\" means that I had to way a whole extra 20ms\nfor an answer...).  If something would really take too long, as in me\nsitting any waiting for an answer, *then* I can try to remove that and\nsee if I ran into some of the horrible edge cases...\n\n-- \n          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:\n                    http://barzilay.org/                   Maze is Life!\n"},{"id":"141229","messageId":"20100508053025.GG14998@coredump.intra.peff.net","threadId":"23732","inReplyTo":"19428.62170.654092.308682@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-08T05:30:25Z","receivedAt":"2010-05-08T05:30:25Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, May 08, 2010 at 01:12:58AM -0400, Eli Barzilay wrote:\n\n> > > BTW, I've had at least 4 people now who got confused by this.  Is\n> > > there any use for -M/-C without --follow?  In any case, it will be\n> > > very helpful if the -M/-C descriptions said \"see also --follow\".\n> > \n> > Yes, it detects renames when doing diffs.\n> \n> OK, so just to clear this up: -C and -M (and --find-copies-harder) are\n> for `diff', and --follow is for `log' with a single file (and each\n> will pass it on to the other)?\n\nYes (well, diff can never pass --follow to log, since diff never invokes\nlog, but yes, the per-commit diff shown by log uses the -C and -M given\nto log).\n\n> > Documentation patch is below.\n> \n> Thanks!  (It would also be nice to mention it in -C, but not critical\n> since it's right after -M.)\n\nYeah, I considered that, but didn't because of the proximity. But maybe\nit would make sense to do so, or to point -C at -M (e.g., say \"like -M,\nbut detect copies as well as renames\").\n\n> Well, the \"algorithm\" I used was probably one that is very popular:\n> \n> * use `git log some-file' with something that got renamed recently\n> * be horrified that all history is gone\n> * remember something vague about git detecting renames => go look at\n>   the man page\n> * Find -M, add it, try it, still doesn't work\n> * Go back to scanning the man page, repeat\n> * At the end I end up with:\n>     -C -M --find-copies-harder --follow\n> \n> So if there was some single\n> \n>   --do-whatever-you-can-as-much-as-you-can-to-find-all-renames\n\nBut I think all you really wanted was \"--follow\". I'd have to check the\ncode, but I'm not even sure whether \"-C\" will impact --follow at all.\n\n> Even with the chain of more flags with descriptions that sound like\n> they're trying to scare me away by promising that my machine will work\n> for a REALLY LONG TIME, I'd still want to turn it on -- if it got\n> something slower I sure didn't notice it so far, and that's on a real\n> repository which is not that small (but with git's reputation I won't\n> be surprised if \"slower\" means that I had to way a whole extra 20ms\n> for an answer...).  If something would really take too long, as in me\n> sitting any waiting for an answer, *then* I can try to remove that and\n> see if I ran into some of the horrible edge cases...\n\nNo, copy detection can be _really_ slow. There is a reason it isn't on\nby default. Try \"git log -1000 -p\" versus \"git log -1000 -p -C -M\n--find-copies-harder\" in some repository. In a simple git.git test, it\nis almost 5x slower (about 1 second versus 5 seconds on my machine). For\nlarge repositories, it can be much worse, because now each diff is\nO(size of repository) instead of O(size of changes).\n\nStill, I see your point that you might want it on all the time, if you\nhave a sufficiently small repo. There is \"diff.renames\" to turn on\nrename detection all the time. But I think a log.follow option doesn't\nmake sense at this point. For example:\n\n  $ git config log.follow true\n  $ git log foo.c ;# ok, follow foo.c\n  $ git log foo.c bar.c ;# uh oh, now what?\n\nDoes the last one just barf, and make you say \"git log --no-follow foo.c\nbar.c\"? Does it quietly turn off --follow, making the user guess why\n\"git log foo.c\" finds some history that \"git log foo.c bar.c\" doesn't?\n\n-Peff\n"},{"id":"141231","messageId":"7v39y3c5p1.fsf@alter.siamese.dyndns.org","threadId":"23732","inReplyTo":"19428.62170.654092.308682@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-05-08T05:39:54Z","receivedAt":"2010-05-08T05:39:54Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eli Barzilay <eli@barzilay.org> writes:\n\n> So if there was some single\n>\n>   --do-whatever-you-can-as-much-as-you-can-to-find-all-renames\n\nIf I am not mistaken, that is exactly the point of Bo's patch:\n\n    Message-Id: <1273207949-18500-4-git-send-email-struggleyb.nku@gmail.com>\n"},{"id":"141234","messageId":"19429.3589.823244.270582@winooski.ccs.neu.edu","threadId":"23732","inReplyTo":"7v39y3c5p1.fsf@alter.siamese.dyndns.org","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Eli Barzilay","fromEmail":"eli@barzilay.org","sentAt":"2010-05-08T07:08:53Z","receivedAt":"2010-05-08T07:08:53Z","isPatch":false,"sender":{"key":"eli@barzilay.org","avatar":"https://avatars.githubusercontent.com/u/185905?v=4"},"body":"On May  7, Junio C Hamano wrote:\n> Eli Barzilay <eli@barzilay.org> writes:\n> \n> > So if there was some single\n> >\n> >   --do-whatever-you-can-as-much-as-you-can-to-find-all-renames\n> \n> If I am not mistaken, that is exactly the point of Bo's patch:\n> \n>     Message-Id: <1273207949-18500-4-git-send-email-struggleyb.nku@gmail.com>\n\n(Actually, I was talking about some meta option that always turns on\nwhatever can be done to track copies; but given the clarification from\nJeff below, it's not as important as I first thought.)\n\n\nOn May  8, Jeff King wrote:\n> On Sat, May 08, 2010 at 01:12:58AM -0400, Eli Barzilay wrote:\n> \n> > > > BTW, I've had at least 4 people now who got confused by this.  Is\n> > > > there any use for -M/-C without --follow?  In any case, it will be\n> > > > very helpful if the -M/-C descriptions said \"see also --follow\".\n> > > \n> > > Yes, it detects renames when doing diffs.\n> > \n> > OK, so just to clear this up: -C and -M (and --find-copies-harder)\n> > are for `diff', and --follow is for `log' with a single file (and\n> > each will pass it on to the other)?\n> \n> Yes (well, diff can never pass --follow to log, since diff never\n> invokes log, but yes, the per-commit diff shown by log uses the -C\n> and -M given to log).\n\nAha -- I now see what makes most of this confusion, and an easy way to\nimprove it considerably: looking at the `git-log' man page, I have to\nwade through 11 pages of general diff options (well, 11 is so high\nbecause I like big fonts in my emacs...) before I get to the log\noptions, and even worse, there is no clear indication that those\noptions are only relevant if I want to get patches, which is (at least\nin my interactive use cases) far from being something I do often.\n(Googling around, I see more than a few examples of confused uses of\n`git log -M', even the git faq says \"'git log -M' will give the commit\nhistory with rename information\" -- no mention of it not making any\nsense with a file that went through a rename.)\n\nSo I think that it would really help if (1) the diff options in the\ngit-log man page move to after its own options, and (2) they appeared\nafter a title saying that these are the diff options, (3) `--follow'\nmoves up before the few preceding options that seem to me less\nimportant.  To clarify, I added a simple patch to the end of this\nmessage.  (`git-format-patch' has the same thing, but there it looks\nmore sensible to leave it as is.)\n\n\n> > So if there was some single\n> > \n> >   --do-whatever-you-can-as-much-as-you-can-to-find-all-renames\n> \n> But I think all you really wanted was \"--follow\". I'd have to check the\n> code, but I'm not even sure whether \"-C\" will impact --follow at all.\n\nIf -C/-M are really only affecting the patches, then yes, I'd probably\nbe happy with only `--follow' (or a way to have --follow on by default\nwhen possible).\n\n\n> No, copy detection can be _really_ slow. There is a reason it isn't\n> on by default. Try \"git log -1000 -p\" versus \"git log -1000 -p -C -M\n> --find-copies-harder\" in some repository. In a simple git.git test,\n> it is almost 5x slower (about 1 second versus 5 seconds on my\n> machine). For large repositories, it can be much worse, because now\n> each diff is O(size of repository) instead of O(size of changes).\n\nYes, I see that.  I was talking about interactive uses, where I'd\nnever want to see a 1000 diffs, or even 2.  But given that -C/-M are\nonly for patches, then I agree with that.\n\n\n> Still, I see your point that you might want it on all the time, if you\n> have a sufficiently small repo. There is \"diff.renames\" to turn on\n> rename detection all the time.\n\n(Ah, I missed that...)\n\n\n> But I think a log.follow option doesn't make sense at this\n> point. For example:\n> \n>   $ git config log.follow true\n>   $ git log foo.c ;# ok, follow foo.c\n>   $ git log foo.c bar.c ;# uh oh, now what?\n> \n> Does the last one just barf, and make you say \"git log --no-follow\n> foo.c bar.c\"? Does it quietly turn off --follow, making the user\n> guess why \"git log foo.c\" finds some history that \"git log foo.c\n> bar.c\" doesn't?\n\nHow about these options:\n\n  git config log.follow if-single-file\n    makes it use --follow only when there's a single file path given,\n    ignoring it otherwise (with no confusion about it now)\n\n  git config log.follow if-possible\n    makes it do the same, but might also do it for more cases if/when\n    they become available (so this is the \"do the best you can\"\n    option)\n\n  git config log.follow true\n    invalid until it is always possible to use --follow\n\n?\n\n\n\n[this is the patch that I mentioned above]\n\n-------------------------------------------------------------------------------\ndiff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\nindex fb184ba..6bc7064 100644\n--- a/Documentation/git-log.txt\n+++ b/Documentation/git-log.txt\n@@ -24,7 +24,6 @@ OPTIONS\n -------\n \n :git-log: 1\n-include::diff-options.txt[]\n \n -<n>::\n \tLimits the number of commits to show.\n@@ -37,6 +36,10 @@ include::diff-options.txt[]\n \tand <until>, see \"SPECIFYING REVISIONS\" section in\n \tlinkgit:git-rev-parse[1].\n \n+--follow::\n+\tContinue listing the history of a file beyond renames\n+\t(works only for a single file).\n+\n --decorate[=short|full]::\n \tPrint out the ref names of any commits that are shown. If 'short' is\n \tspecified, the ref name prefixes 'refs/heads/', 'refs/tags/' and\n@@ -55,9 +58,6 @@ include::diff-options.txt[]\n \tthe specified paths; this means that \"<path>...\" limits only\n \tcommits, and doesn't limit diff for those commits.\n \n---follow::\n-\tContinue listing the history of a file beyond renames.\n-\n --log-size::\n \tBefore the log message print out its size in bytes. Intended\n \tmainly for porcelain tools consumption. If git is unable to\n@@ -71,6 +71,10 @@ include::diff-options.txt[]\n \tto be prefixed with \"\\-- \" to separate them from options or\n \trefnames.\n \n+Common diff options\n+~~~~~~~~~~~~~~~~~~~\n+\n+include::diff-options.txt[]\n \n include::rev-list-options.txt[]\n \n-------------------------------------------------------------------------------\n\n\n-- \n          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:\n                    http://barzilay.org/                   Maze is Life!\n"},{"id":"141525","messageId":"20100512113855.GB23847@coredump.intra.peff.net","threadId":"23732","inReplyTo":"19429.3589.823244.270582@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-12T11:38:55Z","receivedAt":"2010-05-12T11:38:55Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, May 08, 2010 at 03:08:53AM -0400, Eli Barzilay wrote:\n\n> So I think that it would really help if (1) the diff options in the\n> git-log man page move to after its own options, and (2) they appeared\n> after a title saying that these are the diff options, (3) `--follow'\n> moves up before the few preceding options that seem to me less\n> important.  To clarify, I added a simple patch to the end of this\n> message.  (`git-format-patch' has the same thing, but there it looks\n> more sensible to leave it as is.)\n\nI have no opinion on moving --follow around, but I definitely agree that\nmore clearly marking the diff-options (and including them after\nrevision traversal options) is much better.\n\n> How about these options:\n> \n>   git config log.follow if-single-file\n>     makes it use --follow only when there's a single file path given,\n>     ignoring it otherwise (with no confusion about it now)\n> \n>   git config log.follow if-possible\n>     makes it do the same, but might also do it for more cases if/when\n>     they become available (so this is the \"do the best you can\"\n>     option)\n> \n>   git config log.follow true\n>     invalid until it is always possible to use --follow\n\nI'm not thrilled with it. It still leaves the confusing behavior, but\nbecause we forced the user to pick the confusing behavior, we get to\nclaim it is their fault. So while we may be guilt-free, I'm not happy\nwith an option that produces such confusing behavior.\n\nI really wonder if it would be that hard to just fix the code to follow\nseveral files. It shouldn't be conceptually different. When any file\nmatching the pathspec we're following has a creation event going from\nthe parent to the commit in question, then we would do rename detection\nfor that file (and any others created in the same commit). Any detected\nsources get added to the pathspec.\n\n> diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\n> index fb184ba..6bc7064 100644\n> --- a/Documentation/git-log.txt\n> +++ b/Documentation/git-log.txt\n> @@ -24,7 +24,6 @@ OPTIONS\n>  -------\n>  \n>  :git-log: 1\n> -include::diff-options.txt[]\n\nThis \":git-log: 1\" magic should probably follow the include. It sets up\nan attribute for diff-options.txt to conditionally include some\nlog-specific bits.\n\n-Peff\n"},{"id":"141526","messageId":"19434.39095.448649.313537@winooski.ccs.neu.edu","threadId":"23732","inReplyTo":"20100512113855.GB23847@coredump.intra.peff.net","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Eli Barzilay","fromEmail":"eli@barzilay.org","sentAt":"2010-05-12T12:01:59Z","receivedAt":"2010-05-12T12:01:59Z","isPatch":false,"sender":{"key":"eli@barzilay.org","avatar":"https://avatars.githubusercontent.com/u/185905?v=4"},"body":"On May 12, Jeff King wrote:\n> On Sat, May 08, 2010 at 03:08:53AM -0400, Eli Barzilay wrote:\n> \n> > So I think that it would really help if (1) the diff options in the\n> > git-log man page move to after its own options, and (2) they appeared\n> > after a title saying that these are the diff options, (3) `--follow'\n> > moves up before the few preceding options that seem to me less\n> > important.  To clarify, I added a simple patch to the end of this\n> > message.  (`git-format-patch' has the same thing, but there it looks\n> > more sensible to leave it as is.)\n> \n> I have no opinion on moving --follow around, but I definitely agree that\n> more clearly marking the diff-options (and including them after\n> revision traversal options) is much better.\n\nShould I send that reorganization as a proper patch then?\n\n\n> > diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\n> > index fb184ba..6bc7064 100644\n> > --- a/Documentation/git-log.txt\n> > +++ b/Documentation/git-log.txt\n> > @@ -24,7 +24,6 @@ OPTIONS\n> >  -------\n> >  \n> >  :git-log: 1\n> > -include::diff-options.txt[]\n> \n> This \":git-log: 1\" magic should probably follow the include. It sets up\n> an attribute for diff-options.txt to conditionally include some\n> log-specific bits.\n\nIt seemed like it's a definition that could be used elsewhere too (eg,\nin other includes that could be added in the future).\n\n\n> > How about these options:\n> > \n> >   git config log.follow if-single-file\n> >     makes it use --follow only when there's a single file path given,\n> >     ignoring it otherwise (with no confusion about it now)\n> > \n> >   git config log.follow if-possible\n> >     makes it do the same, but might also do it for more cases if/when\n> >     they become available (so this is the \"do the best you can\"\n> >     option)\n> > \n> >   git config log.follow true\n> >     invalid until it is always possible to use --follow\n> \n> I'm not thrilled with it. It still leaves the confusing behavior,\n> but because we forced the user to pick the confusing behavior, we\n> get to claim it is their fault. So while we may be guilt-free, I'm\n> not happy with an option that produces such confusing behavior.\n\nWell, yes -- it leaves that potential source of confusion, which could\nresult if someone recommends to just use the `if-single-file' thing,\nand I do that while being unaware of what it actually does.  But OTOH,\nit helps with the apparently popular confusion that makes people panic\nand send \"WHERE DID MY HISTORY GO???\" emails.  (It's been about 2-3\nweeks since we migrated from svn to git, and I had at least three\npeople do exactly that.)\n\n\n> I really wonder if it would be that hard to just fix the code to follow\n> several files. [...]\n\nThat would obviously be a better solution...\n\n-- \n          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:\n                    http://barzilay.org/                   Maze is Life!\n"},{"id":"141527","messageId":"20100512124948.GA11761@coredump.intra.peff.net","threadId":"23732","inReplyTo":"19434.39095.448649.313537@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-12T12:49:48Z","receivedAt":"2010-05-12T12:49:48Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, May 12, 2010 at 08:01:59AM -0400, Eli Barzilay wrote:\n\n> > I have no opinion on moving --follow around, but I definitely agree that\n> > more clearly marking the diff-options (and including them after\n> > revision traversal options) is much better.\n> \n> Should I send that reorganization as a proper patch then?\n\nYes, please.\n\n> > This \":git-log: 1\" magic should probably follow the include. It sets up\n> > an attribute for diff-options.txt to conditionally include some\n> > log-specific bits.\n> \n> It seemed like it's a definition that could be used elsewhere too (eg,\n> in other includes that could be added in the future).\n\nYeah, I considered that, too. So maybe it is best at the top of the\noptions list (but in that case, perhaps it should go at the very top of\nthe file).\n\n> > I really wonder if it would be that hard to just fix the code to follow\n> > several files. [...]\n> \n> That would obviously be a better solution...\n\nIt really wasn't too bad, actually. Here is a rough cut. Still to be\nconsidered are:\n\n - the XXX comment below about proper pathspec limiting. Should be easy\n   to fix, but I need to look into it.\n\n - I haven't tested it with --full-diff to see if there are funny\n   interactions with the pathspec limiting.\n\n - The original --follow swapped the old single path to follow for the\n   new one. This patch instead _appends_ to the list of pathspecs. We\n   have to do this because the pathspecs may still be of interest. For\n   example, consider \"git log --follow subdir\". When we see that\n   \"subdir/foo\" came from \"foo\", we start following \"foo\", too. But we\n   can't stop following \"subdir\", because there may be other files of\n   interest in it.\n\n   But this means if you have a history where the path \"foo\" is of\n   interest for a while, then goes away, then you move something else\n   into its place, you will see commits touching the old foo, even\n   though its content is not connected with the new foo.\n\n   We could special-case when we exactly match a file with a pathspec,\n   since we know it is no longer of interest. But I am tempted to call\n   the new behavior _more_ useful than the old. It means that \"git log\n   --follow <pathspec>\" means we are interested in what has _ever_ been\n   in <pathspec> (which is what it means without follow), in addition to\n   the history of anything that got renamed into pathspec (ever).\n\nAnyway, here is the patch. My testing so far has been very simple, so\nplease try it on a few repos and let me know if it does what you expect\nin all cases. Note that is based on \"next\", as it has Bo's\nfind_copies_harder patch.\n\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 976e16f..5a7611a 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -88,9 +88,10 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,\n \tif (rev->diffopt.pickaxe || rev->diffopt.filter)\n \t\trev->always_show_header = 0;\n \tif (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {\n-\t\trev->always_show_header = 0;\n-\t\tif (rev->diffopt.nr_paths != 1)\n-\t\t\tusage(\"git logs can only follow renames on one pathname at a time\");\n+\t\tif (!rev->diffopt.nr_paths)\n+\t\t\tDIFF_OPT_CLR(&rev->diffopt, FOLLOW_RENAMES);\n+\t\telse\n+\t\t\trev->always_show_header = 0;\n \t}\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 1fb3e94..9467f27 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -5,6 +5,7 @@\n #include \"diff.h\"\n #include \"diffcore.h\"\n #include \"tree.h\"\n+#include \"dir.h\"\n \n static char *malloc_base(const char *base, int baselen, const char *path, int pathlen)\n {\n@@ -322,78 +323,75 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru\n }\n \n /*\n- * Does it look like the resulting diff might be due to a rename?\n- *  - single entry\n- *  - not a valid previous file\n+ * Does it look like the resulting diff might be due to a rename? If we have\n+ * any files that appeared, then maybe.\n  */\n static inline int diff_might_be_rename(void)\n {\n-\treturn diff_queued_diff.nr == 1 &&\n-\t\t!DIFF_FILE_VALID(diff_queued_diff.queue[0]->one);\n+\tint i;\n+\tfor (i = 0; i < diff_queued_diff.nr; i++)\n+\t\tif (!DIFF_FILE_VALID(diff_queued_diff.queue[i]->one))\n+\t\t\treturn 1;\n+\treturn 0;\n }\n \n static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt)\n {\n \tstruct diff_options diff_opts;\n+\tstruct diff_queue_struct old_queue;\n \tstruct diff_queue_struct *q = &diff_queued_diff;\n-\tstruct diff_filepair *choice;\n-\tconst char *paths[1];\n+\tconst char **new_paths;\n+\tint new_paths_num, new_paths_alloc;\n \tint i;\n \n-\t/* Remove the file creation entry from the diff queue, and remember it */\n-\tchoice = q->queue[0];\n-\tq->nr = 0;\n+\t/* The diff machinery operates on a global queue, so we need to save a\n+\t * copy before doing another diff. */\n+\told_queue = *q;\n+\tDIFF_QUEUE_CLEAR(q);\n \n \tdiff_setup(&diff_opts);\n \tDIFF_OPT_SET(&diff_opts, RECURSIVE);\n \tDIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);\n \tdiff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;\n-\tdiff_opts.single_follow = opt->paths[0];\n \tdiff_opts.break_opt = opt->break_opt;\n-\tpaths[0] = NULL;\n-\tdiff_tree_setup_paths(paths, &diff_opts);\n \tif (diff_setup_done(&diff_opts) < 0)\n \t\tdie(\"unable to set up diff options to follow renames\");\n \tdiff_tree(t1, t2, base, &diff_opts);\n \tdiffcore_std(&diff_opts);\n-\tdiff_tree_release_paths(&diff_opts);\n \n-\t/* Go through the new set of filepairing, and see if we find a more interesting one */\n+\tnew_paths_num = new_paths_alloc = opt->nr_paths;\n+\tnew_paths = xmalloc(opt->nr_paths * sizeof(*new_paths));\n+\tfor (i = 0; i < opt->nr_paths; i++)\n+\t\tnew_paths[i] = opt->paths[i];\n+\n+\t/* Go through the new set of filepairs, looking for renames. */\n \tfor (i = 0; i < q->nr; i++) {\n \t\tstruct diff_filepair *p = q->queue[i];\n \n-\t\t/*\n-\t\t * Found a source? Not only do we use that for the new\n-\t\t * diff_queued_diff, we will also use that as the path in\n-\t\t * the future!\n-\t\t */\n-\t\tif ((p->status == 'R' || p->status == 'C') && !strcmp(p->two->path, opt->paths[0])) {\n-\t\t\t/* Switch the file-pairs around */\n-\t\t\tq->queue[i] = choice;\n-\t\t\tchoice = p;\n-\n-\t\t\t/* Update the path we use from now on.. */\n-\t\t\tdiff_tree_release_paths(opt);\n-\t\t\topt->paths[0] = xstrdup(p->one->path);\n-\t\t\tdiff_tree_setup_paths(opt->paths, opt);\n-\t\t\tbreak;\n-\t\t}\n-\t}\n+\t\tif (p->status != 'R' && p->status != 'C')\n+\t\t\tcontinue;\n \n-\t/*\n-\t * Then, discard all the non-relevant file pairs...\n-\t */\n-\tfor (i = 0; i < q->nr; i++) {\n-\t\tstruct diff_filepair *p = q->queue[i];\n-\t\tdiff_free_filepair(p);\n+\t\t/* XXX actually this is the slightly different wildcarding\n+\t\t * pathspec. We really want to check just prefixes. But\n+\t\t * I wonder if we can convince the diff machinery to just\n+\t\t * be interested in these paths as destinations, but use\n+\t\t * the whole tree as sources */\n+\t\tif (!match_pathspec(opt->paths, p->two->path,\n+\t\t\t\t   strlen(p->two->path), 0, NULL))\n+\t\t\tcontinue;\n+\n+\t\tALLOC_GROW(new_paths, new_paths_num + 1, new_paths_alloc);\n+\t\tnew_paths[new_paths_num++] = xstrdup(p->one->path);\n \t}\n \n-\t/*\n-\t * .. and re-instate the one we want (which might be either the\n-\t * original one, or the rename/copy we found)\n-\t */\n-\tq->queue[0] = choice;\n-\tq->nr = 1;\n+\t/* now finalize the new paths */\n+\tALLOC_GROW(new_paths, new_paths_num + 1, new_paths_alloc);\n+\tnew_paths[new_paths_num] = NULL;\n+\tdiff_tree_setup_paths(new_paths, opt);\n+\n+\t/* and restore our old queue */\n+\tfree(q->queue);\n+\t*q = old_queue;\n }\n \n int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt)\n-- \n1.7.1.258.ge9097.dirty\n"},{"id":"141528","messageId":"20100512130339.GA19072@coredump.intra.peff.net","threadId":"23732","inReplyTo":"20100512124948.GA11761@coredump.intra.peff.net","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-12T13:03:39Z","receivedAt":"2010-05-12T13:03:39Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, May 12, 2010 at 08:49:48AM -0400, Jeff King wrote:\n\n> Anyway, here is the patch. My testing so far has been very simple, so\n> please try it on a few repos and let me know if it does what you expect\n> in all cases. Note that is based on \"next\", as it has Bo's\n> find_copies_harder patch.\n\nBy the way, here are some basic speed tests in git.git:\n\n  $ time git log builtin >/dev/null\n  real    0m0.486s\n  user    0m0.468s\n  sys     0m0.016s\n\n  $ time git log --follow builtin >/dev/null\n  real    0m23.518s\n  user    0m23.469s\n  sys     0m0.040s\n\nSo it's _way_ slower, but still snappy enough with the first few commits\nnot to be awful. However, I haven't done any profiling, so it may be\nthat we can improve that by limiting the rename-detection diff only to\ninteresting paths.\n\n-Peff\n"},{"id":"141530","messageId":"AANLkTin0E9rd7Ld3exCA5NbGnYhlspUZ93KT1O6Zvzrq@mail.gmail.com","threadId":"23732","inReplyTo":"19434.39095.448649.313537@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Bo Yang","fromEmail":"struggleyb.nku@gmail.com","sentAt":"2010-05-12T13:06:11Z","receivedAt":"2010-05-12T13:06:11Z","isPatch":false,"sender":{"key":"struggleyb.nku@gmail.com","avatar":"https://avatars.githubusercontent.com/u/233030?v=4"},"body":"Hi,\n\nOn Wed, May 12, 2010 at 8:01 PM, Eli Barzilay <eli@barzilay.org> wrote:\n>> I really wonder if it would be that hard to just fix the code to follow\n>> several files. [...]\n>\n> That would obviously be a better solution...\n\nThe new line level history browser utility will follow multiple line\nranges of multiple files and it of course will do this. :) Please wait\nfor some days, I will make it possible in this summer.\n\nRegards!\nBo\n-- \nMy blog: http://blog.morebits.org\n"},{"id":"141529","messageId":"20100512130918.GA20755@coredump.intra.peff.net","threadId":"23732","inReplyTo":"AANLkTin0E9rd7Ld3exCA5NbGnYhlspUZ93KT1O6Zvzrq@mail.gmail.com","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-12T13:09:18Z","receivedAt":"2010-05-12T13:09:18Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, May 12, 2010 at 09:06:11PM +0800, Bo Yang wrote:\n\n> On Wed, May 12, 2010 at 8:01 PM, Eli Barzilay <eli@barzilay.org> wrote:\n> >> I really wonder if it would be that hard to just fix the code to follow\n> >> several files. [...]\n> >\n> > That would obviously be a better solution...\n> \n> The new line level history browser utility will follow multiple line\n> ranges of multiple files and it of course will do this. :) Please wait\n> for some days, I will make it possible in this summer.\n\nYeah, I know there is some overlap with your work. I wonder, though, if\nit may be desirable for speed reasons to have three levels of limiting:\n\n  1. limit by pathspec (what we have now, very fast)\n\n  2. limit by path with rename following (my patch, slower)\n\n  3. limit to history of arbitrary content (your work, which will\n     presumably be even slower still)\n\nObviously if your (3) can be as fast as my (2), then there is no need\nfor (2).\n\n-Peff\n"},{"id":"141534","messageId":"19434.48308.815673.263230@winooski.ccs.neu.edu","threadId":"23732","inReplyTo":"20100512124948.GA11761@coredump.intra.peff.net","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Eli Barzilay","fromEmail":"eli@barzilay.org","sentAt":"2010-05-12T14:35:32Z","receivedAt":"2010-05-12T14:35:32Z","isPatch":false,"sender":{"key":"eli@barzilay.org","avatar":"https://avatars.githubusercontent.com/u/185905?v=4"},"body":"On May 12, Jeff King wrote:\n> On Wed, May 12, 2010 at 08:01:59AM -0400, Eli Barzilay wrote:\n> \n> > > I have no opinion on moving --follow around, but I definitely agree that\n> > > more clearly marking the diff-options (and including them after\n> > > revision traversal options) is much better.\n> > \n> > Should I send that reorganization as a proper patch then?\n> \n> Yes, please.\n\nDone.\n\n\n> > > This \":git-log: 1\" magic should probably follow the include. It sets up\n> > > an attribute for diff-options.txt to conditionally include some\n> > > log-specific bits.\n> > \n> > It seemed like it's a definition that could be used elsewhere too (eg,\n> > in other includes that could be added in the future).\n> \n> Yeah, I considered that, too. So maybe it is best at the top of the\n> options list (but in that case, perhaps it should go at the very top\n> of the file).\n\nSince I don't know, I just dragged it along with the include.  (Moving\nit to the top would be better better done with the other files, so\nit's a different thing...)\n\n\n> Anyway, here is the patch. My testing so far has been very simple,\n> so please try it on a few repos and let me know if it does what you\n> expect in all cases. Note that is based on \"next\", as it has Bo's\n> find_copies_harder patch.\n\nI tried it with our repository -- it does what I expected it to do wrt\nshowing the log messages, and at a very small penalty (~0.9s vs ~0.7s\nfor scanning a history of about 20k commits).\n\nBut with `-p' it was doing something confusing: I used two files that\nwere recently renamed, and the result was the correct log history, but\nthe first patch that was shown (the rename) showed the two files as\nadded.  (That's even when I added `-C' and `-M'.)  This happens even\nwith a single path.  OTOH, using `--follow' with `-p' and a single\npath without your patch produces the expected result where the first\npatch is a rename (even without `-C'/`-M').\n\n-- \n          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:\n                    http://barzilay.org/                   Maze is Life!\n"},{"id":"141535","messageId":"19434.48712.225245.305483@winooski.ccs.neu.edu","threadId":"23732","inReplyTo":"AANLkTin0E9rd7Ld3exCA5NbGnYhlspUZ93KT1O6Zvzrq@mail.gmail.com","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Eli Barzilay","fromEmail":"eli@barzilay.org","sentAt":"2010-05-12T14:42:16Z","receivedAt":"2010-05-12T14:42:16Z","isPatch":false,"sender":{"key":"eli@barzilay.org","avatar":"https://avatars.githubusercontent.com/u/185905?v=4"},"body":"On May 12, Bo Yang wrote:\n> On Wed, May 12, 2010 at 8:01 PM, Eli Barzilay <eli@barzilay.org> wrote:\n> > That would obviously be a better solution...\n> \n> The new line level history browser utility will follow multiple line\n> ranges of multiple files and it of course will do this. :) Please\n> wait for some days, I will make it possible in this summer.\n\n(Looking at the description (in the SoC2010Ideas page) it wasn't clear\nto me whether this will be simple to use as log -- that is, just run\nsome `git foo dir/{x,y,z}' or `git foo dir'.)\n\n-- \n          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:\n                    http://barzilay.org/                   Maze is Life!\n"},{"id":"141536","messageId":"AANLkTikhJO7MI9c5KezktpcMoQ86JPzAr4iT6_Yt2Ms3@mail.gmail.com","threadId":"23732","inReplyTo":"19434.48712.225245.305483@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Bo Yang","fromEmail":"struggleyb.nku@gmail.com","sentAt":"2010-05-12T14:49:03Z","receivedAt":"2010-05-12T14:49:03Z","isPatch":false,"sender":{"key":"struggleyb.nku@gmail.com","avatar":"https://avatars.githubusercontent.com/u/233030?v=4"},"body":"Hi,\nOn Wed, May 12, 2010 at 10:42 PM, Eli Barzilay <eli@barzilay.org> wrote:\n> (Looking at the description (in the SoC2010Ideas page) it wasn't clear\n> to me whether this will be simple to use as log -- that is, just run\n> some `git foo dir/{x,y,z}' or `git foo dir'.)\n\nThe idea here is that line level history will trace rename/copies of\nmultiple files and trace rename/copies of multiple files is obviously\na subset of tracing of it. So, what I mean is along implement such a\nline level browser, I can do the --follow files case very well. :)\n\nAnd as Jeff said in his mail, his implementation is necessary in speed\nand please still use 'git log --follow -- pathspec' for whole file\nhistory traversing.\n\nRegards!\nBo\n\n-- \nMy blog: http://blog.morebits.org\n"},{"id":"141538","messageId":"AANLkTilje2dBHjd2aykMnAjWdf8k1vayJ_ez4IfMrl7_@mail.gmail.com","threadId":"23732","inReplyTo":"19434.48308.815673.263230@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Bo Yang","fromEmail":"struggleyb.nku@gmail.com","sentAt":"2010-05-12T16:07:24Z","receivedAt":"2010-05-12T16:07:24Z","isPatch":false,"sender":{"key":"struggleyb.nku@gmail.com","avatar":"https://avatars.githubusercontent.com/u/233030?v=4"},"body":"Hi,\n\n> But with `-p' it was doing something confusing: I used two files that\n> were recently renamed, and the result was the correct log history, but\n> the first patch that was shown (the rename) showed the two files as\n> added.  (That's even when I added `-C' and `-M'.)  This happens even\n> with a single path.  OTOH, using `--follow' with `-p' and a single\n> path without your patch produces the expected result where the first\n> patch is a rename (even without `-C'/`-M').\n\nTry this one, it only change a little on Jeff's patch, my simple tests\nshow it works. Apply it on 'next' branch.\n\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 6208703..0142036 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -70,9 +70,10 @@ static void cmd_log_init(int argc, const char\n**argv, const char *prefix,\n        if (rev->diffopt.pickaxe || rev->diffopt.filter)\n                rev->always_show_header = 0;\n        if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {\n-               rev->always_show_header = 0;\n-               if (rev->diffopt.nr_paths != 1)\n-                       usage(\"git logs can only follow renames on one\npathname at a time\");\n+               if (!rev->diffopt.nr_paths)\n+                       DIFF_OPT_CLR(&rev->diffopt, FOLLOW_RENAMES);\n+               else\n+                       rev->always_show_header = 0;\n        }\n        for (i = 1; i < argc; i++) {\n                const char *arg = argv[i];\ndiff --git a/diffcore.h b/diffcore.h\nindex 491bea0..9039a06 100644\n--- a/diffcore.h\n+++ b/diffcore.h\n@@ -99,6 +99,10 @@ struct diff_queue_struct {\n                (q)->nr = (q)->alloc = 0; \\\n                (q)->run = 0; \\\n        } while(0);\n+#define DIFF_QUEUE_MARK_RUN(q, r) \\\n+       do { \\\n+               (q)->run = (r); \\\n+       } while(0);\n\n extern struct diff_queue_struct diff_queued_diff;\n extern struct diff_filepair *diff_queue(struct diff_queue_struct *,\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 1fb3e94..dd95f74 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -5,6 +5,7 @@\n #include \"diff.h\"\n #include \"diffcore.h\"\n #include \"tree.h\"\n+#include \"dir.h\"\n\n static char *malloc_base(const char *base, int baselen, const char\n*path, int pathlen)\n {\n@@ -322,78 +323,74 @@ int diff_tree(struct tree_desc *t1, struct\ntree_desc *t2, const char *base, stru\n }\n\n /*\n- * Does it look like the resulting diff might be due to a rename?\n- *  - single entry\n- *  - not a valid previous file\n+ * Does it look like the resulting diff might be due to a rename? If we have\n+ * any files that appeared, then maybe.\n  */\n static inline int diff_might_be_rename(void)\n {\n-       return diff_queued_diff.nr == 1 &&\n-               !DIFF_FILE_VALID(diff_queued_diff.queue[0]->one);\n+       int i;\n+       for (i = 0; i < diff_queued_diff.nr; i++)\n+               if (!DIFF_FILE_VALID(diff_queued_diff.queue[i]->one))\n+                       return 1;\n+       return 0;\n }\n\n static void try_to_follow_renames(struct tree_desc *t1, struct\ntree_desc *t2, const char *base, struct diff_options *opt)\n {\n        struct diff_options diff_opts;\n+       struct diff_queue_struct outq;\n        struct diff_queue_struct *q = &diff_queued_diff;\n-       struct diff_filepair *choice;\n-       const char *paths[1];\n+       const char **new_paths;\n+       int new_paths_num, new_paths_alloc;\n        int i;\n\n-       /* Remove the file creation entry from the diff queue, and\nremember it */\n-       choice = q->queue[0];\n+       DIFF_QUEUE_CLEAR(&outq);\n        q->nr = 0;\n\n        diff_setup(&diff_opts);\n        DIFF_OPT_SET(&diff_opts, RECURSIVE);\n        DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);\n        diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;\n-       diff_opts.single_follow = opt->paths[0];\n        diff_opts.break_opt = opt->break_opt;\n-       paths[0] = NULL;\n-       diff_tree_setup_paths(paths, &diff_opts);\n        if (diff_setup_done(&diff_opts) < 0)\n                die(\"unable to set up diff options to follow renames\");\n        diff_tree(t1, t2, base, &diff_opts);\n        diffcore_std(&diff_opts);\n-       diff_tree_release_paths(&diff_opts);\n\n-       /* Go through the new set of filepairing, and see if we find a\nmore interesting one */\n+       new_paths_num = new_paths_alloc = opt->nr_paths;\n+       new_paths = xmalloc(opt->nr_paths * sizeof(*new_paths));\n+       for (i = 0; i < opt->nr_paths; i++)\n+               new_paths[i] = opt->paths[i];\n+\n+       /* Go through the new set of filepairs, looking for renames. */\n        for (i = 0; i < q->nr; i++) {\n                struct diff_filepair *p = q->queue[i];\n\n-               /*\n-                * Found a source? Not only do we use that for the new\n-                * diff_queued_diff, we will also use that as the path in\n-                * the future!\n-                */\n-               if ((p->status == 'R' || p->status == 'C') &&\n!strcmp(p->two->path, opt->paths[0])) {\n-                       /* Switch the file-pairs around */\n-                       q->queue[i] = choice;\n-                       choice = p;\n-\n-                       /* Update the path we use from now on.. */\n-                       diff_tree_release_paths(opt);\n-                       opt->paths[0] = xstrdup(p->one->path);\n-                       diff_tree_setup_paths(opt->paths, opt);\n-                       break;\n-               }\n-       }\n+               /* XXX actually this is the slightly different wildcarding\n+                * pathspec. We really want to check just prefixes. But\n+                * I wonder if we can convince the diff machinery to just\n+                * be interested in these paths as destinations, but use\n+                * the whole tree as sources */\n+               if (!match_pathspec(opt->paths, p->two->path,\n+                                  strlen(p->two->path), 0, NULL))\n+                       continue;\n\n-       /*\n-        * Then, discard all the non-relevant file pairs...\n-        */\n-       for (i = 0; i < q->nr; i++) {\n-               struct diff_filepair *p = q->queue[i];\n-               diff_free_filepair(p);\n+               diff_q(&outq, p);\n+\n+               ALLOC_GROW(new_paths, new_paths_num + 1, new_paths_alloc);\n+               new_paths[new_paths_num++] = xstrdup(p->one->path);\n        }\n\n-       /*\n-        * .. and re-instate the one we want (which might be either the\n-        * original one, or the rename/copy we found)\n-        */\n-       q->queue[0] = choice;\n-       q->nr = 1;\n+       /* now finalize the new paths */\n+       ALLOC_GROW(new_paths, new_paths_num + 1, new_paths_alloc);\n+       new_paths[new_paths_num] = NULL;\n+       diff_tree_release_paths(opt);\n+       diff_tree_setup_paths(new_paths, opt);\n+\n+       /* and restore our old queue */\n+       free(q->queue);\n+       *q = outq;\n+       DIFF_QUEUE_MARK_RUN(q, 1);\n }\n\n int diff_tree_sha1(const unsigned char *old, const unsigned char\n*new, const char *base, struct diff_options *opt)\n\n\nRegards!\nBo\n"},{"id":"141539","messageId":"20100512164522.GA14710@coredump.intra.peff.net","threadId":"23732","inReplyTo":"AANLkTilje2dBHjd2aykMnAjWdf8k1vayJ_ez4IfMrl7_@mail.gmail.com","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-12T16:45:22Z","receivedAt":"2010-05-12T16:45:22Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, May 13, 2010 at 12:07:24AM +0800, Bo Yang wrote:\n\n> > But with `-p' it was doing something confusing: I used two files that\n> > were recently renamed, and the result was the correct log history, but\n> > the first patch that was shown (the rename) showed the two files as\n> > added.  (That's even when I added `-C' and `-M'.)  This happens even\n> > with a single path.  OTOH, using `--follow' with `-p' and a single\n> > path without your patch produces the expected result where the first\n> > patch is a rename (even without `-C'/`-M').\n> \n> Try this one, it only change a little on Jeff's patch, my simple tests\n> show it works. Apply it on 'next' branch.\n\nThis is badly whitespace damaged. I fixed up some wrapping, but it seems\nthat there was some tab/space interchanges, too. Can you repost?\n\n-Peff\n"},{"id":"141559","messageId":"AANLkTilES9d8rj5Zwfju7t3H7cjM7h9HWL8YprcxPc6t@mail.gmail.com","threadId":"23732","inReplyTo":"20100512164522.GA14710@coredump.intra.peff.net","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Bo Yang","fromEmail":"struggleyb.nku@gmail.com","sentAt":"2010-05-13T02:12:52Z","receivedAt":"2010-05-13T02:12:52Z","isPatch":false,"sender":{"key":"struggleyb.nku@gmail.com","avatar":"https://avatars.githubusercontent.com/u/233030?v=4"},"body":"Hi Jeff,\nOn Thu, May 13, 2010 at 12:45 AM, Jeff King <peff@peff.net> wrote:\n> On Thu, May 13, 2010 at 12:07:24AM +0800, Bo Yang wrote:\n>>\n>> Try this one, it only change a little on Jeff's patch, my simple tests\n>> show it works. Apply it on 'next' branch.\n>\n> This is badly whitespace damaged. I fixed up some wrapping, but it seems\n> that there was some tab/space interchanges, too. Can you repost?\n\nAh, sorry. I just copy the patch from my putty window, so it convert\nall tabs into spaces...\nAnd the following change this. Also, I have run a 'make test', seems\nthere is no problem for it. Happy try it!\n\n\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 6208703..0142036 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -70,9 +70,10 @@ static void cmd_log_init(int argc, const char\n**argv, const char *prefix,\n \tif (rev->diffopt.pickaxe || rev->diffopt.filter)\n \t\trev->always_show_header = 0;\n \tif (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {\n-\t\trev->always_show_header = 0;\n-\t\tif (rev->diffopt.nr_paths != 1)\n-\t\t\tusage(\"git logs can only follow renames on one pathname at a time\");\n+\t\tif (!rev->diffopt.nr_paths)\n+\t\t\tDIFF_OPT_CLR(&rev->diffopt, FOLLOW_RENAMES);\n+\t\telse\n+\t\t\trev->always_show_header = 0;\n \t}\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\ndiff --git a/diffcore.h b/diffcore.h\nindex 491bea0..9039a06 100644\n--- a/diffcore.h\n+++ b/diffcore.h\n@@ -99,6 +99,10 @@ struct diff_queue_struct {\n \t\t(q)->nr = (q)->alloc = 0; \\\n \t\t(q)->run = 0; \\\n \t} while(0);\n+#define DIFF_QUEUE_MARK_RUN(q, r) \\\n+\tdo { \\\n+\t\t(q)->run = (r); \\\n+\t} while(0);\n\n extern struct diff_queue_struct diff_queued_diff;\n extern struct diff_filepair *diff_queue(struct diff_queue_struct *,\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 1fb3e94..dd95f74 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -5,6 +5,7 @@\n #include \"diff.h\"\n #include \"diffcore.h\"\n #include \"tree.h\"\n+#include \"dir.h\"\n\n static char *malloc_base(const char *base, int baselen, const char\n*path, int pathlen)\n {\n@@ -322,78 +323,74 @@ int diff_tree(struct tree_desc *t1, struct\ntree_desc *t2, const char *base, stru\n }\n\n /*\n- * Does it look like the resulting diff might be due to a rename?\n- *  - single entry\n- *  - not a valid previous file\n+ * Does it look like the resulting diff might be due to a rename? If we have\n+ * any files that appeared, then maybe.\n  */\n static inline int diff_might_be_rename(void)\n {\n-\treturn diff_queued_diff.nr == 1 &&\n-\t\t!DIFF_FILE_VALID(diff_queued_diff.queue[0]->one);\n+\tint i;\n+\tfor (i = 0; i < diff_queued_diff.nr; i++)\n+\t\tif (!DIFF_FILE_VALID(diff_queued_diff.queue[i]->one))\n+\t\t\treturn 1;\n+\treturn 0;\n }\n\n static void try_to_follow_renames(struct tree_desc *t1, struct\ntree_desc *t2, const char *base, struct diff_options *opt)\n {\n \tstruct diff_options diff_opts;\n+\tstruct diff_queue_struct outq;\n \tstruct diff_queue_struct *q = &diff_queued_diff;\n-\tstruct diff_filepair *choice;\n-\tconst char *paths[1];\n+\tconst char **new_paths;\n+\tint new_paths_num, new_paths_alloc;\n \tint i;\n\n-\t/* Remove the file creation entry from the diff queue, and remember it */\n-\tchoice = q->queue[0];\n+\tDIFF_QUEUE_CLEAR(&outq);\n \tq->nr = 0;\n\n \tdiff_setup(&diff_opts);\n \tDIFF_OPT_SET(&diff_opts, RECURSIVE);\n \tDIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);\n \tdiff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;\n-\tdiff_opts.single_follow = opt->paths[0];\n \tdiff_opts.break_opt = opt->break_opt;\n-\tpaths[0] = NULL;\n-\tdiff_tree_setup_paths(paths, &diff_opts);\n \tif (diff_setup_done(&diff_opts) < 0)\n \t\tdie(\"unable to set up diff options to follow renames\");\n \tdiff_tree(t1, t2, base, &diff_opts);\n \tdiffcore_std(&diff_opts);\n-\tdiff_tree_release_paths(&diff_opts);\n\n-\t/* Go through the new set of filepairing, and see if we find a more\ninteresting one */\n+\tnew_paths_num = new_paths_alloc = opt->nr_paths;\n+\tnew_paths = xmalloc(opt->nr_paths * sizeof(*new_paths));\n+\tfor (i = 0; i < opt->nr_paths; i++)\n+\t\tnew_paths[i] = opt->paths[i];\n+\n+\t/* Go through the new set of filepairs, looking for renames. */\n \tfor (i = 0; i < q->nr; i++) {\n \t\tstruct diff_filepair *p = q->queue[i];\n\n-\t\t/*\n-\t\t * Found a source? Not only do we use that for the new\n-\t\t * diff_queued_diff, we will also use that as the path in\n-\t\t * the future!\n-\t\t */\n-\t\tif ((p->status == 'R' || p->status == 'C') && !strcmp(p->two->path,\nopt->paths[0])) {\n-\t\t\t/* Switch the file-pairs around */\n-\t\t\tq->queue[i] = choice;\n-\t\t\tchoice = p;\n-\n-\t\t\t/* Update the path we use from now on.. */\n-\t\t\tdiff_tree_release_paths(opt);\n-\t\t\topt->paths[0] = xstrdup(p->one->path);\n-\t\t\tdiff_tree_setup_paths(opt->paths, opt);\n-\t\t\tbreak;\n-\t\t}\n-\t}\n+\t\t/* XXX actually this is the slightly different wildcarding\n+\t\t * pathspec. We really want to check just prefixes. But\n+\t\t * I wonder if we can convince the diff machinery to just\n+\t\t * be interested in these paths as destinations, but use\n+\t\t * the whole tree as sources */\n+\t\tif (!match_pathspec(opt->paths, p->two->path,\n+\t\t\t\t   strlen(p->two->path), 0, NULL))\n+\t\t\tcontinue;\n\n-\t/*\n-\t * Then, discard all the non-relevant file pairs...\n-\t */\n-\tfor (i = 0; i < q->nr; i++) {\n-\t\tstruct diff_filepair *p = q->queue[i];\n-\t\tdiff_free_filepair(p);\n+\t\tdiff_q(&outq, p);\n+\n+\t\tALLOC_GROW(new_paths, new_paths_num + 1, new_paths_alloc);\n+\t\tnew_paths[new_paths_num++] = xstrdup(p->one->path);\n \t}\n\n-\t/*\n-\t * .. and re-instate the one we want (which might be either the\n-\t * original one, or the rename/copy we found)\n-\t */\n-\tq->queue[0] = choice;\n-\tq->nr = 1;\n+\t/* now finalize the new paths */\n+\tALLOC_GROW(new_paths, new_paths_num + 1, new_paths_alloc);\n+\tnew_paths[new_paths_num] = NULL;\n+\tdiff_tree_release_paths(opt);\n+\tdiff_tree_setup_paths(new_paths, opt);\n+\n+\t/* and restore our old queue */\n+\tfree(q->queue);\n+\t*q = outq;\n+\tDIFF_QUEUE_MARK_RUN(q, 1);\n }\n\n int diff_tree_sha1(const unsigned char *old, const unsigned char\n*new, const char *base, struct diff_options *opt)\n\n\nRegards!\nBo\n-- \nMy blog: http://blog.morebits.org\n"},{"id":"141560","messageId":"19435.33415.163892.762639@winooski.ccs.neu.edu","threadId":"23732","inReplyTo":"AANLkTilES9d8rj5Zwfju7t3H7cjM7h9HWL8YprcxPc6t@mail.gmail.com","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Eli Barzilay","fromEmail":"eli@barzilay.org","sentAt":"2010-05-13T04:39:35Z","receivedAt":"2010-05-13T04:39:35Z","isPatch":false,"sender":{"key":"eli@barzilay.org","avatar":"https://avatars.githubusercontent.com/u/185905?v=4"},"body":"On May 13, Bo Yang wrote:\n> \n> Ah, sorry. I just copy the patch from my putty window, so it convert\n> all tabs into spaces...  And the following change this. Also, I have\n> run a 'make test', seems there is no problem for it. Happy try it!\n\nThere are still a few lines that got wrapped -- after I fixed them I\ncould apply it, and it looks like it works as (I) expected with and\nwithout `-p'.  (I didn't try to measure the speed though -- it was\nperfectly fine for any interactive use that I'd want to use it for.)\n\n-- \n          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:\n                    http://barzilay.org/                   Maze is Life!\n"},{"id":"141631","messageId":"20100514045522.GE6075@coredump.intra.peff.net","threadId":"23732","inReplyTo":"19434.48308.815673.263230@winooski.ccs.neu.edu","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-14T04:55:22Z","receivedAt":"2010-05-14T04:55:22Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, May 12, 2010 at 10:35:32AM -0400, Eli Barzilay wrote:\n\n> But with `-p' it was doing something confusing: I used two files that\n> were recently renamed, and the result was the correct log history, but\n> the first patch that was shown (the rename) showed the two files as\n> added.  (That's even when I added `-C' and `-M'.)  This happens even\n> with a single path.  OTOH, using `--follow' with `-p' and a single\n> path without your patch produces the expected result where the first\n> patch is a rename (even without `-C'/`-M').\n\nAh, yeah, I see. The problem is that my code is doing something like:\n\n  1. Do a sha1-only diff with our current path list.\n\n  2. If there were any created files, they might be renames.\n     Put aside the old diff results. Do a new diff, looking for renames.\n\n  3. If there are renames, add them to our path list.\n\n  4. Restore the old diff results.\n\n  5. Proceed with other desired diff options (rename detection, showing\n     patches, etc).\n\nBut the during step (5), remember that we are still working with the old\ndiff results, which will not include the expanded path. Thus we won't\nconsider the new path as a rename source, and will fail to find the\nrename.\n\nThe naive right way would be to re-do step (1) with the expanded path.\nBut there is an optimization, since we can use the diff results from (2)\ndirectly, including avoiding re-doing the rename detection.\n\nThe only \"downside\" is that it means --follow actually impacts the diff\ngeneration by implying --find-copies-harder. And I put downside in\nquotes because it is probably not a big deal. We have already spent the\nCPU time to find the answer, so it is silly not to show it. I can't\nimagine why somebody would want --follow, but would _not_ want rename\ndetection in the resulting diff.\n\nBo's version of the patch does that optimization. When I clean up the\npatch (probably sometime next week), I'll take those changes.\n\n-Peff\n"},{"id":"141633","messageId":"19436.55814.552536.42519@winooski.ccs.neu.edu","threadId":"23732","inReplyTo":"20100514045522.GE6075@coredump.intra.peff.net","subject":"Re: Re: git log -M -- filename is not working?","fromName":"Eli Barzilay","fromEmail":"eli@barzilay.org","sentAt":"2010-05-14T05:05:10Z","receivedAt":"2010-05-14T05:05:10Z","isPatch":false,"sender":{"key":"eli@barzilay.org","avatar":"https://avatars.githubusercontent.com/u/185905?v=4"},"body":"On May 14, Jeff King wrote:\n> [...]\n\n(I didn't get most of that...)\n\n> The only \"downside\" is that it means --follow actually impacts the diff\n> generation by implying --find-copies-harder. And I put downside in\n> quotes because it is probably not a big deal. We have already spent the\n> CPU time to find the answer, so it is silly not to show it. I can't\n> imagine why somebody would want --follow, but would _not_ want rename\n> detection in the resulting diff.\n\n...but this seems very reasonable.  (In fact, if --follow implies\nfinding copies and renames, and if it's doing that for diff too, then\nit's exactly what I originally wanted.)\n\n\n> Bo's version of the patch does that optimization. When I clean up the\n> patch (probably sometime next week), I'll take those changes.\n\nThanks!\n\n-- \n          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:\n                    http://barzilay.org/                   Maze is Life!\n"}]}