{"thread":{"id":"32430","subject":"[RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?","startedAt":"2012-12-21T15:58:27Z","lastAt":"2012-12-21T21:59:44Z","messageCount":7,"participants":["Junio C Hamano","Martin von Zweigbergk","Michael Haggerty"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"205340","messageId":"7v8v8r2y8s.fsf@alter.siamese.dyndns.org","threadId":"32430","inReplyTo":null,"subject":"[RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-12-21T15:58:27Z","receivedAt":"2012-12-21T15:58:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When you want to redo a branch forked from another branch (say\n'master'), a handy way to work is to first detach HEAD at the\nprevious fork point:\n\n    $ git checkout master...branch\n\nand build an updated history on top of this state.  Once you are\ndone, you can verify your results with commands like:\n\n    $ git show-branch branch HEAD\n    $ git diff branch HEAD\n\nand then finish it off with:\n\n    $ git checkout -B branch\n\nThis way, you can keep the history of the previous round on 'branch'\nuntil you are done with the new history you build on the detached\nHEAD state, and if you do not like updated history, you can reset\nback to branch@{1} easily.\n\nBut you may not even need to have such an easy access to the old\nhistory and just want to restart, with:\n\n    $ git checkout -B branch <old fork point>\n\nUnfortunately, master...branch syntax does not seem to work for\nspecifying the \"old fork point\" for this purpose, even though we\nhave special case to support the syntax in the \"detach at that\ncommit\" case (the first command line example in this message).\n\nPerhaps we should teach the <start-point> parser this syntax as\nwell?\n"},{"id":"205345","messageId":"CANiSa6ibS7ORY=QMS3WQzXYJQQH4ZYvPO75qgLgv-oWGMSBBrw@mail.gmail.com","threadId":"32430","inReplyTo":"CANiSa6jP_JN+DpDgYpWA9Aky9REJvFq3aR3Yj0vF3+axWvtmsw@mail.gmail.com","subject":"Fwd: [RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2012-12-21T16:55:43Z","receivedAt":"2012-12-21T16:55:43Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"Oops, meant for all of you.\n\n\n---------- Forwarded message ----------\nFrom: Martin von Zweigbergk <martinvonz@gmail.com>\nDate: Fri, Dec 21, 2012 at 8:45 AM\nSubject: Re: [RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?\nTo: Junio C Hamano <gitster@pobox.com>\n\n\nOn Fri, Dec 21, 2012 at 7:58 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>     $ git checkout -B branch <old fork point>\n>\n> Unfortunately, master...branch syntax does not seem to work for\n> specifying the \"old fork point\" for this purpose\n\nI have personally always found it confusing to use the same syntax for\nspecifying ranges/sets and single revisions. I keep forgetting what\n\"git diff A..B\" does. I know it doesn't do what I expect (i.e. \"git\ndiff $(git merge-base A B) B\"), but I don't know what it does (maybe\nsame as \"git diff A B\" (?), but that's besides the point). Having\nworked a bit on rebase, I know that $onto can also take the \"A...B\"\nform. So there is clearly some precedence for the \"...\" syntax to\nrefer to a revision in some contexts. I would have much preferred if\nit was possible to make the revision parser generally interpret e.g.\n\"A.^.B\" as \"the merge base of A and B\" (failing if not exactly one).\nIt seems like something that must have come up before. Is there a\nparticular reason this would not be a good idea?\n"},{"id":"205351","messageId":"7vr4mj1g8j.fsf@alter.siamese.dyndns.org","threadId":"32430","inReplyTo":"CANiSa6ibS7ORY=QMS3WQzXYJQQH4ZYvPO75qgLgv-oWGMSBBrw@mail.gmail.com","subject":"Re: Fwd: [RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-12-21T17:12:44Z","receivedAt":"2012-12-21T17:12:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Martin von Zweigbergk <martinvonz@gmail.com> writes:\n\n> I keep forgetting what \"git diff A..B\" does.\n\n\"diff\" is always about two endpoints, not the path that connects\nthese two endpoints (aka \"range\"), and when you want to \"diff\"\nbetween two commits, you say \"diff A B\".  \"A..B\" happens to be\naccepted as such only by accident (e.g. the old command line parser\ndid not have a reliable way to tell \"^A B\" and \"A..B\" apart), not by\ndesign.\n\n    side note: incidentally, now we have rev_cmdline_info support,\n    we could start deprecating \"diff A..B\" syntax.\n\nThe special case \"git checkout master...branch\" is not about\nspecifying a range.  The command knows it wants a single point (not\ntwo endpoints, nor a range), and A...B as a notation to specify a\nsingle point is $(merge-base A B).\n\n> I would have much preferred if\n> it was possible to make the revision parser generally interpret e.g.\n> \"A.^.B\" as \"the merge base of A and B\" (failing if not exactly one).\n\nActually, in many places where the command line parser knows it\nwants a single point, and never a range, we should be able to apply\nthe \"A...B as a notation to specify a single point\" rule.  \n\nOf course you could come up with a symbol other than \"...\" for that\npurpose, and migrate the current \"git checkout A...B\" special case\nto use that other symbol, but that would be more work and also you\nwould need to retrain existing users.\n"},{"id":"205369","messageId":"50D4BBDC.6030700@alum.mit.edu","threadId":"32430","inReplyTo":"7vr4mj1g8j.fsf@alter.siamese.dyndns.org","subject":"Re: Fwd: [RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2012-12-21T19:43:24Z","receivedAt":"2012-12-21T19:43:24Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 12/21/2012 06:12 PM, Junio C Hamano wrote:\n> \"diff\" is always about two endpoints, not the path that connects\n> these two endpoints (aka \"range\"), and when you want to \"diff\"\n> between two commits, you say \"diff A B\".  \"A..B\" happens to be\n> accepted as such only by accident (e.g. the old command line parser\n> did not have a reliable way to tell \"^A B\" and \"A..B\" apart), not by\n> design.\n> \n>     side note: incidentally, now we have rev_cmdline_info support,\n>     we could start deprecating \"diff A..B\" syntax.\n\nI often find myself using \"git diff A..B\" syntax when using the command\nline history because the previous command used \"A..B\"; e.g.,\n\n    git log A..B\n    git diff A..B\n\nIt's quick to recall the previous command, edit \"log\" -> \"diff\", and\npress enter; having to remove the dots would require a few extra keypresses.\n\n> Actually, in many places where the command line parser knows it\n> wants a single point, and never a range, we should be able to apply\n> the \"A...B as a notation to specify a single point\" rule.  \n> \n> Of course you could come up with a symbol other than \"...\" for that\n> purpose, and migrate the current \"git checkout A...B\" special case\n> to use that other symbol, but that would be more work and also you\n> would need to retrain existing users.\n\nOTOH making A...B sometimes mean a range and sometimes a merge-base\n(depending on context) adds a confusing non-uniformity, and also has the\ndisadvantage of making merge-base shorthand unavailable in contexts that\nallow a range.\n\nOTOOH git already has so many notations that can be used on the command\nline; inventing yet another one would make it that much more overwhelming.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"205372","messageId":"CANiSa6hcDHTpZnAXR3zxdv-H4r-yRjuSx_kgE5V1rSFk_pNhOA@mail.gmail.com","threadId":"32430","inReplyTo":"50D4BBDC.6030700@alum.mit.edu","subject":"Re: Fwd: [RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2012-12-21T21:31:00Z","receivedAt":"2012-12-21T21:31:00Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Fri, Dec 21, 2012 at 11:43 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> On 12/21/2012 06:12 PM, Junio C Hamano wrote:\n>> \"diff\" is always about two endpoints, not the path that connects\n>> these two endpoints (aka \"range\"), and when you want to \"diff\"\n>> between two commits, you say \"diff A B\".  \"A..B\" happens to be\n>> accepted as such only by accident (e.g. the old command line parser\n>> did not have a reliable way to tell \"^A B\" and \"A..B\" apart), not by\n>> design.\n\nOff topic: I also find it hard to wrap my head around what diffing\nagainst a negative revision would mean. Looking at the result of\nrunning it, it seems to be the same as diffing against a positive one.\n\n>>\n>>     side note: incidentally, now we have rev_cmdline_info support,\n>>     we could start deprecating \"diff A..B\" syntax.\n>\n> I often find myself using \"git diff A..B\" syntax when using the command\n> line history because the previous command used \"A..B\"; e.g.,\n>\n>     git log A..B\n>     git diff A..B\n\nThe problem with this, to me, if it wasn't clear, is that \"git log\nA..B\" shows you is new _since B branched off from A_, while \"git diff\nA..B\" shows you what has changed _between A and B_.\n\n>> Actually, in many places where the command line parser knows it\n>> wants a single point, and never a range, we should be able to apply\n>> the \"A...B as a notation to specify a single point\" rule.\n>>\n>> Of course you could come up with a symbol other than \"...\" for that\n>> purpose, and migrate the current \"git checkout A...B\" special case\n>> to use that other symbol, but that would be more work and also you\n>> would need to retrain existing users.\n>\n> OTOH making A...B sometimes mean a range and sometimes a merge-base\n> (depending on context) adds a confusing non-uniformity, and also has the\n> disadvantage of making merge-base shorthand unavailable in contexts that\n> allow a range.\n\nAnd making it unavailable in contexts where the command was not\nspecifically implemented to support it. I'm sure there are many\nscripts out there that use \"git ... $(git merge-base A B) ...\" that\ncould be simplified if rev-parse could resolve a merge base.\n\n> OTOOH git already has so many notations that can be used on the command\n> line; inventing yet another one would make it that much more overwhelming.\n\nAgreed.\n"},{"id":"205375","messageId":"CAPc5daWN_a0d2o37CkRk5n9bc4dy5_Zan22dN81waT=-+b7pVA@mail.gmail.com","threadId":"32430","inReplyTo":"CANiSa6hcDHTpZnAXR3zxdv-H4r-yRjuSx_kgE5V1rSFk_pNhOA@mail.gmail.com","subject":"Re: Fwd: [RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-12-21T21:45:14Z","receivedAt":"2012-12-21T21:45:14Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"> Off topic: I also find it hard to wrap my head around what diffing\n> against a negative revision would mean. Looking at the result of\n> running it, it seems to be the same as diffing against a positive one.\n\nThat is not an off-topic at all, but is the crux of \"diff A..B\" being\na hysterical raisins.\nIt is parsed as and converted to \"diff ^A B\" by the revision command\nline parser in\nsetup_revisions(), and the caller *guesses* what the command line\noriginally said by\ninspecting that there are two revs in rev.pending[] array, the first\none is negative and\nthe second one is positive, to infer that the user typed \"diff A..B\"\nand then finally\ndecides to compare A and B.\n\nThis was done before we introduced rev.cmdline_info to record what was\ngiven from\nthe command line to result in the set of commits in rev.pending array.\nIf we were\nwriting \"git diff\" UI from scratch today, we wouldn't be looking at\nrev.pending but\nwould be looking at rev.cmdline_info and we can differenciate between\n\"A B\", \"^A B\",\nand \"A..B\" (and reject the latter two as nonsense).\n"},{"id":"205377","messageId":"50D4DBD0.7050601@alum.mit.edu","threadId":"32430","inReplyTo":"CANiSa6hcDHTpZnAXR3zxdv-H4r-yRjuSx_kgE5V1rSFk_pNhOA@mail.gmail.com","subject":"Re: Fwd: [RFC/FR] Should \"git checkout (-B|-b) branch master...branch\" work?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2012-12-21T21:59:44Z","receivedAt":"2012-12-21T21:59:44Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 12/21/2012 10:31 PM, Martin von Zweigbergk wrote:\n> On Fri, Dec 21, 2012 at 11:43 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n>> On 12/21/2012 06:12 PM, Junio C Hamano wrote:\n>>>     side note: incidentally, now we have rev_cmdline_info support,\n>>>     we could start deprecating \"diff A..B\" syntax.\n>>\n>> I often find myself using \"git diff A..B\" syntax when using the command\n>> line history because the previous command used \"A..B\"; e.g.,\n>>\n>>     git log A..B\n>>     git diff A..B\n> \n> The problem with this, to me, if it wasn't clear, is that \"git log\n> A..B\" shows you is new _since B branched off from A_, while \"git diff\n> A..B\" shows you what has changed _between A and B_.\n\nYou are quite right, of course, though in many useful cases they are the\nsame.  But I guess I should just buck myself up for the new orthodoxy :-)\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"}]}