{"thread":{"id":"6059","subject":"Re: Updated Kernel Hacker's guide to git","startedAt":"2006-12-21T12:24:32Z","lastAt":"2006-12-22T23:31:09Z","messageCount":12,"participants":["Francis Moreau","Linus Torvalds","Carl Worth","Junio C Hamano","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"29943","messageId":"38b2ab8a0612210424o4ec5fcd5kb5086c52ccd76491@mail.gmail.com","threadId":"6059","inReplyTo":null,"subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Francis Moreau","fromEmail":"francis.moro@gmail.com","sentAt":"2006-12-21T12:24:32Z","receivedAt":"2006-12-21T12:24:32Z","isPatch":false,"sender":{"key":"francis.moro@gmail.com","avatar":null},"body":"Hi,\n\n[ sorry for breaking up the thread but I'd like to fully\n  understand that point and I just subscribed to git mail\n  list... ]\n\nLinus Torvalds wrote:\n>\n> On Wed, 20 Dec 2006, Jay Cliburn wrote:\n>> $ git diff $(git merge-base master driver)..driver\n>\n> Be careful. This ONLY works if you don't have criss-cross merges etc, so\n> you need to be somewhat careful about it. If you end up having a complex\n> merge history between the origin branch and your development tree, things\n> will stop working\n>\n> So it's actually worth understanding what the above does.\n>\n> Here's the picture to keep in mind: you started off with something like\n> this:\n>\n> \t<- older\t\t\tnewer ->\n>\n> \t..--A---B---C---D\n>\n> where the top commit was D, and you started doing your own work off there.\n> However, the tree you are tracking (doing \"git fetch origin\" or somethng)\n> ALSO continues, so soon enough you'll have a history that looks like\n>\n> \t<- older\t\t\tnewer ->\n>\n> \t..--A---B---C---D---E---F---G---H <-\"origin\"\n> \t                 \\\n> \t                  --X---Y---Z <- your \"driver\" branch\"\n>\n> where your work is the \"X-Y-Z\" sequence.\n>\n> How, the reason you must NOT do\n>\n> \tgit diff origin..driver\n>\n> or something like that, is that it will LITERALLY do a diff between those\n> two heads. And while that is a perfectly normal diff, it's not what you\n> want: it's the diff between the up-stream work and yours, and it will show\n> that a lot of work has _not_ happened in your branch (all the E-F-G-H\n> stuff), and then you've added some work (X-Y-Z).\n\nI must really miss something but is a diff between origin and driver heads\nachieved by:\n\n\t$ git diff driver origin\n\ninstead of:\n\n\t$ git diff origin..driver\n\n?\n\n>From the git-rev-list documentation I can read that:\n\n\tgit-rev-list origin..driver == git-rev-list driver ^origin\n\nI assume it's still true for git-diff. And the documentation says that\nthe above command \"lists all the commits which are included in driver,\nbut not in origin\".\n\nSo all commits included in driver are: (A-B-C-D-X-Y-Z)\nall commits included in origin are: (A-B-C-D-E-F-G-H)\n\nAll the commits which are included in driver, but not in origin are:\n(X-Y-Z), which is definitely not what you claimed.\n\nI know that I'm wrong, so please shed some light in my stupid brain.\n\n-- \nFrancis\n"},{"id":"29961","messageId":"Pine.LNX.4.64.0612211013500.3394@woody.osdl.org","threadId":"6059","inReplyTo":"38b2ab8a0612210424o4ec5fcd5kb5086c52ccd76491@mail.gmail.com","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-12-21T18:23:30Z","receivedAt":"2006-12-21T18:23:30Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Dec 2006, Francis Moreau wrote:\n> \n> I must really miss something but is a diff between origin and driver heads\n> achieved by:\n> \n> \t$ git diff driver origin\n> \n> instead of:\n> \n> \t$ git diff origin..driver\n\nNo. \n\n\tgit diff origin driver\n\nand\n\n\tgit diff origin..driver\n\nis exactly the same thing.\n\n> From the git-rev-list documentation I can read that:\n> \n> \tgit-rev-list origin..driver == git-rev-list driver ^origin\n\nCorrect. However, \"git diff\" is very aware of things like \"^origin\", and \nunderstands that\n\n\tgit diff driver ^origin\n\nis the same thing as saying \"I want what is in driver, but not in origin\", \nso it needs to switch the arguments.\n\nIn short, for git diff (and ONLY) git diff, all of these are the same:\n\n\tgit diff a..b\n\tgit diff a b\n\tgit diff b ^a\n\n[ ADDITIONALLY git diff _also_ has a magic special case of\n\n\tgit diff a b ^c\n\n  which actually means the same as \"git diff c..a\" (and \"b\" is \n  totally ignored). That may sound strange, but it's because the \n  expression \"a...b\" means \"b a --not $(git-merge-base a b)\", and so what \n  you actually WANT is that if you do\n\n\tgit diff a...b\n\n  you should get \"diff from merge-base to b\", so when \"a...b\" expands to \n  \"b a ^merge-base\", then git understands that if it gets that stange \n  command line with THREE commits, and one of them is negated, you really \n  wanted the diff from the negated one to the first one ]\n\nIt basically all boils down to:\n\n\t\"git diff\" is special\n\nexactly because unlike almost ALL other git commands, \"git diff\" does not \nwork on a _list_ of commits, it only works on two end-points. That means \nthat the \"list operations\" actually end up meaning something else for git \ndiff than they do for \"git log\" and friends.\n\n\t\tLinus\n"},{"id":"29995","messageId":"87slf83erg.wl%cworth@cworth.org","threadId":"6059","inReplyTo":"Pine.LNX.4.64.0612211013500.3394@woody.osdl.org","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-12-22T01:23:15Z","receivedAt":"2006-12-22T01:23:15Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Thu, 21 Dec 2006 10:23:30 -0800 (PST), Linus Torvalds wrote:\n> In short, for git diff (and ONLY) git diff, all of these are the same:\n>\n> \tgit diff a..b\n> \tgit diff a b\n\nI admit that I had had never passed a range of commits to git diff,\nnor even given any thought to what it might do, but I definitely find\nthe above very surprising---and not necessarily very useful. Why is\nanyone ever typing those two dots here if they have no effect on the\nresult?\n\n> It basically all boils down to:\n>\n> \t\"git diff\" is special\n>\n> exactly because unlike almost ALL other git commands, \"git diff\" does not\n> work on a _list_ of commits, it only works on two end-points. That means\n> that the \"list operations\" actually end up meaning something else for git\n> diff than they do for \"git log\" and friends.\n\nYes, \"git diff\" can only work on two end points. So a command like:\n\n\tgit diff a b\n\nis really easy to understand. And if the user wants to compare those\ntwo points, why would the user ever provide them with any other\nsyntax?\n\nIn other words, what's the advantage of \"git diff\" accepting a special\nsyntax for a range (\"a..b\") and yet not actually doing anything\nspecial with it?\n\nIn particular, the operation that would be interesting here is what\none can get with:\n\n\tgit diff $(git merge-base a b) b\n\nso why isn't _that_ the operation that is accessed with the syntax of:\n\n\tgit diff a..b\n\nSaid another way, if \"git log a..b\" displays a range of commits, why\ndoesn't \"git diff a..b\" display the diff from the beginning of that\nrange to the end?\n\nOf course, all the warnings you gave about what \"git diff\" would do\nin the case of various criss-cross merge scenarios would still apply.\n\n-Carl\n"},{"id":"30008","messageId":"Pine.LNX.4.64.0612212009370.3536@woody.osdl.org","threadId":"6059","inReplyTo":"87slf83erg.wl%cworth@cworth.org","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-12-22T04:13:52Z","receivedAt":"2006-12-22T04:13:52Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Dec 2006, Carl Worth wrote:\n>\n> On Thu, 21 Dec 2006 10:23:30 -0800 (PST), Linus Torvalds wrote:\n> > In short, for git diff (and ONLY) git diff, all of these are the same:\n> >\n> > \tgit diff a..b\n> > \tgit diff a b\n> \n> I admit that I had had never passed a range of commits to git diff,\n> nor even given any thought to what it might do, but I definitely find\n> the above very surprising---and not necessarily very useful. Why is\n> anyone ever typing those two dots here if they have no effect on the\n> result?\n\nI do it all the time, I never even use the old-fashioned syntax any more. \nIt's much more concise and easy to read, and it has all the nice shortcuts \n(like empty meaning \"HEAD\", so you can do \"git diff ..next\" to see the \ndiff from HEAD to another branch).\n\nIt's also useful exactly because of the semantics of things like \"...\".\n\nIn other words, sure, \"git diff a b\" works, but it just _looks_ more \npleasing to use \"a..b\" and you mentally always pronounce the \"..\" as \"to\".\n\nSo \"git diff a b\" doesn't even look good to me any more, because it's \nliterally missing that mental \"to\" that the \"..\" adds for me when I read \nit.\n\n\t\tLinus\n"},{"id":"30036","messageId":"38b2ab8a0612220135p6925be4cmf003811f616395ba@mail.gmail.com","threadId":"6059","inReplyTo":"Pine.LNX.4.64.0612211013500.3394@woody.osdl.org","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Francis Moreau","fromEmail":"francis.moro@gmail.com","sentAt":"2006-12-22T09:35:47Z","receivedAt":"2006-12-22T09:35:47Z","isPatch":false,"sender":{"key":"francis.moro@gmail.com","avatar":null},"body":"Linus Torvalds wrote:\n>\n> In short, for git diff (and ONLY) git diff, all of these are the same:\n>\n> \tgit diff a..b\n> \tgit diff a b\n> \tgit diff b ^a\n>\n\nI think this part is really confusing. For a new comer, saying that:\n\n\tgit diff a b == git diff a..b\n\nis really not intuitive. Maybe just because adding a new symbol \"..\"\nin git diff command line means (for me) that we're doing a special\ndiff. I would never thought by my own that \"..\" means a simple \"to\".\n\n> [ ADDITIONALLY git diff _also_ has a magic special case of\n>\n> \tgit diff a b ^c\n>\n>   which actually means the same as \"git diff c..a\" (and \"b\" is\n>   totally ignored). That may sound strange, but it's because the\n>   expression \"a...b\" means \"b a --not $(git-merge-base a b)\", and so what\n>   you actually WANT is that if you do\n>\n> \tgit diff a...b\n>\n>   you should get \"diff from merge-base to b\", so when \"a...b\" expands to\n>   \"b a ^merge-base\", then git understands that if it gets that stange\n>   command line with THREE commits, and one of them is negated, you really\n>   wanted the diff from the negated one to the first one ]\n>\n> It basically all boils down to:\n>\n> \t\"git diff\" is special\n>\n\nbut this very special part of git diff is also not documented at all\nwhen reading the manual of git-diff... Maybe it can be reached by\nothers manuals ?\n\n> exactly because unlike almost ALL other git commands, \"git diff\" does not\n> work on a _list_ of commits, it only works on two end-points. That means\n> that the \"list operations\" actually end up meaning something else for git\n> diff than they do for \"git log\" and friends.\n>\n\nI think I got your point now: git-diff only works on two end-points.\n\n\nWhy not making it less special as follow:\n\n\tgit diff a b\n\tgit diff b ^a\n\nThese two diff commands are the same. They do a diff between a and b\nend-points (maybe commits is better there since we don't add one more\nkeyword). It's similar to diff command. For me it's quite intuitive.\n\n\tgit diff a..b\n\nOk now the command syntax is more special (maybe simply because\ntraditional diff() does not have a similar syntax, it's really\nspecific to git). \"git log\" and friends have a similar syntax and they\ndo work on a list of commits. For consistency sake, make this commad\nworks on commit list too. Therefore this command would end up doing\nexactly the same thing like \"git diff a...b\"\n\n\tgit diff a...b\n\nNo more need of this special syntax.\n\n\nWhat do you think ?\n\nthanks\n-- \nFrancis\n"},{"id":"30040","messageId":"7vvek41b29.fsf@assigned-by-dhcp.cox.net","threadId":"6059","inReplyTo":"38b2ab8a0612220135p6925be4cmf003811f616395ba@mail.gmail.com","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-22T10:26:06Z","receivedAt":"2006-12-22T10:26:06Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Francis Moreau\" <francis.moro@gmail.com> writes:\n\n> I think this part is really confusing. For a new comer, saying that:\n>\n> \tgit diff a b == git diff a..b\n>\n> is really not intuitive. Maybe just because adding a new symbol \"..\"\n> in git diff command line means (for me) that we're doing a special\n> diff. I would never thought by my own that \"..\" means a simple \"to\".\n\nWe did not originally have \"A B\"; you were supposed to always\nsay \"A..B\".  But all other SCM had \"A B\" notation, so we added\nsupport for both because doing so was trivial and there is no\nrisk of confusion (because diff is about two points while log is\nabout a set).  These two notations are interchangeable for\n\"diff\".  If it confuses you, you can stick to the \"git diff A B\"\nnotation.  Of if you are like Linus, stick to \"A..B\" notation.\nEither way, you can pretend that the other notation does not\neven exist and be happy ;-).\n\nYes, users often wondered why \"git diff\" accepts \"A B\", \"git\nlog\" wants \"A..B\" and \"git log A B\" is a disaster.  But the root\ncause of the confusion was not about notation but about the\nconceptual difference (two points vs a set).\n\nI do not think changing the meaning of \"diff A..B\" to what \"diff\nA...B\" means is a good thing.  The notation \"...\" even _looks_\nlike a magic, and in diff context, what it does _is_ magic (it\nis magic in log context, too).  You are giving two points, but\nwhat actually is used as the two points for diff are different\nfrom what you gave; in that sense, it is a very good notation.\nChanging it would confuse and inconvenience people who already\nunderstood and got used to the difference between \"diff\" and\n\"log\": diff takes two points, so given usual A..B notation it\nuses A and B, while log is about a set and means 'the ones\nreachable from B, excluding the ones reachable from A'; \"A...B\"\nis magic and does a magical thing in both \"diff\" and \"log\",\ntaking the merge bases between A and B into account.\n"},{"id":"30093","messageId":"38b2ab8a0612221234x3832c5bfr1f64caccbb8247b9@mail.gmail.com","threadId":"6059","inReplyTo":"7vvek41b29.fsf@assigned-by-dhcp.cox.net","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Francis Moreau","fromEmail":"francis.moro@gmail.com","sentAt":"2006-12-22T20:34:50Z","receivedAt":"2006-12-22T20:34:50Z","isPatch":false,"sender":{"key":"francis.moro@gmail.com","avatar":null},"body":"On 12/22/06, Junio C Hamano <junkio@cox.net> wrote:\n> \"Francis Moreau\" <francis.moro@gmail.com> writes:\n>\n> > I think this part is really confusing. For a new comer, saying that:\n> >\n> >       git diff a b == git diff a..b\n> >\n> > is really not intuitive. Maybe just because adding a new symbol \"..\"\n> > in git diff command line means (for me) that we're doing a special\n> > diff. I would never thought by my own that \"..\" means a simple \"to\".\n>\n> We did not originally have \"A B\"; you were supposed to always\n> say \"A..B\".  But all other SCM had \"A B\" notation, so we added\n> support for both because doing so was trivial and there is no\n> risk of confusion (because diff is about two points while log is\n> about a set).  These two notations are interchangeable for\n> \"diff\".  If it confuses you, you can stick to the \"git diff A B\"\n> notation.  Of if you are like Linus, stick to \"A..B\" notation.\n> Either way, you can pretend that the other notation does not\n> even exist and be happy ;-).\n>\n\nno, no, I think you miss my point here. What is confusing, and it\nseems I'm not the only one to find it confusing,  is the fact that\n\"git diff A B == git diff A..B\", not the \"A..B\" notation per se.\n\ngit diff A B, is really intuitive and easy to understand because we\nall use to using the diff \"A B\" notation and it always has worked with\n2 endpoints. So I would bet that all newbies who use for the first\ntime the git diff command will use \"A B\" notation, not \"A..B\" one.\n\n> Yes, users often wondered why \"git diff\" accepts \"A B\", \"git\n> log\" wants \"A..B\" and \"git log A B\" is a disaster.  But the root\n> cause of the confusion was not about notation but about the\n> conceptual difference (two points vs a set).\n>\n> I do not think changing the meaning of \"diff A..B\" to what \"diff\n> A...B\" means is a good thing.  The notation \"...\" even _looks_\n> like a magic, and in diff context, what it does _is_ magic (it\n> is magic in log context, too).  You are giving two points, but\n\nBut \"..\" is magic too ! I would really expect something magic to\nhappen when using the \"A..B\" notation because I'm a new comer in git\nand I never used the \"A..B\" notation before.\n\nAnd since I already used this notation when using git log command, I\nwould expect \"git diff A..B\" to give the current result given by \"git\ndiff A...B\".\n\nBut yes, now I have understand that git diff works with end points\nunlike git log, I can stick with two notations:\n\n        git diff A B\n        git diff A...B (3 dots)\n\nand I'm happy ;)\n\nthanks\n-- \nFrancis\n"},{"id":"30118","messageId":"877iwjinda.wl%cworth@cworth.org","threadId":"6059","inReplyTo":"Pine.LNX.4.64.0612212009370.3536@woody.osdl.org","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-12-22T22:20:33Z","receivedAt":"2006-12-22T22:20:33Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Thu, 21 Dec 2006 20:13:52 -0800 (PST), Linus Torvalds wrote:\n> I do it all the time, I never even use the old-fashioned syntax any more.\n> It's much more concise and easy to read, and it has all the nice shortcuts\n> (like empty meaning \"HEAD\", so you can do \"git diff ..next\" to see the\n> diff from HEAD to another branch).\n\nI can understand the advantage of a shortcut like \"git diff ..next\",\nbut I still don't understand why it's the comparison of HEAD and next\nthat's really interesting here. Wouldn't comparing the merge-base to\nnext be more desirable? For example, if I'm considering whether to\nmerge in next or not, why should I care to see in the diff all the\nirrelevant stuff that's happened on HEAD since next branched off?\n\nBut, really, I still don't understand exactly _what_ \"diff a..b\" even\nmeans. Can you explain it to me?\n\nPresumably the rev-parse magic is happening to the arguments. So does\nthe diff code just end up seeing the expanded equivalent of \"b ^a\" and\nthen just use the ^ to decide which tree to be on the left side or\nsomething?\n\n> It's also useful exactly because of the semantics of things like \"...\".\n\nAnd now I'm really confused. If I'm not mistaken, rev-parse will turn\n\"a...b\" into something like \"a b ^$(merge-base a b)\", right? So does\nthe diff code now end up seeing three different tree specifiers? What\ndoes it do with that? And how is this useful? (As you said before,\ndiff is always going to end up acting on only two items, so I don't\nsee where there could be an interesting distinction from how you\nobtain two items from \"a..b\" compared to \"a...b\".) But it might be\njust that I'm really confused here.\n\n> So \"git diff a b\" doesn't even look good to me any more, because it's\n> literally missing that mental \"to\" that the \"..\" adds for me when I read\n> it.\n\nOK, that's fine. But can you comment on why you want the comparison\nbetween the tips and not something based on a comparison from the\nmerge-base to a tip?\n\n-Carl\n"},{"id":"30120","messageId":"Pine.LNX.4.64.0612221432430.3671@woody.osdl.org","threadId":"6059","inReplyTo":"877iwjinda.wl%cworth@cworth.org","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-12-22T22:34:18Z","receivedAt":"2006-12-22T22:34:18Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 22 Dec 2006, Carl Worth wrote:\n> \n> I can understand the advantage of a shortcut like \"git diff ..next\",\n> but I still don't understand why it's the comparison of HEAD and next\n> that's really interesting here.\n\nI can't understand why people complain about this.\n\nYOU DON'T HAVE TO USE IT. \n\nNobvody forces you. Really. And dammit, if I want to compare HEAD and \nnext, I compare HEAD and next. You have absolutely no business saying that \nyou don't understand why I'd want to do it. It's MY LIFE.\n\n> But, really, I still don't understand exactly _what_ \"diff a..b\" even\n> means. Can you explain it to me?\n\nIt means exactly the same as \"diff a b\".\n\nIt's that simple.\n\nSo now go away. Stop complaining.\n\n\t\tLinus\n"},{"id":"30123","messageId":"7v7iwjwnwh.fsf@assigned-by-dhcp.cox.net","threadId":"6059","inReplyTo":"877iwjinda.wl%cworth@cworth.org","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-22T22:45:18Z","receivedAt":"2006-12-22T22:45:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n> On Thu, 21 Dec 2006 20:13:52 -0800 (PST), Linus Torvalds wrote:\n>> I do it all the time, I never even use the old-fashioned syntax any more.\n>> It's much more concise and easy to read, and it has all the nice shortcuts\n>> (like empty meaning \"HEAD\", so you can do \"git diff ..next\" to see the\n>> diff from HEAD to another branch).\n>\n> I can understand the advantage of a shortcut like \"git diff ..next\",\n> but I still don't understand why it's the comparison of HEAD and next\n> that's really interesting here. Wouldn't comparing the merge-base to\n> next be more desirable?\n\n\"git diff ...next\" should work just as well, I think.\n\n> But, really, I still don't understand exactly _what_ \"diff a..b\" even\n> means. Can you explain it to me?\n\ndiff between two points.\n\n> Presumably the rev-parse magic is happening to the arguments. So does\n> the diff code just end up seeing the expanded equivalent of \"b ^a\" and\n> then just use the ^ to decide which tree to be on the left side or\n> something?\n\nExactly; diff just reuses the non-magic part of revision\nparameter parsing without using the ancestry traversal\nmachinery (which is the magic part).\n\n>> It's also useful exactly because of the semantics of things like \"...\".\n>\n> And now I'm really confused. If I'm not mistaken, rev-parse will turn\n> \"a...b\" into something like \"a b ^$(merge-base a b)\", right? So does\n> the diff code now end up seeing three different tree specifiers? What\n> does it do with that?\n\nIt knows that rev-parse makes it \"b a ^base\", and it knows what\nthe user meant is \"base..b\".\n\nThat's all because we teach them to spell \"a...b\" when they want\n\"base..b\".  Similarly, because we allow them to spell \"a..b\"\nwhen they mean \"between two points, a and b\", it handles \"b ^a\"\nas the equivalent to giving two trees separately, as \"a b\".\n\n> And how is this useful? (As you said before,\n> diff is always going to end up acting on only two items, so I don't\n> see where there could be an interesting distinction from how you\n> obtain two items from \"a..b\" compared to \"a...b\".) But it might be\n> just that I'm really confused here.\n\nI do not think you are seriously saying that comparing A and\nB in this picture is meaningless:\n\n      o---o---B\n     /\n ---M---o---A\n\nYes, it is often useful to compare M and B, but that \"often\" is\nlimited to the phase of the workflow where you are at A and are\ncontemplating of merging B.  But merging two forked branches is\nnot the only thing you do.\n\nComparing two revisions regardless of how they are topologically\nrelated is useful as often.  It is only that it may not as\nuseful while you are trying to merge B into A.\n\nSo there are two ways to let you do both, and they need to be\nspecified differently (.. vs ...)  because you need to tell it\nto do which one.\n"},{"id":"30125","messageId":"emhnsm$iuo$1@sea.gmane.org","threadId":"6059","inReplyTo":"877iwjinda.wl%cworth@cworth.org","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-12-22T23:00:12Z","receivedAt":"2006-12-22T23:00:12Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"[Cc: Carl Worth <cworth@cworth.org>, Linus Torvalds <torvalds@osdl.org>\n git@vger.kernel.org]\n\nCarl Worth wrote:\n\n> On Thu, 21 Dec 2006 20:13:52 -0800 (PST), Linus Torvalds wrote:\n>> I do it all the time, I never even use the old-fashioned syntax any more.\n>> It's much more concise and easy to read, and it has all the nice shortcuts\n>> (like empty meaning \"HEAD\", so you can do \"git diff ..next\" to see the\n>> diff from HEAD to another branch).\n> \n> I can understand the advantage of a shortcut like \"git diff ..next\",\n> but I still don't understand why it's the comparison of HEAD and next\n> that's really interesting here. Wouldn't comparing the merge-base to\n> next be more desirable? For example, if I'm considering whether to\n> merge in next or not, why should I care to see in the diff all the\n> irrelevant stuff that's happened on HEAD since next branched off?\n> \n> But, really, I still don't understand exactly _what_ \"diff a..b\" even\n> means. Can you explain it to me?\n\nFor me, it's just a bit of syntactic sugar (I always have in mind that\ngit-log and friends outputs commit list and use revisions range, while\ngit-diff and friends needs two (or less) revisions) allowing to\ncopy'n'paste arguments from \"git log a..b\" to \"git diff a..b\"\n \n> Presumably the rev-parse magic is happening to the arguments. So does\n> the diff code just end up seeing the expanded equivalent of \"b ^a\" and\n> then just use the ^ to decide which tree to be on the left side or\n> something?\n\nAnd that is just implementation. I don't think anyone uses \"git diff b ^a\".\n\n>> It's also useful exactly because of the semantics of things like \"...\".\n> \n> And now I'm really confused. If I'm not mistaken, rev-parse will turn\n> \"a...b\" into something like \"a b ^$(merge-base a b)\", right? So does\n> the diff code now end up seeing three different tree specifiers? What\n> does it do with that? And how is this useful? (As you said before,\n> diff is always going to end up acting on only two items, so I don't\n> see where there could be an interesting distinction from how you\n> obtain two items from \"a..b\" compared to \"a...b\".) But it might be\n> just that I'm really confused here.\n\nI would have thought that it would be combined diff of a and b against\nit's merge base... but it is not.\n\n\"git diff a...b\" is turned into \"git diff a b ^$(git merge-base a b)\",\nand by a bit of magic (and by a convention) it is turned into\n\"git diff ^$(merge-base a b) a\" (and a...b ceases to be _symmetric_\nfor git-diff).\n\nI'd like for \"git diff --cc a...b\" to do 'the right thing' and show\ngit diff --cc for pretended merge (I'm not sure if with or without\nresolving trivial conflicts).\n\n>> So \"git diff a b\" doesn't even look good to me any more, because it's\n>> literally missing that mental \"to\" that the \"..\" adds for me when I read\n>> it.\n> \n> OK, that's fine. But can you comment on why you want the comparison\n> between the tips and not something based on a comparison from the\n> merge-base to a tip?\n\na..b does not imply merge-base, a...b does.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"30127","messageId":"8764c3ik3m.wl%cworth@cworth.org","threadId":"6059","inReplyTo":"7v7iwjwnwh.fsf@assigned-by-dhcp.cox.net","subject":"Re: Updated Kernel Hacker's guide to git","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-12-22T23:31:09Z","receivedAt":"2006-12-22T23:31:09Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Fri, 22 Dec 2006 14:45:18 -0800, Junio C Hamano wrote:\n> Exactly; diff just reuses the non-magic part of revision\n> parameter parsing without using the ancestry traversal\n> machinery (which is the magic part).\n\nThanks, that helps.\n\n> It knows that rev-parse makes it \"b a ^base\", and it knows what\n> the user meant is \"base..b\".\n\nAhah! So the \"a...b\" syntax is how to get at what:\n\n\tgit diff $(git merge-base a b) b\n\nwould give. Thanks for explaining, since that was not at all obvious.\n\n> That's all because we teach them to spell \"a...b\" when they want\n> \"base..b\".  Similarly, because we allow them to spell \"a..b\"\n> when they mean \"between two points, a and b\", it handles \"b ^a\"\n> as the equivalent to giving two trees separately, as \"a b\".\n\nWhere is that teaching happening exactly? Both the \"a..b\" and \"a...b\"\nforms seem to be entirely missing from the documentation of git\ndiff. :-)\n\n> I do not think you are seriously saying that comparing A and\n> B in this picture is meaningless:\n>\n>       o---o---B\n>      /\n>  ---M---o---A\n\nNo, I'm certainly not saying that that that comparison is meaningless.\n\nAll I was trying to say is that comparing M to B would be meaningful\ntoo, and I hoped that git would provide good syntax for both. If I'm\nunderstanding things correctly now, what exists is:\n\n  git diff A B\n  git diff A..B\n\n\tCompare A to B\n\n  git diff A...B\n\n\tCompare M to B\n\nSo, at the beginning of this thread I wasn't aware that git provided\nany short syntax for the \"M to B\" comparison, (the thread started with\nsuggestions for adding \"git diff $(git merge-base A B) B\" to the\nhackers guide).\n\nNow, I'm happy to know that git does provide a short syntax for that\nuseful operation.\n\nMy only comment now is that the distinction between \"..\" and \"...\" in\ngit-diff is quite surprising. In fact, in one sense it's exactly\nopposite from the distinction of \"..\" and \"...\" as used in git log.\n\nFor example, given the above graph, \"git diff A..B\" shows changes due\nto all 5 of commits on both branches while \"git log -p A..B\" shows\nonly the changes of the 3 commits from M to B.\n\nMeanwhile, \"git diff A...B\" shows changes due to the 3 commits from M\nto B while \"git log -p A...B\" shows the changes from all 5 of the\ncommits on both branches.\n\nThat's really surprising behavior (to me at least).\n\n-Carl\n"}]}