{"thread":{"id":"33596","subject":"Itches with the current rev spec","startedAt":"2013-04-25T05:07:16Z","lastAt":"2013-04-30T04:02:19Z","messageCount":24,"participants":["Ramkumar Ramachandra","Matthieu Moy","Felipe Contreras","Andreas Schwab","Phil Hord","Yann Dirson","Johannes Sixt","Junio C Hamano","Michael J Gruber"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"215403","messageId":"CALkWK0n97VLtiR96VEy86645NVoDL2rS-g7LBuLb=JpncdH6VA@mail.gmail.com","threadId":"33596","inReplyTo":null,"subject":"Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-25T05:07:16Z","receivedAt":"2013-04-25T05:07:16Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Hi,\n\nSo, I have three serious itches that would be nice to address:\n\n1. git reset --hard HEAD~1/ git show HEAD~1 is a very common idiom\nthat's unnecessarily cumbersome to type out.  We can make the <rev>\npart of <rev>~<n> optional without being ambiguous: you might argue\nthat ~<n> normally refers to a /home/<n>, but who uses numbers in\nplace of usernames?  Even if they do, how can that path possibly be\ninside our repository?\n\n2. git rebase -i master fails unless I've rebased my branch on top of\nmaster.  I always wished I could do the equivalent of 'git rebase -i\nmaster..', but I can't.  Can we give the A..B syntax a new meaning in\nthe context of rebase, namely $(git merge-base A B)?  No, this is not\nsimilar to the current diff A..B at all: first, we don't operate on\ntwo endpoints (so 'git rebase -i A B' is nonsensical, and only the\n'git rebase -i A ^B'/ 'git rebase -i ^A B' should be handled as\nspecial cases); second, we're trying to be consistent with the\nend-result meaning of A..B in ranged-commands like log (as opposed to\ndiff, which is being inconsistent).\n\n3. Even though I lashed out strongly against 'git diff A..B' because\nof inconsistency, I can't say that it's not useful (omit specifying\nHEAD on one side).  If we were to start over today, I would argue that\n'git diff A ^B' and 'git diff B ^A' be handled as special cases to\nmean 'git diff B $(git merge-base A B)' and 'git diff $(git merge-base\nA B) B' respectively.  The normal 'git diff A B' should have nothing\nto do with this.  Plus, 'git diff A...B' is really an eyesore.  So I\nask again: what can be done to improve the situation?\n\nThanks.\n"},{"id":"215405","messageId":"CALkWK0mr55QwrcsvyeRzq1K0RgEB7YOxMRhz2kjckRGZe-Tz7A@mail.gmail.com","threadId":"33596","inReplyTo":"CALkWK0n97VLtiR96VEy86645NVoDL2rS-g7LBuLb=JpncdH6VA@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-25T05:54:14Z","receivedAt":"2013-04-25T05:54:14Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Ramkumar Ramachandra wrote:\n> 3. Even though I lashed out strongly against 'git diff A..B' because\n> of inconsistency, I can't say that it's not useful (omit specifying\n> HEAD on one side).  If we were to start over today, I would argue that\n> 'git diff A ^B' and 'git diff B ^A' be handled as special cases to\n> mean 'git diff B $(git merge-base A B)' and 'git diff $(git merge-base\n> A B) B' respectively.  The normal 'git diff A B' should have nothing\n> to do with this.  Plus, 'git diff A...B' is really an eyesore.  So I\n> ask again: what can be done to improve the situation?\n\nOkay, so my solution to this is:\n\n1. Change the meaning of 'git diff A..B' (and A ^B, ^A B for\nconsistency).  Existing users might be using 'git diff master..' on\ntheir feature branches to get meaningful output, and this will not\nchange.  'git diff featurebranch1..' on another feature branch doesn't\ngive meaningful output anyway, and I find it hard to believe that\nusers will complain if we change the meaning of this.  Okay, maybe we\nwant to do it in git 2.0?\n\n2. Document (1) properly in gitrevisions.txt.\n\n3. Deprecate 'git diff A...B'.\n\nWhat do you think?\n"},{"id":"215415","messageId":"vpqehdzkoix.fsf@grenoble-inp.fr","threadId":"33596","inReplyTo":"CALkWK0n97VLtiR96VEy86645NVoDL2rS-g7LBuLb=JpncdH6VA@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2013-04-25T08:22:46Z","receivedAt":"2013-04-25T08:22:46Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Hi,\n>\n> So, I have three serious itches that would be nice to address:\n>\n> 1. git reset --hard HEAD~1/ git show HEAD~1 is a very common idiom\n> that's unnecessarily cumbersome to type out.  We can make the <rev>\n> part of <rev>~<n> optional without being ambiguous: you might argue\n> that ~<n> normally refers to a /home/<n>, but who uses numbers in\n> place of usernames?  Even if they do, how can that path possibly be\n> inside our repository?\n\nIt's a bit more complex than that: the ~<username> is expanded by the\nshell, before Git has any opportunity to guess anything.\n\n~1 would be unusable for zsh users and tcsh users at least by default:\n\nzsh% echo ~1\nzsh: not enough directory stack entries.\n\ntcsh% echo ~1\nUnknown user: 1.\n\n(An obvious workaround is to shell-quote it, but as the goal is to have\nsomething easy to type, \\~1 or '~1' do not give so much benefit over\nHEAD~1)\n\nThat said, it seems to work fine for bash (even if the number is a PID,\nit's not expanded), so it may be a good idea to add it as a shortcut,\nwith a warning in the doc about shell expansion.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"215416","messageId":"CAMP44s3P02yFoi64j5aROQm69O4NGzvzxONyEjkpvLzW-GTenA@mail.gmail.com","threadId":"33596","inReplyTo":"vpqehdzkoix.fsf@grenoble-inp.fr","subject":"Re: Itches with the current rev spec","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-25T08:48:57Z","receivedAt":"2013-04-25T08:48:57Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, Apr 25, 2013 at 3:22 AM, Matthieu Moy\n<Matthieu.Moy@grenoble-inp.fr> wrote:\n> Ramkumar Ramachandra <artagnon@gmail.com> writes:\n>\n>> Hi,\n>>\n>> So, I have three serious itches that would be nice to address:\n>>\n>> 1. git reset --hard HEAD~1/ git show HEAD~1 is a very common idiom\n>> that's unnecessarily cumbersome to type out.  We can make the <rev>\n>> part of <rev>~<n> optional without being ambiguous: you might argue\n>> that ~<n> normally refers to a /home/<n>, but who uses numbers in\n>> place of usernames?  Even if they do, how can that path possibly be\n>> inside our repository?\n>\n> It's a bit more complex than that: the ~<username> is expanded by the\n> shell, before Git has any opportunity to guess anything.\n>\n> ~1 would be unusable for zsh users and tcsh users at least by default:\n>\n> zsh% echo ~1\n> zsh: not enough directory stack entries.\n>\n> tcsh% echo ~1\n> Unknown user: 1.\n>\n> (An obvious workaround is to shell-quote it, but as the goal is to have\n> something easy to type, \\~1 or '~1' do not give so much benefit over\n> HEAD~1)\n>\n> That said, it seems to work fine for bash (even if the number is a PID,\n> it's not expanded), so it may be a good idea to add it as a shortcut,\n> with a warning in the doc about shell expansion.\n\nYeah, probably fine, but I would also like H~1.\n\n-- \nFelipe Contreras\n"},{"id":"215417","messageId":"m2obd3ou34.fsf@igel.home","threadId":"33596","inReplyTo":"CALkWK0n97VLtiR96VEy86645NVoDL2rS-g7LBuLb=JpncdH6VA@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2013-04-25T09:09:03Z","receivedAt":"2013-04-25T09:09:03Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> you might argue that ~<n> normally refers to a /home/<n>, but who uses\n> numbers in place of usernames?\n\n~<n> expands to the <n>th element of the dir stack.\n\nAndreas.\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5\n\"And now for something completely different.\"\n"},{"id":"215418","messageId":"CALkWK0m-CKN6rW_rr4=M0J5Wf5g-ng6Z_rXM3q-DThY=H1+xVg@mail.gmail.com","threadId":"33596","inReplyTo":"m2obd3ou34.fsf@igel.home","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-25T09:13:32Z","receivedAt":"2013-04-25T09:13:32Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Andreas Schwab wrote:\n> Ramkumar Ramachandra <artagnon@gmail.com> writes:\n>\n>> you might argue that ~<n> normally refers to a /home/<n>, but who uses\n>> numbers in place of usernames?\n>\n> ~<n> expands to the <n>th element of the dir stack.\n\nOh, ouch.  And this is bash.\n\nHave to think of something else.\n"},{"id":"215426","messageId":"CALkWK0n67c203tLWYvCi9qiMtBo2ZOkKLYbsqFC1ukwz0CLEuw@mail.gmail.com","threadId":"33596","inReplyTo":"CAMP44s3P02yFoi64j5aROQm69O4NGzvzxONyEjkpvLzW-GTenA@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-25T11:06:17Z","receivedAt":"2013-04-25T11:06:17Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n> Yeah, probably fine, but I would also like H~1.\n\nYou can get that now using `git symbolic ref H HEAD`.  I'm wondering\nif we can do better than hard-interpreting HEAD as H at the rev-parse\nlevel.\n"},{"id":"215475","messageId":"CABURp0pSMRZLLDz8hgXxMtTtx-vpn8SSAi-16tyw2+J+ttUQTg@mail.gmail.com","threadId":"33596","inReplyTo":"CALkWK0n97VLtiR96VEy86645NVoDL2rS-g7LBuLb=JpncdH6VA@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2013-04-25T19:08:09Z","receivedAt":"2013-04-25T19:08:09Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Thu, Apr 25, 2013 at 1:07 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> 2. git rebase -i master fails unless I've rebased my branch on top of\n> master.  I always wished I could do the equivalent of 'git rebase -i\n> master..', but I can't.\n\nIn what way does it fail?   It seems to work ok for me.  Do you mean\nthat it chooses extra commits you did not want?\n\nMaybe you expect rebase--interactive will only result in changes to\ncommits you touch in the todo list and it will not actually rebase\nanything.   Is that the goal?\n\nI have been thinking of adding a targeted \"rebase -i\" extension.  I\noften use rebase -i to change one commit in recent history or to\nsquash some fixup into place.  The trip through $EDITOR to do this\nseems disruptive to my thinking.   So I would like to be able to do\nthis:\n\n   git rebase --edit $REF\n\nwhich should act the same as\n\n  GIT_EDITOR='sed -i \"s/^pick $REF/edit $REF/\"' \\\n  git rebase -i $REF^\n\nExcept that $REF could be any ref and not just the exact\nSHA1-abbreviation given in todo.\n\nThe change I imagine allows --fixup, --reword,  --squash, etc.  It\nmight even allow multiple instances of each.\n\nI haven't thought through how to handle the case where there are\nmerges in the way, but I do already suppose that the command will\nsimply fail if a ref is not an ancestor of HEAD.\n\nMaybe this is too simple for your workflow, though. As I said, I did\nnot understand your itch.\n\nPhil\n"},{"id":"215568","messageId":"20130426101946.433f2d12@chalon.bertin.fr","threadId":"33596","inReplyTo":"CALkWK0n97VLtiR96VEy86645NVoDL2rS-g7LBuLb=JpncdH6VA@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Yann Dirson","fromEmail":"dirson@bertin.fr","sentAt":"2013-04-26T08:19:46Z","receivedAt":"2013-04-26T08:19:46Z","isPatch":false,"sender":{"key":"dirson@bertin.fr","avatar":null},"body":">2. git rebase -i master fails unless I've rebased my branch on top of\n>master.  I always wished I could do the equivalent of 'git rebase -i\n>master..', but I can't.  Can we give the A..B syntax a new meaning in\n>the context of rebase, namely $(git merge-base A B)? \n\nIf I understand well, you're refering to a problem that also annoys me,\nie. using \"rebase -i\" to just edit your local commits, without rebasing\nonto the lastest revision on the upstream branch, right ?  That is, just\nanother wart of having a single command for arguably-different use cases,\nor of having the single-argument version of rebase use that argument for\n2 very different things (cut-off point and destination), but I won't try\nto address either of these today :)\n\nIn that case, what about just adding a new flag to \"rebase -i\", that would\nprevent the single-argument to be interpreted as destination ?  I really\nconsider this a workaround for a suboptimal CLI, but since we don't want\nto change the rebase CLI before at least 2.0, that could fill the gap for now.\n\nAs for the flag itself, what about --here ?  Obviously it would only be\nmeaninglful together with -i, and be exclusive with --onto.\n\n-- \nYann Dirson - Bertin Technologies\n"},{"id":"215573","messageId":"517A3E47.6010606@viscovery.net","threadId":"33596","inReplyTo":"20130426101946.433f2d12@chalon.bertin.fr","subject":"Re: Itches with the current rev spec","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2013-04-26T08:43:51Z","receivedAt":"2013-04-26T08:43:51Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 4/26/2013 10:19, schrieb Yann Dirson:\n>> 2. git rebase -i master fails unless I've rebased my branch on top of\n>> master.  I always wished I could do the equivalent of 'git rebase -i\n>> master..', but I can't.  Can we give the A..B syntax a new meaning in\n>> the context of rebase, namely $(git merge-base A B)? \n> \n> If I understand well, you're refering to a problem that also annoys me,\n> ie. using \"rebase -i\" to just edit your local commits, without rebasing\n> onto the lastest revision on the upstream branch, right ?  That is, just\n> another wart of having a single command for arguably-different use cases,\n> or of having the single-argument version of rebase use that argument for\n> 2 very different things (cut-off point and destination), but I won't try\n> to address either of these today :)\n> \n> In that case, what about just adding a new flag to \"rebase -i\", that would\n> prevent the single-argument to be interpreted as destination ?  I really\n> consider this a workaround for a suboptimal CLI, but since we don't want\n> to change the rebase CLI before at least 2.0, that could fill the gap for now.\n> \n> As for the flag itself, what about --here ?  Obviously it would only be\n> meaninglful together with -i, and be exclusive with --onto.\n\nHow about this:\n\nAllow alternative spelling of\n\n   git rebase -i master topic\n\nlike this:\n\n   git rebase -i master..topic\n\n(as always, the default for topic is HEAD).\n\nThen by extension (cf. git diff, where A...B shows the diff between the\nmergebase and B)\n\n   git rebase -i master...topic\n\nwould rebase onto the mergebase, which in practice will be the fork point\nof topic, i.e., a \"non-rebasing rebase\".\n\n-- Hannes\n"},{"id":"215590","messageId":"CALkWK0mDZapwUUMRQDqeip2myfHXiRThGmR4uuOjNPFOPKh65A@mail.gmail.com","threadId":"33596","inReplyTo":"517A3E47.6010606@viscovery.net","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-26T12:33:04Z","receivedAt":"2013-04-26T12:33:04Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Johannes Sixt wrote:\n>    git rebase -i master..topic\n>    git rebase -i master...topic\n\nWe absolutely don't want to go down the inconsistent diff UI route.  See [1].\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/222248\n"},{"id":"215604","messageId":"7v7gjpxjw0.fsf@alter.siamese.dyndns.org","threadId":"33596","inReplyTo":"517A3E47.6010606@viscovery.net","subject":"Re: Itches with the current rev spec","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-26T17:49:03Z","receivedAt":"2013-04-26T17:49:03Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> Allow alternative spelling of\n>\n>    git rebase -i master topic\n>\n> like this:\n>\n>    git rebase -i master..topic\n>\n> (as always, the default for topic is HEAD).\n\nI actually made this typo a few times in the past.\n\nIn a single-strand-of-pearls history, what rebase operates on is\nclearly a _range_ with a defined linear order of commits, and\nmaster..topic is a natural way to express it.\n\nAnd rebase not just needs the range that defines the set of commits\nto be replayed, but also needs the commit on top of which they are\nreplayed.  It is natural to take ^master as that commit, and it is\nuseful when you are trying to catch up with that branch.  \n\nThe reason you would use \"rebase -i\" is not for catching up [*1*],\nso defaulting to replay onto ^master is not useful.  You want the\ncommand to replay on top of the stable same base, so that you can\ncompare the result with the previous version in order to verify.\nOften, the fork-point with master is a good choice for that.\n\nIt is tempting to say that \"rebase -i\" and normal catch-up \"rebase\"\n(e.g. \"pull --rebase\") should have designed to behave differently.\n\"git rebase -i master\" perhaps should have made to rebase the\ncurrent work on top of the fork-point from master, not on top of it,\nand require an explict --onto master if the user does want to also\ncatch up.\n\nBut the above is orthogonal to the syntax \"../...\" issue.\n\n\n[Footnote]\n\n*1* \"rebase\" and \"rebase -i\" already behave slightly differently\nwith respect to $onto\" in that a catch-up rebase that is already up\nto date notices the situation and turns into a no-op, but it does\nnot turn \"rebase -i\" into a no-op for this exact reason.\n"},{"id":"215625","messageId":"CAMP44s0-C_TRC_eD_ZbN3WFe4NKWVPQVhh+ME-F5yBBwKs2NdA@mail.gmail.com","threadId":"33596","inReplyTo":"7v7gjpxjw0.fsf@alter.siamese.dyndns.org","subject":"Re: Itches with the current rev spec","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-26T19:48:38Z","receivedAt":"2013-04-26T19:48:38Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Apr 26, 2013 at 12:49 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Johannes Sixt <j.sixt@viscovery.net> writes:\n>\n>> Allow alternative spelling of\n>>\n>>    git rebase -i master topic\n>>\n>> like this:\n>>\n>>    git rebase -i master..topic\n>>\n>> (as always, the default for topic is HEAD).\n>\n> I actually made this typo a few times in the past.\n>\n> In a single-strand-of-pearls history, what rebase operates on is\n> clearly a _range_ with a defined linear order of commits, and\n> master..topic is a natural way to express it.\n\nI agree, but I think there are other unexpected things.\n\nI don't know what 'git rebase master' does, but I would expect 'git\nrebase --onto=master' to do the same thing. Then, if 'git rebase\n--onto=next master..topic' makes sense, so should 'git rebase next\nmaster..topic'.\n\nMoreover, it often annoys me that 'git rebase master' does exactly\nwhat I want, but 'git rebase --onto=master previous' doesn't find the\ncommits that are already into 'master'. One would expect the more\ndefined version to work better, but it doesn't =/\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"215639","messageId":"7v8v45vvuy.fsf@alter.siamese.dyndns.org","threadId":"33596","inReplyTo":"CAMP44s0-C_TRC_eD_ZbN3WFe4NKWVPQVhh+ME-F5yBBwKs2NdA@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-26T21:13:25Z","receivedAt":"2013-04-26T21:13:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> I don't know what 'git rebase master' does, but I would expect 'git\n> rebase --onto=master' to do the same thing. Then, if 'git rebase\n> --onto=next master..topic' makes sense, so should 'git rebase next\n> master..topic'.\n>\n> Moreover, it often annoys me that 'git rebase master' does exactly\n> what I want, but 'git rebase --onto=master previous' doesn't find the\n> commits that are already into 'master'. One would expect the more\n> defined version to work better, but it doesn't =/\n\nThat all stems from the fact that rebase (not -i variant) predates\nthese nice A..B, A...B, and $(merge-base A B) concepts have been\ningrained in the user's mindset as the primary UI language of Git.\n\n - The UI language of \"rebase origin\" comes more from the \"workflow\"\n   school.  \"I have built on 'origin'; I want to catch up with its\n   current state\".  To support that workflow, 'origin' is the only\n   thing you need to say, and \"rebase origin\" matches that nicely.\n   If you then add \"By the way, that statement expresses my wish for\n   the 'topic' branch, not my current one\", you get \"rebase origin\n   topic\".\n\n - If the UI language for \"rebase\" were designed following the\n   \"composition using common elements like ranges and revisions\"\n   school, it would have started from \"rebase --onto=X A..B\".\n\nBack then, we did not know which principle to design the UI language\nwould prevail, but we needed something that works to support the end\nusers.  So \"git log\" spoke \"A..B\" but \"git rebase\" took \"origin\".\n\nOver time, the \"composition\" school prevailed and these days we see\nmany commands accept and act on revision ranges or discrete\nrevisions.\n\nThe same thing happened to format-patch, whose original syntax was\n\n    format-patch origin\n\nwhich is still accepted, but we have adjusted it to understand the\nmore prevalent\n\n    format-patch origin..\n\nbecause it is far more understandable if you know other commands\nthat are based on \"composition\" UI language.  That adjustment\nstarted making sense after it has become clear that \"composition\"\nschool of UI language is the way forward.\n\nIt's just that \"rebase\" is waiting for the same kind of adjustment.\n\nHint, hint.\n"},{"id":"215850","messageId":"517E7D12.6020605@drmicha.warpmail.net","threadId":"33596","inReplyTo":"vpqehdzkoix.fsf@grenoble-inp.fr","subject":"Re: Itches with the current rev spec","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2013-04-29T14:00:50Z","receivedAt":"2013-04-29T14:00:50Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Matthieu Moy venit, vidit, dixit 25.04.2013 10:22:\n> Ramkumar Ramachandra <artagnon@gmail.com> writes:\n> \n>> Hi,\n>>\n>> So, I have three serious itches that would be nice to address:\n>>\n>> 1. git reset --hard HEAD~1/ git show HEAD~1 is a very common idiom\n>> that's unnecessarily cumbersome to type out.  We can make the <rev>\n>> part of <rev>~<n> optional without being ambiguous: you might argue\n>> that ~<n> normally refers to a /home/<n>, but who uses numbers in\n>> place of usernames?  Even if they do, how can that path possibly be\n>> inside our repository?\n> \n> It's a bit more complex than that: the ~<username> is expanded by the\n> shell, before Git has any opportunity to guess anything.\n> \n> ~1 would be unusable for zsh users and tcsh users at least by default:\n> \n> zsh% echo ~1\n> zsh: not enough directory stack entries.\n> \n> tcsh% echo ~1\n> Unknown user: 1.\n> \n> (An obvious workaround is to shell-quote it, but as the goal is to have\n> something easy to type, \\~1 or '~1' do not give so much benefit over\n> HEAD~1)\n> \n> That said, it seems to work fine for bash (even if the number is a PID,\n> it's not expanded), so it may be a good idea to add it as a shortcut,\n> with a warning in the doc about shell expansion.\n\nI've been using a patch for that for ages without problems; it had been\nrejected because of the reasons above, plus:\n\nNote that even in bash ~1 has a different meaning when your directory\nstack is non-empty. It's just that I don't use that feature, and bash\nleaves '~1' as is when there is no stack (you haven't used pushd),\nwhereas zsh errors out.\n\nSo, I do understand that some consider this semi-broken, even though\nit's not. But we avoid clashes with shell expansion in most cases for\nmost shells.\n\nAs for rebase, I still have to look up what \"git rebase A B\" means. This\nwould be much clearer with a range notation. I seem to recall I even\nsuggested it, but that might have been in a parallel universe.\n\nMichael\n"},{"id":"215855","messageId":"CALkWK0=W_FxDwc3Tby=h90yc5i8UEuT7maERahFRDQU=hQ633g@mail.gmail.com","threadId":"33596","inReplyTo":"7v8v45vvuy.fsf@alter.siamese.dyndns.org","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-29T15:08:03Z","receivedAt":"2013-04-29T15:08:03Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n>  - If the UI language for \"rebase\" were designed following the\n>    \"composition using common elements like ranges and revisions\"\n>    school, it would have started from \"rebase --onto=X A..B\".\n\nI think you're looking at the whole issue backwards from the way I\nlook at it.  Let's try to lay out some fundamental principles and\nbuild a representations on top of that:\n\n1. All rev specs (those specified in revisions.txt) either emit a\nsingle positive/ negative (^) commit or multiple positive/ negative\ncommits (where the ordering does not matter).\n\n2. Fundamentally, all commands require single/ multiple commits to\noperate on.  They might also require some additional information.\n\nrebase requires three pieces of information: the commit onto which to\nreplay, a list of commits to replay, and a refspec to update once the\nreplaying is done.\n\nlog requires one piece of information: the list of commits.\n\ndiff requires two pieces of information: two commits to diff.\n\n3. \"Range\" is not an inherent property of A..B or A...B.  There are no\n\"revision ranges\".\n\n4. Every command is free to interpret positive and negative commits as\nit sees fit.  Since there is no ordering, it must never treat one\nnegative commit differently from another negative commit, or one\npositive commit differently from another positive commit.\n\nshow takes a list of positive commits and shows all of them.\n\nlog will show all the commits reachable from positive commits, and\nexclude all the commits reachable from negative commits.  Here, the\n\"list of commits\" are interpreted differently from the show case.\n\ndiff can either take two positive commits or one positive + one\nnegative commit.  In the latter case, it swaps the arguments and\ntreats both as positive commits.\n\nrebase can take one negative commit and one positive commit.  The\ncommits reachable from the positive commit, but not from the negative\ncommit are replayed onto the negative commit.  Now, we can use --onto=\nto override the commit onto which to replay.  But the fundamental\nconstraint remains: rebase _cannot_ make this --onto= parameter part\nof the normal rev spec (we only have two types of commits: positive\nand negative to which we can assign different meanings).\n--\n\nThis, I think, is the way forward.  In any command, forcing the user\nto differentiate between the two commits only using argv[0] and\nargv[1] is just horrible (diff with two positive commits is the only\nnecessary exception to this rule).\n\nFurther, what I think is of utmost importance is consistency.\nInventing loose mnemonics like in the diff case is the road to\ninsanity.  All commands _must_ behave exactly the same way with all\nthe different rev specs (or error out when the particular rev spec\nemits more commits than the command needs/ the wrong number of\npositive-negative commits).\n\nWhat's more?  I have a solution.  A brand new revspec is the _only_\nway to solve our problems without breaking consistency, or trading off\nterseness [Who wants to do git rebase --onto master $(git merge-base\nmaster topic)..topic every single time?].  I mentioned it on the other\nthread, but didn't get feedback :(\n"},{"id":"215857","messageId":"CALkWK0n=K1PK64xAvCUOQwhMUUtdSLyOGxNLZuqWYvVddZgmKw@mail.gmail.com","threadId":"33596","inReplyTo":"7v8v45vvuy.fsf@alter.siamese.dyndns.org","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-29T15:20:44Z","receivedAt":"2013-04-29T15:20:44Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n>  - If the UI language for \"rebase\" were designed following the\n>    \"composition using common elements like ranges and revisions\"\n>    school, it would have started from \"rebase --onto=X A..B\".\n\nI will try to drive the point home one more time.  What do you really\nwant to rebase?  B ^A or B ^$(git merge-base A B)?  They're two\nentirely different things as I've repeated countless times.  And the\nlatter is what I always really mean.\n"},{"id":"215858","messageId":"20130429173726.04cb5ac5@chalon.bertin.fr","threadId":"33596","inReplyTo":"CALkWK0=W_FxDwc3Tby=h90yc5i8UEuT7maERahFRDQU=hQ633g@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Yann Dirson","fromEmail":"dirson@bertin.fr","sentAt":"2013-04-29T15:37:26Z","receivedAt":"2013-04-29T15:37:26Z","isPatch":false,"sender":{"key":"dirson@bertin.fr","avatar":null},"body":"On Mon, 29 Apr 2013 20:38:03 +0530 Ramkumar Ramachandra <artagnon@gmail.com> wrote:\n> 3. \"Range\" is not an inherent property of A..B or A...B.  There are no\n> \"revision ranges\".\n\nWell, that could be seen as a problem, the .. syntax being commonly associated\nwith the concept of range.\n\n> 4. Every command is free to interpret positive and negative commits as\n> it sees fit.  Since there is no ordering, it must never treat one\n> negative commit differently from another negative commit, or one\n> positive commit differently from another positive commit.\n> \n> show takes a list of positive commits and shows all of them.\n> \n> log will show all the commits reachable from positive commits, and\n> exclude all the commits reachable from negative commits.  Here, the\n> \"list of commits\" are interpreted differently from the show case.\n> \n> diff can either take two positive commits or one positive + one\n> negative commit.  In the latter case, it swaps the arguments and\n> treats both as positive commits.\n> \n> rebase can take one negative commit and one positive commit.  The\n> commits reachable from the positive commit, but not from the negative\n> commit are replayed onto the negative commit.  Now, we can use --onto=\n> to override the commit onto which to replay.  But the fundamental\n> constraint remains: rebase _cannot_ make this --onto= parameter part\n> of the normal rev spec (we only have two types of commits: positive\n> and negative to which we can assign different meanings).\n> --\n\nDon't forget the particular situation of cherry-pick, which shows a situation\nwhere we may want to specify a set of single commits and ranges, but for which\nthe current mechanisms cause a problem.\n\nSee: http://thread.gmane.org/gmane.comp.version-control.git/199994/focus=200058\n\n\n-- \nYann Dirson - Bertin Technologies\n"},{"id":"215859","messageId":"7vobcxl3ui.fsf@alter.siamese.dyndns.org","threadId":"33596","inReplyTo":"CALkWK0=W_FxDwc3Tby=h90yc5i8UEuT7maERahFRDQU=hQ633g@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-29T16:05:25Z","receivedAt":"2013-04-29T16:05:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n>>  - If the UI language for \"rebase\" were designed following the\n>>    \"composition using common elements like ranges and revisions\"\n>>    school, it would have started from \"rebase --onto=X A..B\".\n>\n> I think you're looking at the whole issue backwards from the way I\n> look at it.\n\nI am not \"looking at\" anything.  I was giving the historical\nbackground to explain how the current UI language came to be, but\nthat was not to argue for keeping it to be the way it is, or even to\njustify that it is the right UI.\n\n> Let's try to lay out some fundamental principles and\n\nVery interesting.\n\n> 3. \"Range\" is not an inherent property of A..B or A...B.  There are no\n> \"revision ranges\".\n>\n> 4. Every command is free to interpret positive and negative commits as\n> it sees fit.  Since there is no ordering, it must never treat one\n> negative commit differently from another negative commit, or one\n> positive commit differently from another positive commit.\n\nThat world view is broken, isn't it?  Perhaps you forgot to consider\nsymmetric differences, where left positives and right positives have\nto be treated differently.  \"diff A B\" and \"diff B A\" mean very\ndifferent things, for that matter.  A line of thought that begins\nwith \"there is no ordering\" may be a \"brave proposal\", perhaps, but\nit is not \"fundamental principles\".\n\nIf you do not like the word \"range\", read it as a DAG.\n\n\"rebase requires three: onto, list and a ref\" (by the way, it is not\nrefspec, which has a specific meaning) is trapped by the limitation\nof its current UI language that came from the \"workflow\" school and\nmissing what the operation really means.\n\nrebase takes a DAG with one negative commit, and replays it to form\nan isomorphic DAG on top of another commit.  At the essential level,\nit takes two pieces of information, such a DAG and an \"onto\" commit.\n\nBut in the current UI, the way to specify these two things are by\ngiving three commits, i.e. --onto=ONTO ONE_NEGATIVE ONE_POSITIVE.\nThe positive is used to specify which ref to update.\n\nIt is not far-fetched to allow rebase to handle a history with two\nbranches A and B that share the common initial part (i.e. ^X A B)\nand replay that history on top of an unrelated point in history Y to\ntransform:\n\n             o---o---Y\n            /\n    ---o---X---C---C---A---A---A (tip of branch A)\n                    \\\n                     B---B---B (tip of branch B)\n\ninto\n\n             o---o---Y---C'--C'--A'--A'--A' (updated tip of branch A)\n            /         \\\n    ---o---X           B'--B'--B' (updated tip of branch B)\n\nBut the \"rebase one branch on a new base\" UI that came from the\n\"workflow\" school is unable to express such an operation.  The\npieces of information we are using in the above are:\n\n * Where the bottom of the DAG being replayed is (i.e. X);\n * What refs are the top of the DAG (i.e. A and B);\n * Where the new bottom of the replayed DAG (i.e. Y).\n\nSo if we are refining the rebase UI, while making sure we can later\nextend it, we shouldn't start from \"onto, list and a ref\".  We\nshould start from \"a single onto, a single bottom, and one or more\nrefs that define tops\".\n\n> constraint remains: rebase _cannot_ make this --onto= parameter part\n> of the normal rev spec\n\nSo what?  Why do you even _need_ to mix up all positive revisions,\nsome of which mean different things from others, into a single bag,\nonly to later differenciate some as special (i.e. used as the onto\ncommit) from the others (i.e. the tips in the DAG)?  If something is\nspecial, you can say not just it is special and can say what it\nmeans by saying \"this is where I want to replay the DAG on top\".\n\nA much larger issue is that the current setup_revisions()\ninfrastructure does not let us express an operation that involves\ntwo or more DAGs.  People sometimes wish to say an equivalent of\n\n    git show $(git rev-list A..B) $(git rev-list C..D)\n\nbut obviously\n\n    git show A..B C..D\n\nis not the way to say it, and this limitation comes from it.\n"},{"id":"215871","messageId":"CALkWK0k7w4xuewnJFNJLk730NSiZOA_1UF0_Dqcnw5Or3GYOcA@mail.gmail.com","threadId":"33596","inReplyTo":"7vobcxl3ui.fsf@alter.siamese.dyndns.org","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-29T17:14:39Z","receivedAt":"2013-04-29T17:14:39Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> That world view is broken, isn't it?  Perhaps you forgot to consider\n> symmetric differences, where left positives and right positives have\n> to be treated differently.\n\nNo, I did consider symmetric difference.  How is git log A B --not\n$(git merge-base --all A B) different from git log B A --not $(git\nmerge-base --all A B)?\n\n> \"diff A B\" and \"diff B A\" mean very\n> different things, for that matter.\n\nIn fact, I would go so far as to claim that git diff A B is broken.\ndiff should be forbidden from taking two positives (since it has no\nway to differentiate between them but for the ordering).  It should\ndiff a positive against a negative.\n\n> A line of thought that begins\n> with \"there is no ordering\" may be a \"brave proposal\", perhaps, but\n> it is not \"fundamental principles\".\n\nMy claim is very simple.  If a command _depends_ on A..B being\nresolved as ^A B, and not B ^A, we have have a big problem.  Why?\nBecause we've already established that git log A B is exactly the same\nthing as git log B A.  To maintain consistency with this, ordering\nshould never matter.\n\n> \"rebase requires three: onto, list and a ref\" (by the way, it is not\n> refspec, which has a specific meaning)\n\nSorry about that thinko: yes, I meant ref.\n\nAfter working on the implicit-push proposal for so long, I think I can\ntell the difference between a ref and refspec ;)\n\n> It is not far-fetched to allow rebase to handle a history with two\n> branches A and B that share the common initial part (i.e. ^X A B)\n> and replay that history on top of an unrelated point in history Y to\n> transform:\n>\n>              o---o---Y\n>             /\n>     ---o---X---C---C---A---A---A (tip of branch A)\n>                     \\\n>                      B---B---B (tip of branch B)\n>\n> into\n>\n>              o---o---Y---C'--C'--A'--A'--A' (updated tip of branch A)\n>             /         \\\n>     ---o---X           B'--B'--B' (updated tip of branch B)\n\nI wholeheartedly agree.\n\nHowever, I think you've misunderstood what I said: my goal is to\ndefine _everything_ in terms of how different commands interpret a\nlist of positive and negative commits.  It's not that some commands\ntake DAGs, other ranges, and yet others lists; all of them take rev\nspecs that resolve to a list of positive-negative commits.  What to do\nwith that information is up to the command (erroring out is a valid\nresponse).  In my above proposal, I'd like to change \"rebase can take\none negative commit and one positive commit\" to \"rebase can take one\nnegative commit and multiple positive commits\" (in fact, this was my\noriginal sentence, but I went back to \"one positive commit\" before\nsending out the email because I thought I was being crazy).\n\n> So what?  Why do you even _need_ to mix up all positive revisions,\n> some of which mean different things from others, into a single bag,\n> only to later differenciate some as special (i.e. used as the onto\n> commit) from the others (i.e. the tips in the DAG)?  If something is\n> special, you can say not just it is special and can say what it\n> means by saying \"this is where I want to replay the DAG on top\".\n\nUm, my point was again that \"ordering does not matter\"; therefore for\na third type of commit, you need a command-line parameter.\n\n>     git show A..B C..D\n\nThis is seriously bad.  We'll have to think about fixing this along the way.\n"},{"id":"215873","messageId":"7vip35jl7z.fsf@alter.siamese.dyndns.org","threadId":"33596","inReplyTo":"CALkWK0k7w4xuewnJFNJLk730NSiZOA_1UF0_Dqcnw5Or3GYOcA@mail.gmail.com","subject":"Re: Itches with the current rev spec","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-29T17:33:04Z","receivedAt":"2013-04-29T17:33:04Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Junio C Hamano wrote:\n>> That world view is broken, isn't it?  Perhaps you forgot to consider\n>> symmetric differences, where left positives and right positives have\n>> to be treated differently.\n>\n> No, I did consider symmetric difference.  How is git log A B --not\n> $(git merge-base --all A B) different from git log B A --not $(git\n> merge-base --all A B)?\n\nCompare these (gitk will give you nicer picture):\n\n   $ git log --oneline --graph --left-right A...B\n   $ git log --oneline --graph --left-right B...A\n\n> Um, my point was again that \"ordering does not matter\"; therefore for\n> a third type of commit, you need a command-line parameter.\n>\n>>     git show A..B C..D\n>\n> This is seriously bad.  We'll have to think about fixing this along the way.\n\nFor the purpose of \"doing one thing and well\", we have drawn the\nline at \"we operate on at most one DAG and specify what happens to\nit with various other parameters, which may include commits\" long\ntime ago.  If you want to operate on more than one DAG, the cleanest\nway is to do the set computation for A..B and C..D separately and\ncombine them yourself (which is the example you omitted from the\nquote).\n\nThe setup_revisions() machinery that is the foundation of the\ncurrent codebase has this design decision ingrained in it.  That is\nwhere the marking of commits with only two primary colors (i.e. the\nUNINTERESTING bit) comes from, and where the \"single DAG\" limitation\noriginates.  You can extending it a little bit (e.g. by introducing\na secondary color left/right) to enrich it, but fundamentally the\ninfrastructure pretty much assumes we operate on one DAG and a\ncommit is either outside or inside (or at the boundary) of it.\n\nIt may be nice if the low-level operated on more than one DAG, but\nit is very close to a proposition to throw the baby with the\nbathwater and restart from scratch.  It is a lot more than a little\n\"as an aside\" task.\n"},{"id":"215903","messageId":"CALkWK0nH0n2UZeMh_q4TQuUqzwhp8qGk9Oi+2DExozkuyfKzTg@mail.gmail.com","threadId":"33596","inReplyTo":"7vip35jl7z.fsf@alter.siamese.dyndns.org","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-29T19:10:15Z","receivedAt":"2013-04-29T19:10:15Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> Compare these (gitk will give you nicer picture):\n>\n>    $ git log --oneline --graph --left-right A...B\n>    $ git log --oneline --graph --left-right B...A\n\nDarn.  I didn't realize that rev-list had a --left-right to mark\ncommits with <, >, or - before giving it to the command.  So, that's\none more thing to note: there are positive and negative commits, as\nwell as commits marked with a direction (in the special case of\n--left-right).  Have we missed anything?\n\n> It may be nice if the low-level operated on more than one DAG, but\n> it is very close to a proposition to throw the baby with the\n> bathwater and restart from scratch.  It is a lot more than a little\n> \"as an aside\" task.\n\nI know too little to comment on the issue.  I was merely musing.\n"},{"id":"215906","messageId":"CALkWK0nQhfbX8KQwMxwQ9Lntx1JFwKB4gPVsViz4e7i5c6G+Rw@mail.gmail.com","threadId":"33596","inReplyTo":"7vobcxl3ui.fsf@alter.siamese.dyndns.org","subject":"Re: Itches with the current rev spec","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-04-29T19:23:44Z","receivedAt":"2013-04-29T19:23:44Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n>  * Where the bottom of the DAG being replayed is (i.e. X);\n>  * What refs are the top of the DAG (i.e. A and B);\n>  * Where the new bottom of the replayed DAG (i.e. Y).\n\nOkay, so can I start writing a series that will make git rebase accept\none negative commit (N) and one positive commit (P) in any order?  A\ngit rebase N..P should rebase the DAG defined by P ^N onto $(git\nmerge-base N P).  Does that make sense?\n\n(two positive commits are a special case for backward compatibility?)\n"},{"id":"215959","messageId":"7vip34fyyc.fsf@alter.siamese.dyndns.org","threadId":"33596","inReplyTo":"7vobcxl3ui.fsf@alter.siamese.dyndns.org","subject":"Re: Itches with the current rev spec","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-30T04:02:19Z","receivedAt":"2013-04-30T04:02:19Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> A much larger issue is that the current setup_revisions()\n> infrastructure does not let us express an operation that involves\n> two or more DAGs.  People sometimes wish to say an equivalent of\n>\n>     git show $(git rev-list A..B) $(git rev-list C..D)\n>\n> but obviously\n>\n>     git show A..B C..D\n>\n> is not the way to say it, and this limitation comes from it.\n\nJust a clarification. Technically, this is _not_ impossible.  With\nsome (read: quite a lot of) work to move objects.flags out of the\nobject and to allow unbounded number of flag bits, you could support\narbitrary number of ranges that are UNION'ed together by pretty much\nthe same code structure as the current revision machinery.  You need\n2 x N bits (for the above example, 2 x 2 bits) per commit.\n\nI am not saying it is easy or we should start working on it, though\n;-).\n"}]}