{"thread":{"id":"27548","subject":"Command-line interface thoughts","startedAt":"2011-06-04T16:17:48Z","lastAt":"2011-06-14T07:51:18Z","messageCount":98,"participants":["Michael Nahas","Jakub Narebski","Scott Chacon","Paul Ebermann","Junio C Hamano","Michael J Gruber","Drew Northup","Jonathan Nieder","Holger Hellmuth","René Scharfe","Jeff King","Michael Haggerty","Andreas Ericsson","Thomas Rast","Jay Soffian","Miles Bader"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"169304","messageId":"BANLkTinTWG7YXGKZzmH0rqtt+Ob7X+2yMQ@mail.gmail.com","threadId":"27548","inReplyTo":"BANLkTikTWx7A64vN+hVZgL7cuiZ16Eobgg@mail.gmail.com","subject":"Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-04T16:17:48Z","receivedAt":"2011-06-04T16:17:48Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"Quick list of recommendations:\n\n1. Pick aliases for the next commit and the working tree that act like\ncommits on the command-line.\n2. Adopt a (semi-)formal notation for describing what commands do.\n3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\ntheir own command names\n4. Deemphasize the \"branch\" command for creating branches.\n\nA \"normal\" (long) email follows.  At the end are examples of commands\nin a not-quite-so-formal notation.\n\nI AM NOT ON THE MAILING LIST - PLEASE CC ME ON REPLIES.\n\n\n------------\n\nI was the primary designer of the PAR2 open file format and write a\nlot of big software (application-layer multicast, etc.).  I've been\nusing Git for 2 months.  I love it and I greatly admire the plumbing.\nHowever, the default \"porcelain\" has at times been more confusing than\nenlightening.\n\nI had some ideas about the porcelain and decided they were worth\nsending to the mailing list.  I ran the ideas by the two Git gurus who\nanswer my questions and they agreed with them.  I wish I had the time\nto implement them but I did PAR2 when I had time off and I'm working\nnow.  I apologize if any of these are repeats or have already been\ndiscussed to death.\n\n\nMy recommendations are:\n\n1. Pick aliases for the next commit and the working tree that act like\ncommits on the command-line.\n\nBy \"next commit\", I mean \"the commit that would be generated if the\n\"commit\" command was run right now\".  \"Next commit\" is not the same as\nthe index.  The index is a _file_ that serves multiple purposes.\n(Think of it's state during a conflicted merge.)  But the index does\nusually hold the files that change between HEAD and the next commit.\n\nFor the alias for the next commit and working tree, I suggest \"NEXT\"\nand \"WTREE\".  Creating these aliases will make the interface more\nregular. It will remove oddities like \"diff --cached FOO\" and replace\nthem with \"diff NEXT FOO\" and mean that \"diff\" and \"diff FOO\" can be\nexplained as \"diff WTREE NEXT\" and \"diff WTREE FOO\".\n\n\n2. Adopt a notation for describing what commands do.\n\nI am sure in developer discussions there are descriptions of the\n\"commit\" command as something like:\n   HEAD = new(HEAD + (NEXT-HEAD))\n   NEXT = HEAD\n\nWhere \"-\" creates a patch between versions and + applys a patch.  Git\nalready has some operators like \"^\", which refers to the parent of a\ncommit. Those are useful for defining things like \"commit --amend\":\n   HEAD = new(HEAD^ + (NEXT-HEAD^))\n   NEXT = HEAD\n\nHaving this notation and using it in the man pages will make the exact\nnature of the operation clear. (Right now, it takes a lot of reading\nto figure out what happens to NEXT with the various command-line\noptions of \"reset\".)\n\nCurrently, to understand what commands do, I use \"A Visual Git\nReference\", which has been extremely valuable to me. Kuddos to Mark\nLodato for it.\nhttp://marklodato.github.com/visual-git-guide/index-en.html\n\n[I've included git commands in a not-formal-enough notation at the end\nof this email.]\n\n\n3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\ntheir own command names\n\nThis is my biggest and most important suggestion.\n\n\"checkout -- foo.txt\" copies foo.txt from NEXT to WTREE. Similarly,\n\"reset -- foo.txt\" will copy foo.txt from HEAD to NEXT.\n\nThese are operations to designate/undesignate files in the next commit\nand should be grouped with others like them: \"add\", \"rm\" and \"mv\". (In\nfact, the man page for \"reset -- <file>\" even says that it is the\nopposite of \"add\"!)\n\nWhen these file-based operations are removed from \"checkout\" and\n\"reset\", the purposes of those commands becomes clearer: \"checkout\"\nchanges HEAD to a new branch and \"reset\" moves the current branch\npointer to a different commit.  These operations may share code with\nthe operations \"checkout -- <file>\" and \"reset -- <file>\", but they\nserve different purposes from the user's perspective and the user\nshould have different names to refer to them.\n\nAs for naming these new commands, the \"yet-another-porcelain\" renames\n\"reset -- <file>\" to \"unadd\", which I like very much.  For the other,\nmy best suggestion is \"head-to-next\", but I'm sure someone can do\nbetter.\n\n\n4. Deemphasize the \"branch\" command for creating branches.\n\nI assumed that the command \"branch\" was used for creating branches.\nAfter all, that's how it is done in the \"gittutorial(7)\" man page.\nHowever, after reviewing all the major commands, I find that it is the\n_last_ way I want to create a branch. It creates a new branch, but it\ndoesn't switch HEAD to the new branch!\n\nThe commands that should be emphasized are \"checkout -b <name>\",\n\"commit -b <name>\", and \"stash branch\".  These make sense in normal\ngit usage. The \"branch\" command has its uses but it is not usually the\nway you want to create a branch.\n\n\nThese are my suggestions.  I wish i had time to implement them, but\nI'm glad to help in the discussion of them.  I'm not on the mailing\nlist, so PLEASE CC ME WITH ANY REPLIES.\n\nMichael Nahas\n\n\n----\n\nThese are just some commands written in a not-quite-formal notation.\nThis notation doesn't handle a detached head, adding directories, the\nstate after a conflicted \"stash pop\", etc.  Still, as it is, I think\nit's very informative to users for getting the gist of what command\ndoes.\n\n\"add foo.txt\"\n   NEXT:foo.txt = WTREE:foo.txt\n\"rm foo.txt\"\n   delete(NEXT:foo.txt)\n   delete(WTREE:foo.txt)\n\"rm --cached foo.txt\"\n   delete(NEXT:foo.txt)\n\"/bin/rm foo.txt\"\n   delete(WTREE:foo.txt)\n\"mv foo.txt bar.txt\"\n   WTREE:bar.txt = WTREE:foo.txt\n   NEXT.bar.txt = WTREE:foo.txt\n   delete(WTREE:foo.txt)\n   delete(NEXT:foo.txt)\n\"checkout -- foo.txt\"\n   WTREE:foo.txt = NEXT:foo.txt\n\"reset -- foo.txt\"\n   NEXT:foo.txt = HEAD:foo.txt\n\n\"commit\"\n   HEAD = new(HEAD + (NEXT-HEAD))\n   NEXT = HEAD\n\"commit --amend\"\n   HEAD = new(HEAD^ + (NEXT-HEAD^))\n   NEXT = HEAD\n\n\"checkout FOO\" (prequires WTREE==NEXT==HEAD)\n   WTREE = FOO\n   NEXT = FOO\n   HEAD ::= FOO // changes the alias of HEAD to refer to FOO\n\n\"reset --soft FOO\"\n   HEAD = FOO // move branch; don't change alias\n\"reset --mixed FOO\" (the default)\n   NEXT = FOO\n   HEAD = FOO // move branch; don't change alias\n\"reset --hard FOO\"\n   WTREE = FOO\n   NEXT = FOO\n   HEAD = FOO // move branch; don't change alias\n\n\"stash save\"\n   STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)\n   NEXT = HEAD\n   WTREE = HEAD\n   push(STASH)\n\"stash pop\"\n   STASH = pop()\n   WTREE = HEAD + (STASH-STASH^^)\n   NEXT = HEAD + (STASH^-STASH^^)\n\n\"branch FOO\"\n   FOO = HEAD\n\"commit -b FOO\"\n   FOO = new(HEAD + (NEXT-HEAD))\n   NEXT = FOO\n   HEAD ::= FOO // change alias\n\"checkout -b FOO\" (prequires WTREE==NEXT==HEAD)\n   FOO = HEAD // create FOO and make it a copy of HEAD\n   WTREE = FOO\n   NEXT = FOO\n   HEAD ::= FOO // change alias\n\"stash branch FOO\"\n   STASH = pop()\n   FOO = STASH^^ // create FOO and make it a copy of STASH^^\n   NEXT = STASH^\n   WTREE = STASH\n   HEAD ::= FOO // change alias\n\n\"merge FOO\" (prequires NEXT=HEAD)\n   [ANC is the nearest common ancestor]\n   WTREE = ANC + (WTREE - ANC) + (FOO-ANC)\n   NEXT = ANC + (HEAD - ANC) + (FOO-ANC)\n   HEAD = new(HEAD + (NEXT-HEAD))\n   NEXT = HEAD\n\"cherry-pick FOO\" (prequires WTREE==NEXT==HEAD)\n   HEAD = new(HEAD + (FOO - FOO^))\n   NEXT = HEAD\n   WTREE = HEAD\n\"rebase FOO\" is basically a iterated application of \"cherry-pick\"\n"},{"id":"169309","messageId":"m339jps1wt.fsf@localhost.localdomain","threadId":"27548","inReplyTo":"BANLkTinTWG7YXGKZzmH0rqtt+Ob7X+2yMQ@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-04T21:49:53Z","receivedAt":"2011-06-04T21:49:53Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Michael Nahas <mike.nahas@gmail.com> writes:\n\n> Quick list of recommendations:\n> \n> 1. Pick aliases for the next commit and the working tree that act like\n>    commits on the command-line.\n\nNo go.  This was asked for many times, and each time shot down.\nThose \"aliases\" / pseudo-refs looks like commits but do not behave\nexactly like commits.  This would increase connfusion.\n\nSee also gitcli(7) manpage for description of --index and --cached\noptions (and other git command line conventions).\n\n> 2. Adopt a (semi-)formal notation for describing what commands do.\n\nWhom it would help?  Not an ordinary user.\n\n> 3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\n>    their own command names\n\nProposed \"git unadd <pathspec>...\" doesn't cover all features of\n\"git reset <rev> -- <path>\" nor \"git checkout [<rev>] -- <path>\".\n\n> 4. Deemphasize the \"branch\" command for creating branches.\n\nOr add \"git branch --checkout <newbranch>\".\n\n> \n> A \"normal\" (long) email follows.  At the end are examples of commands\n> in a not-quite-so-formal notation.\n \n> ------------\n> \n> I was the primary designer of the PAR2 open file format and write a\n> lot of big software (application-layer multicast, etc.).  I've been\n> using Git for 2 months.  I love it and I greatly admire the plumbing.\n> However, the default \"porcelain\" has at times been more confusing than\n> enlightening.\n\nBTW. have you read gitcli(7) manpage?\n \n> I had some ideas about the porcelain and decided they were worth\n> sending to the mailing list.  I ran the ideas by the two Git gurus who\n> answer my questions and they agreed with them.  I wish I had the time\n> to implement them but I did PAR2 when I had time off and I'm working\n> now.  I apologize if any of these are repeats or have already been\n> discussed to death.\n> \n> \n> My recommendations are:\n> \n> 1. Pick aliases for the next commit and the working tree that act like\n> commits on the command-line.\n> \n> By \"next commit\", I mean \"the commit that would be generated if the\n> \"commit\" command was run right now\".  \"Next commit\" is not the same as\n> the index.  The index is a _file_ that serves multiple purposes.\n> (Think of it's state during a conflicted merge.)  But the index does\n> usually hold the files that change between HEAD and the next commit.\n> \n> For the alias for the next commit and working tree, I suggest \"NEXT\"\n> and \"WTREE\".  Creating these aliases will make the interface more\n> regular. It will remove oddities like \"diff --cached FOO\" and replace\n> them with \"diff NEXT FOO\" and mean that \"diff\" and \"diff FOO\" can be\n> explained as \"diff WTREE NEXT\" and \"diff WTREE FOO\".\n \nThis idea ws proposed multiple time on git mailing list, and every\ntime it was rejected.\n\nThe problem is first, that you make INDEX / STAGE / NEXT and \nWORK / WTREE *look* like commits (like pseudo symbolic refs), while\nthey do not *behave* like commits.\n \n\"git show HEAD\" looks differently from \"git show NEXT\" or \"git show WTREE\".\nNeither the index now working tree have a parent, or author, or commit\nmessage.  The index (staging area) can have stages, though you sidestep\nthis issue by handwaving it away.  Working area has notion of tracked,\nuntracked ignored and untracked not ignored (other) files.   Etc., etc.\n\nBTW. both index and worktree have their own \"aliases\", namely ':0:'\nfor index (stage 0), and ':' or ':/' for top tree.\n\n\nSecond, it doesn't solve issue of needing --cached and/or --index\nswiches completely.  Those pseudo-almost-refs hide them for \"git diff\",\n\"git grep\", \"git ls-files\", perhaps \"git submodule\" where we *read*\nfrom index, but not for \"git apply\", \"git rm\" or \"git stash\" where\nthose swicthes affect *writing*.\n\n> 2. Adopt a notation for describing what commands do.\n> \n> I am sure in developer discussions there are descriptions of the\n> \"commit\" command as something like:\n>    HEAD = new(HEAD + (NEXT-HEAD))\n>    NEXT = HEAD\n\nBasic algebra fail\n\n  HEAD + (NEXT-HEAD) == NEXT\n\nBesides \"git commit\" creates commit from state of index, no diffing or\npatching is involved.\n\n> Where \"-\" creates a patch between versions and + applies a patch.  Git\n> already has some operators like \"^\", which refers to the parent of a\n> commit. Those are useful for defining things like \"commit --amend\":\n>    HEAD = new(HEAD^ + (NEXT-HEAD^))\n>    NEXT = HEAD\n\nWhich is again not true.\n \n> Having this notation and using it in the man pages will make the exact\n> nature of the operation clear. (Right now, it takes a lot of reading\n> to figure out what happens to NEXT with the various command-line\n> options of \"reset\".)\n\nIt's not that difficult: only \"git reset --soft [<rev>]\" doesn't\naffect index.\n\nHrmmm... how this notation would explain differences between \n\"git reset --hard\", \"git reset --keep\" and \"git reset --merge\"?\n\n> \n> Currently, to understand what commands do, I use \"A Visual Git\n> Reference\", which has been extremely valuable to me. Kuddos to Mark\n> Lodato for it.\n> http://marklodato.github.com/visual-git-guide/index-en.html\n\nUnfortunately manpages cannot really include images.  Well, there is\nsome kind of obscure graph description language for manpages ('dot' or\nsomething like that), supposedly, IIRC...\n\n> \n> [I've included git commands in a not-formal-enough notation at the end\n> of this email.]\n \nNEVERTHELESS some kind of semi-formal notation might be useful.\n \n> 3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\n> their own command names\n> \n> This is my biggest and most important suggestion.\n> \n> \"checkout -- foo.txt\" copies foo.txt from NEXT to WTREE. Similarly,\n> \"reset -- foo.txt\" will copy foo.txt from HEAD to NEXT.\n\n  \"checkout HEAD -- foo.txt\" copies foo.txt from HEAD to NEXT and WTREE\n\n  \"checkout HEAD^ -- foo.txt\" copies foo.txt from HEAD^ to NEXT and WTREE\n  \"reset HEAD^ -- foo.txt\" copies foo.txt from HEAD^ to NEXT\n \n> These are operations to designate/undesignate files in the next commit\n> and should be grouped with others like them: \"add\", \"rm\" and \"mv\". (In\n> fact, the man page for \"reset -- <file>\" even says that it is the\n> opposite of \"add\"!)\n> \n> When these file-based operations are removed from \"checkout\" and\n> \"reset\", the purposes of those commands becomes clearer: \"checkout\"\n> changes HEAD to a new branch and \"reset\" moves the current branch\n> pointer to a different commit.  These operations may share code with\n> the operations \"checkout -- <file>\" and \"reset -- <file>\", but they\n> serve different purposes from the user's perspective and the user\n> should have different names to refer to them.\n> \n> As for naming these new commands, the \"yet-another-porcelain\" renames\n> \"reset -- <file>\" to \"unadd\", which I like very much.\n\nWell, that goes counter to reducing number of commands, but I quite\nlike this name.  Though \"unadd <revision> -- <file>\" looks a bit\nstrange...\n\n> For the other, my best suggestion is \"head-to-next\", but I'm sure\n> someone can do better.\n\nI'd rather remember that \"git checkout\" is about checking out\nsomething to a working area.\n \n> \n> 4. Deemphasize the \"branch\" command for creating branches.\n> \n> I assumed that the command \"branch\" was used for creating branches.\n> After all, that's how it is done in the \"gittutorial(7)\" man page.\n\nIt _is_ used to create branches.  But perhaps we should update\ngittutorial(7) (and check users manual)...\n\n> However, after reviewing all the major commands, I find that it is the\n> _last_ way I want to create a branch. It creates a new branch, but it\n> doesn't switch HEAD to the new branch!\n\n\"checkout -b\" is just shortcut for \"branch\" + \"checkout\".  Very\nconvenient one, that is...\n\n> \n> The commands that should be emphasized are \"checkout -b <name>\",\n> \"commit -b <name>\", and \"stash branch\".  These make sense in normal\n> git usage. The \"branch\" command has its uses but it is not usually the\n> way you want to create a branch.\n[...]\n\n> ----\n> \n> These are just some commands written in a not-quite-formal notation.\n> This notation doesn't handle a detached head, adding directories, the\n> state after a conflicted \"stash pop\", etc.  Still, as it is, I think\n> it's very informative to users for getting the gist of what command\n> does.\n> \n> \"add foo.txt\"\n>    NEXT:foo.txt = WTREE:foo.txt\n\nWhat about \"add --intent-to-add foo.txt\"?  What about \"add <directory>\"?\nWhat about resolving merge conflicts?\n\n> \"rm foo.txt\"\n>    delete(NEXT:foo.txt)\n>    delete(WTREE:foo.txt)\n> \"rm --cached foo.txt\"\n>    delete(NEXT:foo.txt)\n> \"/bin/rm foo.txt\"\n>    delete(WTREE:foo.txt)\n\nO.K.  Note however that \"git rm foo.txt\" on conflicted entry would\nclean up conflict.\n\n> \"mv foo.txt bar.txt\"\n>    WTREE:bar.txt = WTREE:foo.txt\n>    NEXT.bar.txt = WTREE:foo.txt\n>    delete(WTREE:foo.txt)\n>    delete(NEXT:foo.txt)\n\nO.K., but what is important are atomicity and safety checks.\n\n> \"checkout -- foo.txt\"\n>    WTREE:foo.txt = NEXT:foo.txt\n> \"reset -- foo.txt\"\n>    NEXT:foo.txt = HEAD:foo.txt\n\nThose are not the only modes.\n\n> \"commit\"\n>    HEAD = new(HEAD + (NEXT-HEAD))\n>    NEXT = HEAD\n\n   HEAD + (NEXT-HEAD) == NEXT\n\n\"git commit\" doesn't apply patches.\n\n> \"commit --amend\"\n>    HEAD = new(HEAD^ + (NEXT-HEAD^))\n>    NEXT = HEAD\n\n  HEAD^ + (NEXT-HEAD^) == NEXT\n\n\"git commit --amend\" works correctly even if HEAD is a merge commit!\n\n> \n> \"checkout FOO\" (prequires WTREE==NEXT==HEAD)\n\nNo such requirement.  It's all about which files differ between HEAD\nand FOO.  If you start working on some file, and decide that you\nshould have made the change on different branch, \"git checkout FOO\"\nallow to move to FOO branch... assuming that changed file has the same\ncontents in HEAD and in FOO.\n\nEnd there is \"checkout -f\" and \"checkout -m\".\n\n>    WTREE = FOO\n>    NEXT = FOO\n>    HEAD ::= FOO // changes the alias of HEAD to refer to FOO\n\nAnd this is supposed to be easier to understand?\n\n\n> \"stash save\"\n>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)\n>    NEXT = HEAD\n>    WTREE = HEAD\n>    push(STASH)\n> \"stash pop\"\n>    STASH = pop()\n>    WTREE = HEAD + (STASH-STASH^^)\n>    NEXT = HEAD + (STASH^-STASH^^)\n\n???\n\n[...] \n> \"cherry-pick FOO\" (prequires WTREE==NEXT==HEAD)\n>    HEAD = new(HEAD + (FOO - FOO^))\n>    NEXT = HEAD\n>    WTREE = HEAD\n> \"rebase FOO\" is basically a iterated application of \"cherry-pick\"\n\nOrdinary rebase isn't.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"169310","messageId":"BANLkTinidLbQ_FcVEiGSK91uXYWaKk7MKA@mail.gmail.com","threadId":"27548","inReplyTo":"m339jps1wt.fsf@localhost.localdomain","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-05T01:00:33Z","receivedAt":"2011-06-05T01:00:33Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"Thanks for your reply, Jakub.\n\nOn Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:\n> Michael Nahas <mike.nahas@gmail.com> writes:\n>\n>> Quick list of recommendations:\n>>\n>> 1. Pick aliases for the next commit and the working tree that act like\n>>    commits on the command-line.\n>\n> No go.  This was asked for many times, and each time shot down.\n> Those \"aliases\" / pseudo-refs looks like commits but do not behave\n> exactly like commits.  This would increase connfusion.\n\nI'm glad it was discussed.  I think users would know that those\ncommits were special (they are writeable after all), but I'm sure more\ninformed people than I made the same arguments.\n\n> See also gitcli(7) manpage for description of --index and --cached\n> options (and other git command line conventions).\n\nThanks for the pointer.  I've now read it.\n\n>> 2. Adopt a (semi-)formal notation for describing what commands do.\n>\n> Whom it would help?  Not an ordinary user.\n\nI think it would help experts in discussing exactly what happens.  For\nordinary users that are hitting an intricate case (or don't know\nEnglish very well), it would be good if there was something that would\ntell them mathematically what occurs.\n\n>> 3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\n>>    their own command names\n>\n> Proposed \"git unadd <pathspec>...\" doesn't cover all features of\n> \"git reset <rev> -- <path>\" nor \"git checkout [<rev>] -- <path>\".\n\nI'm confused.  How can it not cover all the features?  I'm just\nsuggesting renaming the command.  From \"git reset -- <path>\" to \"git\nunadd [--] <path>\".  (And renaming \"git checkout -- <path>\" to some\nyet-to-be-named other command.)\n\n>> 4. Deemphasize the \"branch\" command for creating branches.\n>\n> Or add \"git branch --checkout <newbranch>\".\n\nWould that operation be the different from the existing \"git checkout\n-b <new branch>\", or just another way to write it?\n\n>> A \"normal\" (long) email follows.  At the end are examples of commands\n>> in a not-quite-so-formal notation.\n>\n>> ------------\n>>\n>> I was the primary designer of the PAR2 open file format and write a\n>> lot of big software (application-layer multicast, etc.).  I've been\n>> using Git for 2 months.  I love it and I greatly admire the plumbing.\n>> However, the default \"porcelain\" has at times been more confusing than\n>> enlightening.\n>\n> BTW. have you read gitcli(7) manpage?\n\nI have now.  I'd swear I've read close to 30 manpages but never\nheard-of/noticed that one until you mentioned it.  Thanks for the\npointer; it's good to have --index and --cached clarified.\n\n>> I had some ideas about the porcelain and decided they were worth\n>> sending to the mailing list.  I ran the ideas by the two Git gurus who\n>> answer my questions and they agreed with them.  I wish I had the time\n>> to implement them but I did PAR2 when I had time off and I'm working\n>> now.  I apologize if any of these are repeats or have already been\n>> discussed to death.\n>>\n>>\n>> My recommendations are:\n>>\n>> 1. Pick aliases for the next commit and the working tree that act like\n>> commits on the command-line.\n>>\n>> By \"next commit\", I mean \"the commit that would be generated if the\n>> \"commit\" command was run right now\".  \"Next commit\" is not the same as\n>> the index.  The index is a _file_ that serves multiple purposes.\n>> (Think of it's state during a conflicted merge.)  But the index does\n>> usually hold the files that change between HEAD and the next commit.\n>>\n>> For the alias for the next commit and working tree, I suggest \"NEXT\"\n>> and \"WTREE\".  Creating these aliases will make the interface more\n>> regular. It will remove oddities like \"diff --cached FOO\" and replace\n>> them with \"diff NEXT FOO\" and mean that \"diff\" and \"diff FOO\" can be\n>> explained as \"diff WTREE NEXT\" and \"diff WTREE FOO\".\n>\n> This idea ws proposed multiple time on git mailing list, and every\n> time it was rejected.\n>\n> The problem is first, that you make INDEX / STAGE / NEXT and\n> WORK / WTREE *look* like commits (like pseudo symbolic refs), while\n> they do not *behave* like commits.\n>\n> \"git show HEAD\" looks differently from \"git show NEXT\" or \"git show WTREE\".\n> Neither the index now working tree have a parent, or author, or commit\n> message.  The index (staging area) can have stages, though you sidestep\n> this issue by handwaving it away.  Working area has notion of tracked,\n> untracked ignored and untracked not ignored (other) files.   Etc., etc.\n\nI knew of some of these issues and I agree that I was handwaving them\naway.  I didn't have all the answers and certainly didn't want to\nappear to be claiming to have them.  I assumed that if the idea had\nmerit that these issues could be worked out.\n\nThat this idea has been brought up multiple times says that it does\nhave some merit.  But apparently not enough merit.\n\n> BTW. both index and worktree have their own \"aliases\", namely ':0:'\n> for index (stage 0), and ':' or ':/' for top tree.\n\nReally?  Where can these aliases be used?\n\n> Second, it doesn't solve issue of needing --cached and/or --index\n> swiches completely.  Those pseudo-almost-refs hide them for \"git diff\",\n> \"git grep\", \"git ls-files\", perhaps \"git submodule\" where we *read*\n> from index, but not for \"git apply\", \"git rm\" or \"git stash\" where\n> those swicthes affect *writing*.\n\nI agree with you that it would not get rid of all switches.  I never\nexpected it to.  My major aim was to simplify things like the \"diff\"\ncommand, which I have trouble remembering the different variations of.\n\n>> 2. Adopt a notation for describing what commands do.\n>>\n>> I am sure in developer discussions there are descriptions of the\n>> \"commit\" command as something like:\n>>    HEAD = new(HEAD + (NEXT-HEAD))\n>>    NEXT = HEAD\n>\n> Basic algebra fail\n>\n>  HEAD + (NEXT-HEAD) == NEXT\n>\n> Besides \"git commit\" creates commit from state of index, no diffing or\n> patching is involved.\n\nI would claim that the \"state of index\" is an approximation of\n(NEXT-HEAD).  Also, the new Tree and Blob objects that get written\nduring the commit are another approximation of (NEXT-HEAD).  Neither\nof these is exactly a patch applied to HEAD, but that's the intent I\nwas going for with my algebraic identity.  (It's not a fail; it's an\nunoptimization!)\n\n>> Where \"-\" creates a patch between versions and + applies a patch.  Git\n>> already has some operators like \"^\", which refers to the parent of a\n>> commit. Those are useful for defining things like \"commit --amend\":\n>>    HEAD = new(HEAD^ + (NEXT-HEAD^))\n>>    NEXT = HEAD\n>\n> Which is again not true.\n\n[Addressed below, where the \"what if HEAD is a merge commit with\nmultiple predecessors\" is mentioned.]\n\n>> Having this notation and using it in the man pages will make the exact\n>> nature of the operation clear. (Right now, it takes a lot of reading\n>> to figure out what happens to NEXT with the various command-line\n>> options of \"reset\".)\n>\n> It's not that difficult: only \"git reset --soft [<rev>]\" doesn't\n> affect index.\n>\n> Hrmmm... how this notation would explain differences between\n> \"git reset --hard\", \"git reset --keep\" and \"git reset --merge\"?\n\nI don't understand what \"git reset --keep\" and \"git reset --merge\" do.\n I've read the manpage but am still confused.  One of my reasons for\nsuggesting a notation is so that there is a clear mathematical\nrepresentation of what the commands do.  Once I understand them, I can\nmake an attempt at a notation that can explain them.\n\n>> Currently, to understand what commands do, I use \"A Visual Git\n>> Reference\", which has been extremely valuable to me. Kuddos to Mark\n>> Lodato for it.\n>> http://marklodato.github.com/visual-git-guide/index-en.html\n>\n> Unfortunately manpages cannot really include images.  Well, there is\n> some kind of obscure graph description language for manpages ('dot' or\n> something like that), supposedly, IIRC...\n\nThe manpage for \"git checkout\" has some ASCII art of commit DAGs.\nIt's almost there...\n\n>> [I've included git commands in a not-formal-enough notation at the end\n>> of this email.]\n>\n> NEVERTHELESS some kind of semi-formal notation might be useful.\n\nI'm glad you agree.  Do you think my not-formal-enough notation is a\ngood start or do you want to propose another notation to start from?\n\n>> 3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\n>> their own command names\n>>\n>> This is my biggest and most important suggestion.\n>>\n>> \"checkout -- foo.txt\" copies foo.txt from NEXT to WTREE. Similarly,\n>> \"reset -- foo.txt\" will copy foo.txt from HEAD to NEXT.\n>\n>  \"checkout HEAD -- foo.txt\" copies foo.txt from HEAD to NEXT and WTREE\n>\n>  \"checkout HEAD^ -- foo.txt\" copies foo.txt from HEAD^ to NEXT and WTREE\n>  \"reset HEAD^ -- foo.txt\" copies foo.txt from HEAD^ to NEXT\n>\n>> These are operations to designate/undesignate files in the next commit\n>> and should be grouped with others like them: \"add\", \"rm\" and \"mv\". (In\n>> fact, the man page for \"reset -- <file>\" even says that it is the\n>> opposite of \"add\"!)\n>>\n>> When these file-based operations are removed from \"checkout\" and\n>> \"reset\", the purposes of those commands becomes clearer: \"checkout\"\n>> changes HEAD to a new branch and \"reset\" moves the current branch\n>> pointer to a different commit.  These operations may share code with\n>> the operations \"checkout -- <file>\" and \"reset -- <file>\", but they\n>> serve different purposes from the user's perspective and the user\n>> should have different names to refer to them.\n>>\n>> As for naming these new commands, the \"yet-another-porcelain\" renames\n>> \"reset -- <file>\" to \"unadd\", which I like very much.\n>\n> Well, that goes counter to reducing number of commands, but I quite\n> like this name.  Though \"unadd <revision> -- <file>\" looks a bit\n> strange...\n\nI agree, that does look strange.  I think it would be the far less\nfrequent usage, but still strange.\n\n>> For the other, my best suggestion is \"head-to-next\", but I'm sure\n>> someone can do better.\n>\n> I'd rather remember that \"git checkout\" is about checking out\n> something to a working area.\n\nNow that I've separated these two usages of \"checkout\" in my brain,\n\"git checkout <branch>\" is all about changing to a different branch.\nThat files in the working tree change is just incidental to moving to\nthe new branch.\n\nThe manpage paragraph for \"git checkout -- <file>\" has in bold that\nthis usage \"does not switch branches\".  So, for me, it's a completely\ndifferent usage and should be a different command.\n\nI wish I had a reasonable name to suggest for the new command.\n\n>> 4. Deemphasize the \"branch\" command for creating branches.\n>>\n>> I assumed that the command \"branch\" was used for creating branches.\n>> After all, that's how it is done in the \"gittutorial(7)\" man page.\n>\n> It _is_ used to create branches.  But perhaps we should update\n> gittutorial(7) (and check users manual)...\n\nThank you.\n\n>> However, after reviewing all the major commands, I find that it is the\n>> _last_ way I want to create a branch. It creates a new branch, but it\n>> doesn't switch HEAD to the new branch!\n>\n> \"checkout -b\" is just shortcut for \"branch\" + \"checkout\".  Very\n> convenient one, that is...\n\nYes, it's my primary way of making a branch now.\n\n>> The commands that should be emphasized are \"checkout -b <name>\",\n>> \"commit -b <name>\", and \"stash branch\".  These make sense in normal\n>> git usage. The \"branch\" command has its uses but it is not usually the\n>> way you want to create a branch.\n> [...]\n>\n>> ----\n>>\n>> These are just some commands written in a not-quite-formal notation.\n>> This notation doesn't handle a detached head, adding directories, the\n>> state after a conflicted \"stash pop\", etc.  Still, as it is, I think\n>> it's very informative to users for getting the gist of what command\n>> does.\n>>\n>> \"add foo.txt\"\n>>    NEXT:foo.txt = WTREE:foo.txt\n>\n> What about \"add --intent-to-add foo.txt\"?  What about \"add <directory>\"?\n> What about resolving merge conflicts?\n\nGood points.  These are all interesting cases that a fully developed\nformal notation should make sure to address.\n\n>> \"rm foo.txt\"\n>>    delete(NEXT:foo.txt)\n>>    delete(WTREE:foo.txt)\n>> \"rm --cached foo.txt\"\n>>    delete(NEXT:foo.txt)\n>> \"/bin/rm foo.txt\"\n>>    delete(WTREE:foo.txt)\n>\n> O.K.  Note however that \"git rm foo.txt\" on conflicted entry would\n> clean up conflict.\n\nYes.  \"git add foo.txt\" is also used to resolve conflicts.\n\n>> \"mv foo.txt bar.txt\"\n>>    WTREE:bar.txt = WTREE:foo.txt\n>>    NEXT.bar.txt = WTREE:foo.txt\n>>    delete(WTREE:foo.txt)\n>>    delete(NEXT:foo.txt)\n>\n> O.K., but what is important are atomicity and safety checks.\n\nI think it's best to assume every operation is done atomically.\n(Right?)   I'm not sure how to denote safety checks or prerequisites.\n\n>> \"checkout -- foo.txt\"\n>>    WTREE:foo.txt = NEXT:foo.txt\n>> \"reset -- foo.txt\"\n>>    NEXT:foo.txt = HEAD:foo.txt\n>\n> Those are not the only modes.\n>\n>> \"commit\"\n>>    HEAD = new(HEAD + (NEXT-HEAD))\n>>    NEXT = HEAD\n>\n>   HEAD + (NEXT-HEAD) == NEXT\n>\n> \"git commit\" doesn't apply patches.\n\nAgreed.  I addressed this above.\n\n>> \"commit --amend\"\n>>    HEAD = new(HEAD^ + (NEXT-HEAD^))\n>>    NEXT = HEAD\n>\n>  HEAD^ + (NEXT-HEAD^) == NEXT\n>\n> \"git commit --amend\" works correctly even if HEAD is a merge commit!\n\nAnother good issue.  A formal notation will need to specify how to\ndeal with cases of a commit with more than one predecessor.\n\n>> \"checkout FOO\" (prequires WTREE==NEXT==HEAD)\n>\n> No such requirement.  It's all about which files differ between HEAD\n> and FOO.  If you start working on some file, and decide that you\n> should have made the change on different branch, \"git checkout FOO\"\n> allow to move to FOO branch... assuming that changed file has the same\n> contents in HEAD and in FOO.\n\nOkay.  I will have to think about how a formal notation can denote that...\n\n> End there is \"checkout -f\" and \"checkout -m\".\n>\n>>    WTREE = FOO\n>>    NEXT = FOO\n>>    HEAD ::= FOO // changes the alias of HEAD to refer to FOO\n>\n> And this is supposed to be easier to understand?\n\n\"checkout\" is a very simple command to describe in English, so the\nmathematical description will be more convoluted.  I don't (yet)\nunderstand some of the variants of \"git reset\" even though they are\nwritten in English.  I'm hoping a formal notation will make them\neasier to understand.\n\n>> \"stash save\"\n>>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)\n>>    NEXT = HEAD\n>>    WTREE = HEAD\n>>    push(STASH)\n>> \"stash pop\"\n>>    STASH = pop()\n>>    WTREE = HEAD + (STASH-STASH^^)\n>>    NEXT = HEAD + (STASH^-STASH^^)\n>\n> ???\n\n\"stash save\" makes two new consecutive commits: one equal to NEXT and\nanother equal to WTREE.  (This is \"STASH\" above, with my\nunoptimizations.)  I don't know where the SHA of the final commit gets\nstored, so I just created push() and pop() commands.\n\nRereading the man page, the commit containing WTREE has two parents.\nThis notation doesn't have a way to denote that.\n\n> [...]\n>> \"cherry-pick FOO\" (prequires WTREE==NEXT==HEAD)\n>>    HEAD = new(HEAD + (FOO - FOO^))\n>>    NEXT = HEAD\n>>    WTREE = HEAD\n>> \"rebase FOO\" is basically a iterated application of \"cherry-pick\"\n>\n> Ordinary rebase isn't.\n>\n> --\n> Jakub Narebski\n> Poland\n> ShadeHawk on #git\n>\n\nJakub, thanks again for taking the time to respond.\n"},{"id":"169315","messageId":"201106051311.00951.jnareb@gmail.com","threadId":"27548","inReplyTo":"BANLkTinidLbQ_FcVEiGSK91uXYWaKk7MKA@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-05T11:10:56Z","receivedAt":"2011-06-05T11:10:56Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sun, 5 Jun 2011, Michael Nahas wrote:\n> On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:\n>> Michael Nahas <mike.nahas@gmail.com> writes:\n>>\n>>> Quick list of recommendations:\n>>>\n>>> 1. Pick aliases for the next commit and the working tree that act like\n>>>    commits on the command-line.\n>>\n>> No go.  This was asked for many times, and each time shot down.\n>> Those \"aliases\" / pseudo-refs looks like commits but do not behave\n>> exactly like commits.  This would increase connfusion.\n> \n> I'm glad it was discussed.  I think users would know that those\n> commits were special (they are writeable after all), but I'm sure more\n> informed people than I made the same arguments.\n\nPerhaps we should add conclusion / summary of this discussion either\nsomewhere on git wiki (http://git.wiki.kernel.org), or e.g. on gitcli(7)\nmanpage, so that it won't get reiterated again and again.  It is sort\nof frequently asked question^W request.\n \n>> See also gitcli(7) manpage for description of --index and --cached\n>> options (and other git command line conventions).\n> \n> Thanks for the pointer.  I've now read it.\n[...]\n>> BTW. have you read gitcli(7) manpage?\n> \n> I have now.  I'd swear I've read close to 30 manpages but never\n> heard-of/noticed that one until you mentioned it.  Thanks for the\n> pointer; it's good to have --index and --cached clarified.\n\nHmmm... gitcli(7) is linked only from git(1) and git-rev-parse(1)\nmanpages.  Perhaps link to it should be added to user-manual at\nleast, to make it easier to find?\n\n>>> 2. Adopt a (semi-)formal notation for describing what commands do.\n>>\n>> Whom it would help?  Not an ordinary user.\n> \n> I think it would help experts in discussing exactly what happens.  For\n> ordinary users that are hitting an intricate case (or don't know\n> English very well), it would be good if there was something that would\n> tell them mathematically what occurs.\n\nWell, semi-formal notation could help, but I am not sure if it would\nreally be easier to understand than textual description.\n\nThere is also kind of \"meta\" problem: people who do not understand\nEnglish well instead of not understanding textual description of git\nbehavior would now not understand explanation of said formal notation.\n\n  Cargill's quandary: \"any design problem can be solved by adding an\n  additional level of indirection, except for too many levels of\n  indirection.\"\n\n;-)\n\n>>> 3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\n>>>    their own command names\n>>\n>> Proposed \"git unadd <pathspec>...\" doesn't cover all features of\n>> \"git reset <rev> -- <path>\" nor \"git checkout [<rev>] -- <path>\".\n> \n> I'm confused.  How can it not cover all the features?  I'm just\n> suggesting renaming the command.  From \"git reset -- <path>\" to \"git\n> unadd [--] <path>\".\n\nWhat about (well, more rarely used) \"git reset <commit> -- <path>\"?\nBut I quite like \"git unadd\" alias, even if \"git unadd <commit> <path>\"\nlooks strange; we have precedent in the form of \"git stage\" command\n(alias).\n\n> (And renaming \"git checkout -- <path>\" to some \n> yet-to-be-named other command.)\n\nI think this one could be left as is, at least until a really good name\nfor said replacement appears (\"git revert\" means something else, and\n\"git revert-file\" is a bit long, and can be confused with currently\nnot existing but proposed and discussed \"git revert <revision> <pathspec>\".)\n \n>>> 4. Deemphasize the \"branch\" command for creating branches.\n>>\n>> Or add \"git branch --checkout <newbranch>\".\n> \n> Would that operation be the different from the existing \"git checkout\n> -b <new branch>\", or just another way to write it?\n\nNo, it would be just another way to do it.\n\n\n>>> My recommendations are:\n>>>\n>>> 1. Pick aliases for the next commit and the working tree that act like\n>>> commits on the command-line.\n[...]\n>>> For the alias for the next commit and working tree, I suggest \"NEXT\"\n>>> and \"WTREE\".  Creating these aliases will make the interface more\n>>> regular. It will remove oddities like \"diff --cached FOO\" and replace\n>>> them with \"diff NEXT FOO\" and mean that \"diff\" and \"diff FOO\" can be\n>>> explained as \"diff WTREE NEXT\" and \"diff WTREE FOO\".\n>>\n>> This idea ws proposed multiple time on git mailing list, and every\n>> time it was rejected.\n[...]\n> That this idea has been brought up multiple times says that it does\n> have some merit.  But apparently not enough merit.\n\nNo, this only means that people *think* it has merit.  And perhaps\nthat they are poisoned by Subversion's pseudo-refs ;-P \n \n>> BTW. both index and worktree have their own \"aliases\", namely ':0:'\n>> for index (stage 0), and ':' or ':/' for top tree.\n> \n> Really?  Where can these aliases be used?\n\nWell, actually they _currently_ cannot be used in many places.\n\nYou can view version of file as it is in the index with\n\n  $ git show :0:path/to/file\n\nYou can add file from a top of project directory (given new enough git;\nI think it isn't in any released git version yet) with\n\n  $ git add :/path/to/file\n\nindependently on subdirectory you are in (i.e. --full-tree).\n\n\nBut the main point was meant to be that even if there was some merit\nto the pseudo-tree-ish aliases, ':0:' or '::' or ':0' would be better\nthat NEXT / STAGE / INDEX that looks like symbolic refs and therefore\ncommits but ain't, and ':/' would be better that WORK / WTREE.\n\nI'm sorry, I should have written it more clearly.\n \n>> Second, it doesn't solve issue of needing --cached and/or --index\n>> swiches completely.  Those pseudo-almost-refs hide them for \"git diff\",\n>> \"git grep\", \"git ls-files\", perhaps \"git submodule\" where we *read*\n>> from index, but not for \"git apply\", \"git rm\" or \"git stash\" where\n>> those swicthes affect *writing*.\n> \n> I agree with you that it would not get rid of all switches.  I never\n> expected it to.  My major aim was to simplify things like the \"diff\"\n> command, which I have trouble remembering the different variations of.\n\nYou miss the point of this.  The issue is that you have to learn about\n'--cached' and '--index' *anyway* (because pseudo-almost-refs do not\nsolve everything), and for consistency and backward compatibility we\nneed to support '--cached' for \"git diff\" etc., so you proposal brings\nnothing but new thing to learn (and not only syntax, but quirks as well).\n\nSo you only add to required knowledgebase, not reduce it.\n\n>>> 2. Adopt a notation for describing what commands do.\n>>>\n>>> I am sure in developer discussions there are descriptions of the\n>>> \"commit\" command as something like:\n>>>    HEAD = new(HEAD + (NEXT-HEAD))\n>>>    NEXT = HEAD\n>>\n>> Basic algebra fail\n>>\n>>  HEAD + (NEXT-HEAD) == NEXT\n>>\n>> Besides \"git commit\" creates commit from state of index, no diffing or\n>> patching is involved.\n> \n> I would claim that the \"state of index\" is an approximation of\n> (NEXT-HEAD).  Also, the new Tree and Blob objects that get written\n> during the commit are another approximation of (NEXT-HEAD).  Neither\n> of these is exactly a patch applied to HEAD, but that's the intent I\n> was going for with my algebraic identity.  (It's not a fail; it's an\n> unoptimization!)\n\nIt's still fail.  Git is at its repository model _snapshot_ based, not\n_changeset_ (delta) based.  \"git commit\" takes _exact_ state of index,\nand does not care about HEAD version.  Nb. your case does not cover\ncreating root commit (including but not limited to initial commit).\n\nIf you want to describe what \"git commit\" does it would be:\n\n  commit = new Commit\n  commit^{tree} = :0:       # or NEXT\n  commit^ = HEAD^{commit}   # i.e. HEAD, but be more explicit\n  HEAD@ = commit            # or @{0}, i.e. branch pointed by HEAD\n                            # or HEAD itself if it is detached (no branch)\n \nThe above does not cover commit message, author and committer info,\nand in some cases 'encoding' header (for commit message).\n\n>>> Where \"-\" creates a patch between versions and + applies a patch.  Git\n>>> already has some operators like \"^\", which refers to the parent of a\n>>> commit. Those are useful for defining things like \"commit --amend\":\n>>>    HEAD = new(HEAD^ + (NEXT-HEAD^))\n>>>    NEXT = HEAD\n>>\n>> Which is again not true.\n\nAgain, snapshot, not delta.\n \n> [Addressed below, where the \"what if HEAD is a merge commit with\n> multiple predecessors\" is mentioned.]\n> \n>>> Having this notation and using it in the man pages will make the exact\n>>> nature of the operation clear. (Right now, it takes a lot of reading\n>>> to figure out what happens to NEXT with the various command-line\n>>> options of \"reset\".)\n>>\n>> It's not that difficult: only \"git reset --soft [<rev>]\" doesn't\n>> affect index.\n>>\n>> Hrmmm... how this notation would explain differences between\n>> \"git reset --hard\", \"git reset --keep\" and \"git reset --merge\"?\n> \n> I don't understand what \"git reset --keep\" and \"git reset --merge\" do.\n> I've read the manpage but am still confused.  One of my reasons for\n> suggesting a notation is so that there is a clear mathematical\n> representation of what the commands do.  Once I understand them, I can\n> make an attempt at a notation that can explain them.\n\nWhat I meant here is that above notation wouldn't help explaining the\ndifferences between --hard, --keep and --merge.  Perhaps a table could\nhelp there.\n\nBut IMVHO is more important for documentation to tell *when* one would\nuse one or another, not how they work.\n \n[...]\n>>> [I've included git commands in a not-formal-enough notation at the end\n>>> of this email.]\n>>\n>> NEVERTHELESS some kind of semi-formal notation might be useful.\n> \n> I'm glad you agree.  Do you think my not-formal-enough notation is a\n> good start or do you want to propose another notation to start from?\n\nWell, I am not sure if it is good enough idea to waste time on it...\nHmmm... maybe revctrl.org guys would be interested?  Just a thought.\n\n>>> 3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\n>>> their own command names\n>>>\n>>> This is my biggest and most important suggestion.\n>>>\n>>> \"checkout -- foo.txt\" copies foo.txt from NEXT to WTREE. Similarly,\n>>> \"reset -- foo.txt\" will copy foo.txt from HEAD to NEXT.\n>>\n>>  \"checkout HEAD -- foo.txt\" copies foo.txt from HEAD to NEXT and WTREE\n>>\n>>  \"checkout HEAD^ -- foo.txt\" copies foo.txt from HEAD^ to NEXT and WTREE\n>>  \"reset HEAD^ -- foo.txt\" copies foo.txt from HEAD^ to NEXT\n>>\n>>> These are operations to designate/undesignate files in the next commit\n>>> and should be grouped with others like them: \"add\", \"rm\" and \"mv\". (In\n>>> fact, the man page for \"reset -- <file>\" even says that it is the\n>>> opposite of \"add\"!)\n[...]\n\n>>> For the other, my best suggestion is \"head-to-next\", but I'm sure\n>>> someone can do better.\n>>\n>> I'd rather remember that \"git checkout\" is about checking out\n>> something to a working area.\n> \n> Now that I've separated these two usages of \"checkout\" in my brain,\n> \"git checkout <branch>\" is all about changing to a different branch.\n> That files in the working tree change is just incidental to moving to\n> the new branch.\n> \n> The manpage paragraph for \"git checkout -- <file>\" has in bold that\n> this usage \"does not switch branches\".  So, for me, it's a completely\n> different usage and should be a different command.\n\nFor me it is about \"checking out\" two different entities: a branch\n(or related case of non-branch ref, e.g. \"git checkout v1.7.3\", or\n\"git checkout HEAD~2\"), or a pathspec (file or directory).  Checking\nout branch means making it current branch, checking out file means\nmaking this version of a file current.\n \n> I wish I had a reasonable name to suggest for the new command.\n\nGood name is a required prerequisite here, unfortunately...\n\n[cut]\n\n>>> \"commit --amend\"\n>>>    HEAD = new(HEAD^ + (NEXT-HEAD^))\n>>>    NEXT = HEAD\n>>\n>>  HEAD^ + (NEXT-HEAD^) == NEXT\n>>\n>> \"git commit --amend\" works correctly even if HEAD is a merge commit!\n> \n> Another good issue.  A formal notation will need to specify how to\n> deal with cases of a commit with more than one predecessor.\n\nPerhaps, in extension notation proposed for describing what \"git commit\"\ndoes perhaps\n\n   commit^@ = HEAD^@\n\nor just\n\n   commit = copy(HEAD^{commit})\n   commit^{tree} = :0:\n \nNote however that \"git commit\" has more modes.  Not including exotic\nones there is \"git commit -a\", \"git commit [--only] <file>\", and\nrarely used \"git commit --include <file>\".\n\n>>> \"checkout FOO\" (prequires WTREE==NEXT==HEAD)\n>>\n>> No such requirement.  It's all about which files differ between HEAD\n>> and FOO.  If you start working on some file, and decide that you\n>> should have made the change on different branch, \"git checkout FOO\"\n>> allow to move to FOO branch... assuming that changed file has the same\n>> contents in HEAD and in FOO.\n> \n> Okay.  I will have to think about how a formal notation can denote that...\n\nI think that table with HEAD version, worktree version, switched to branch\nversion, and result for plain checkout, -f/--force and -m/--merge would\nbe a better solution than formal notation.\n\n>>>    WTREE = FOO\n>>>    NEXT = FOO\n>>>    HEAD ::= FOO // changes the alias of HEAD to refer to FOO\n>>\n>> And this is supposed to be easier to understand?\n> \n> \"checkout\" is a very simple command to describe in English, so the\n> mathematical description will be more convoluted.  I don't (yet)\n> understand some of the variants of \"git reset\" even though they are\n> written in English.  I'm hoping a formal notation will make them\n> easier to understand.\n\nHmmm...\n \n>>> \"stash save\"\n>>>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)\n>>>    NEXT = HEAD\n>>>    WTREE = HEAD\n>>>    push(STASH)\n>>> \"stash pop\"\n>>>    STASH = pop()\n>>>    WTREE = HEAD + (STASH-STASH^^)\n>>>    NEXT = HEAD + (STASH^-STASH^^)\n>>\n>> ???\n> \n> \"stash save\" makes two new consecutive commits: one equal to NEXT and\n> another equal to WTREE.\n\nNo, \"stash save\" doesn't make two _consecutive_ commits.  It makes\na commit which has state of worktree as one parent, and state of index\nas other parent (i.e. a merge commit).\n\n> (This is \"STASH\" above, with my unoptimizations.)\n> I don't know where the SHA of the final commit gets \n> stored, so I just created push() and pop() commands.\n\nIt is stored in 'refs/stash' and its reflog.\n \n> Rereading the man page, the commit containing WTREE has two parents.\n> This notation doesn't have a way to denote that.\n\nRight.\n \n-- \nJakub Narebski\nPoland\n"},{"id":"169325","messageId":"BANLkTik+xhd5QQ09QiPSH1bFAndzipKtrw@mail.gmail.com","threadId":"27548","inReplyTo":"201106051311.00951.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Scott Chacon","fromEmail":"schacon@gmail.com","sentAt":"2011-06-05T18:39:00Z","receivedAt":"2011-06-05T18:39:00Z","isPatch":false,"sender":{"key":"schacon@gmail.com","avatar":"https://gravatar.com/avatar/9b13a8a078e1dcf8588c4eea9554445d51ebed6c41b51f56f4d96738130b05c6?d=mp&s=160"},"body":"Hey,\n\nOn Sun, Jun 5, 2011 at 4:10 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n> On Sun, 5 Jun 2011, Michael Nahas wrote:\n>> On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:\n>>> Michael Nahas <mike.nahas@gmail.com> writes:\n>>>\n>>>> Quick list of recommendations:\n>>>>\n>>>> 1. Pick aliases for the next commit and the working tree that act like\n>>>>    commits on the command-line.\n>>>\n>>> No go.  This was asked for many times, and each time shot down.\n>>> Those \"aliases\" / pseudo-refs looks like commits but do not behave\n>>> exactly like commits.  This would increase connfusion.\n>>\n>> I'm glad it was discussed.  I think users would know that those\n>> commits were special (they are writeable after all), but I'm sure more\n>> informed people than I made the same arguments.\n>\n> Perhaps we should add conclusion / summary of this discussion either\n> somewhere on git wiki (http://git.wiki.kernel.org), or e.g. on gitcli(7)\n> manpage, so that it won't get reiterated again and again.  It is sort\n> of frequently asked question^W request.\n\nCan you cite any of these threads please?  I also thought this was a\nreasonable suggestion and don't remember these previous discussions.\nAlso, to be fair, I've been pretty active in this community for a long\ntime now and I honestly don't ever remember seeing the 'gitcli'\nmanpage, so don't feel too bad Michael.\n\n>\n>>>> 2. Adopt a (semi-)formal notation for describing what commands do.\n>>>\n>>> Whom it would help?  Not an ordinary user.\n>>\n>> I think it would help experts in discussing exactly what happens.  For\n>> ordinary users that are hitting an intricate case (or don't know\n>> English very well), it would be good if there was something that would\n>> tell them mathematically what occurs.\n>\n> Well, semi-formal notation could help, but I am not sure if it would\n> really be easier to understand than textual description.\n\nI think some notational format like this would be way, way easier to\nunderstand than, for instance, the current git-reset page, which is\nalmost impossible to follow.\n\n> What about (well, more rarely used) \"git reset <commit> -- <path>\"?\n> But I quite like \"git unadd\" alias, even if \"git unadd <commit> <path>\"\n> looks strange; we have precedent in the form of \"git stage\" command\n> (alias).\n>\n\nI actually sort of dislike the idea of an alias, even though I'm\nprobably mostly to blame for the introduction of the 'git stage' alias\nin the first place.  I do feel, however, that 'reset' and 'checkout'\nare horribly and confusingly overloaded and introducing a couple of\nnew porcelain commands to do a subset of their functionality in a\nsafer and more friendly manner would be hugely helpful.  I would\nactually like to start treating 'reset' as more of a plumbing command,\nsince it is so incredibly confusing and does so many different things.\n I think it would be better to introduce things like 'unadd' or\n'unstage', 'revert-file' to revert file contents in the work tree,\n'uncommit' to do 'reset HEAD~', 'unmerge' to do a 'reset --hard' but\ncheck that we are in a conflicted merge state, etc.\n\nNot just aliases, but commands that run 'reset' or 'checkout' in the\nbackground but have command specific options and help pages.  Knowing\nthat 'reset' is how you do all of these things is not intuitive.\nKnowing that some options to 'reset' and 'checkout' are work tree\nunsafe and others are safe is not intuitive in addition to scaring\npeople into not using or figuring out the other options because\nthey're scared of the unsafe invocations.\n\n>> (And renaming \"git checkout -- <path>\" to some\n>> yet-to-be-named other command.)\n>\n> I think this one could be left as is, at least until a really good name\n> for said replacement appears (\"git revert\" means something else, and\n> \"git revert-file\" is a bit long, and can be confused with currently\n> not existing but proposed and discussed \"git revert <revision> <pathspec>\".)\n\nI would really like to not introduce more ways of making one command\ndo totally different things depending on if it gets a file path\nlimiter or not.\n\n\n>>>> My recommendations are:\n>>>>\n>>>> 1. Pick aliases for the next commit and the working tree that act like\n>>>> commits on the command-line.\n> [...]\n>>>> For the alias for the next commit and working tree, I suggest \"NEXT\"\n>>>> and \"WTREE\".  Creating these aliases will make the interface more\n>>>> regular. It will remove oddities like \"diff --cached FOO\" and replace\n>>>> them with \"diff NEXT FOO\" and mean that \"diff\" and \"diff FOO\" can be\n>>>> explained as \"diff WTREE NEXT\" and \"diff WTREE FOO\".\n>>>\n>>> This idea ws proposed multiple time on git mailing list, and every\n>>> time it was rejected.\n> [...]\n>> That this idea has been brought up multiple times says that it does\n>> have some merit.  But apparently not enough merit.\n>\n> No, this only means that people *think* it has merit.  And perhaps\n> that they are poisoned by Subversion's pseudo-refs ;-P\n\nJust for the record, I've never used Subversion, have a pretty solid\nunderstanding of Git internals and I thought this was a good idea.\nFor example, implementation details aside, I think having something\nlike WTREE and NEXT available would help users understand that there\nare these 3 trees that are important and useful in Git and re-inforce\na very non-SVN style workflow in that manner.\n\nHaving people learn '--cached', which just makes no sense in most\ncontexts, is confusing.  It's great that it's there, but it's not\nnecessary to know the difference to use git in almost any\ncircumstances.  I never remember what the difference is, but I rarely,\nif ever, run into a case where I need to use one where I haven't just\nmemorized the invocation I need. For example, 'rm --cached', and 'diff\n--cached' are just commands I use because I know what they do, not\nbecause I remember the semantics of --cached over --index (if --index\neven is applicable in these cases, which I don't think it is).\n\n>\n>>> BTW. both index and worktree have their own \"aliases\", namely ':0:'\n>>> for index (stage 0), and ':' or ':/' for top tree.\n>>\n>> Really?  Where can these aliases be used?\n>\n> Well, actually they _currently_ cannot be used in many places.\n>\n> You can view version of file as it is in the index with\n>\n>  $ git show :0:path/to/file\n>\n> You can add file from a top of project directory (given new enough git;\n> I think it isn't in any released git version yet) with\n>\n>  $ git add :/path/to/file\n>\n> independently on subdirectory you are in (i.e. --full-tree).\n>\n>\n> But the main point was meant to be that even if there was some merit\n> to the pseudo-tree-ish aliases, ':0:' or '::' or ':0' would be better\n> that NEXT / STAGE / INDEX that looks like symbolic refs and therefore\n> commits but ain't, and ':/' would be better that WORK / WTREE.\n\nPlease be kidding.\n\nI just don't understand how you can honestly suggest to someone that\n\"git show :0:/path/to/file.txt\" makes more sense to anyone then \"git\nshow NEXT:/path/to/file.txt\" would.  I have no idea if ':0:' or '::'\nwork anywhere, but if they ever do, I guarantee they will be used by\npractically nobody.\n\n>>> Second, it doesn't solve issue of needing --cached and/or --index\n>>> swiches completely.  Those pseudo-almost-refs hide them for \"git diff\",\n>>> \"git grep\", \"git ls-files\", perhaps \"git submodule\" where we *read*\n>>> from index, but not for \"git apply\", \"git rm\" or \"git stash\" where\n>>> those swicthes affect *writing*.\n>>\n>> I agree with you that it would not get rid of all switches.  I never\n>> expected it to.  My major aim was to simplify things like the \"diff\"\n>> command, which I have trouble remembering the different variations of.\n\nNearly everybody does, which is why I also believe his argument has merit.\n\n> You miss the point of this.  The issue is that you have to learn about\n> '--cached' and '--index' *anyway* (because pseudo-almost-refs do not\n> solve everything), and for consistency and backward compatibility we\n> need to support '--cached' for \"git diff\" etc., so you proposal brings\n> nothing but new thing to learn (and not only syntax, but quirks as well).\n>\n> So you only add to required knowledgebase, not reduce it.\n\nThough I already argued against this, I would reiterate it.  You do\nnot have to learn about those switches to use Git.  You don't have to\nbe able to do everything in Git before you can do anything.  I do not\nknow of a single command I've ever used where I needed to know the\ndifference - it almost never comes up in daily use for nearly all Git\nusers.  Can you come up with an example other than 'apply' that takes\nboth options?  If a user doesn't use 'apply' (and I think the vast\nmajority doesn't), then a simpler alternative that is more universally\napplicable would reduce the required knowledgebase for almost all Git\nusers.\n\n\n>>> Hrmmm... how this notation would explain differences between\n>>> \"git reset --hard\", \"git reset --keep\" and \"git reset --merge\"?\n>>\n>> I don't understand what \"git reset --keep\" and \"git reset --merge\" do.\n>> I've read the manpage but am still confused.  One of my reasons for\n>> suggesting a notation is so that there is a clear mathematical\n>> representation of what the commands do.  Once I understand them, I can\n>> make an attempt at a notation that can explain them.\n>\n> What I meant here is that above notation wouldn't help explaining the\n> differences between --hard, --keep and --merge.  Perhaps a table could\n> help there.\n>\n> But IMVHO is more important for documentation to tell *when* one would\n> use one or another, not how they work.\n\nJust to I also have no idea how to use --keep and --merge. I think it\nwould be useful to have both - I've read the one example of how to use\n--keep, but I've never used it and if I ran into that specific\nuse-case, I'm sure I wouldn't even remember that something was there\nto help.\n\n>>>> 3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\n>>>> their own command names\n>>>>\n>>>> This is my biggest and most important suggestion.\n>>>>\n>>>> \"checkout -- foo.txt\" copies foo.txt from NEXT to WTREE. Similarly,\n>>>> \"reset -- foo.txt\" will copy foo.txt from HEAD to NEXT.\n>>>\n>>>  \"checkout HEAD -- foo.txt\" copies foo.txt from HEAD to NEXT and WTREE\n>>>\n>>>  \"checkout HEAD^ -- foo.txt\" copies foo.txt from HEAD^ to NEXT and WTREE\n>>>  \"reset HEAD^ -- foo.txt\" copies foo.txt from HEAD^ to NEXT\n>>>\n>>>> These are operations to designate/undesignate files in the next commit\n>>>> and should be grouped with others like them: \"add\", \"rm\" and \"mv\". (In\n>>>> fact, the man page for \"reset -- <file>\" even says that it is the\n>>>> opposite of \"add\"!)\n> [...]\n>\n>>>> For the other, my best suggestion is \"head-to-next\", but I'm sure\n>>>> someone can do better.\n>>>\n>>> I'd rather remember that \"git checkout\" is about checking out\n>>> something to a working area.\n>>\n>> Now that I've separated these two usages of \"checkout\" in my brain,\n>> \"git checkout <branch>\" is all about changing to a different branch.\n>> That files in the working tree change is just incidental to moving to\n>> the new branch.\n>>\n>> The manpage paragraph for \"git checkout -- <file>\" has in bold that\n>> this usage \"does not switch branches\".  So, for me, it's a completely\n>> different usage and should be a different command.\n>\n> For me it is about \"checking out\" two different entities: a branch\n> (or related case of non-branch ref, e.g. \"git checkout v1.7.3\", or\n> \"git checkout HEAD~2\"), or a pathspec (file or directory).  Checking\n> out branch means making it current branch, checking out file means\n> making this version of a file current.\n>\n>> I wish I had a reasonable name to suggest for the new command.\n>\n> Good name is a required prerequisite here, unfortunately...\n\nActually, I'm pretty sure even an amazing name wouldn't help here.\nI'm a bit surprised that you would reference the previous WTREE/NEXT\ndiscussions, but not the discussions we've had on this topic:\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/121206/focus=121317\n\nI've brought up splitting checkout and simplifying some commands the\nway EasyGit has done and none other than Linus himself shot it down\nand that was nearly 2 years ago.  Sadly, the chances of getting any UI\nimprovements of this nature in seem quite remote, and have been for\nsome time.\n\nI would like to thank Michael for taking so much time to propose a\nthoughtful response to the UI issues that so many people struggle with\ninstead of just complaining, as most do.\n\nI would love if we could compile suggestions like these and shoot for\na Git 2.0 with a much nicer UI and help system.  However, it seems\nunlikely that Junio would go for this.  It seems somewhat more likely\nthat what would happen is that a simpler, cleaner libgit2 based cli\nwould emerge at some point with an 80% most-used functionality and\nsuper nice UI mentality, but that wouldn't be for some time.\n\nScott\n"},{"id":"169326","messageId":"4DEBF3A7.9090705@gmx.de","threadId":"27548","inReplyTo":"201106051311.00951.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Paul Ebermann","fromEmail":"paul-ebermann@gmx.de","sentAt":"2011-06-05T21:22:47Z","receivedAt":"2011-06-05T21:22:47Z","isPatch":false,"sender":{"key":"paul-ebermann@gmx.de","avatar":"https://gravatar.com/avatar/cc7e51a73ad3f42554d77240dde18357dc826227b021826a604ed4150e43c6f9?d=mp&s=160"},"body":"Jakub Narebski skribis:\n> On Sun, 5 Jun 2011, Michael Nahas wrote:\n>> On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:\n>>> Michael Nahas <mike.nahas@gmail.com> writes:\n[...]\n>>>> \"stash save\"\n>>>>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)\n>>>>    NEXT = HEAD\n>>>>    WTREE = HEAD\n>>>>    push(STASH)\n>>>> \"stash pop\"\n>>>>    STASH = pop()\n>>>>    WTREE = HEAD + (STASH-STASH^^)\n>>>>    NEXT = HEAD + (STASH^-STASH^^)\n>>>\n>>> ???\n>>\n>> \"stash save\" makes two new consecutive commits: one equal to NEXT and\n>> another equal to WTREE.\n> \n> No, \"stash save\" doesn't make two _consecutive_ commits.  It makes\n> a commit which has state of worktree as one parent, and state of index\n> as other parent (i.e. a merge commit).\n\nHmm, for me it always looked like one commit with the index state as\ncontent and HEAD as parent, and second one with the Worktree as content,\nand both HEAD and the mentioned index commit as parent.\n\nThis is technically a merge commit (as it has two parents), but not\nreally done as a merge.\n\n\nPaul\n"},{"id":"169327","messageId":"4DEBF676.5020608@gmx.de","threadId":"27548","inReplyTo":"BANLkTinTWG7YXGKZzmH0rqtt+Ob7X+2yMQ@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Paul Ebermann","fromEmail":"paul-ebermann@gmx.de","sentAt":"2011-06-05T21:34:46Z","receivedAt":"2011-06-05T21:34:46Z","isPatch":false,"sender":{"key":"paul-ebermann@gmx.de","avatar":"https://gravatar.com/avatar/cc7e51a73ad3f42554d77240dde18357dc826227b021826a604ed4150e43c6f9?d=mp&s=160"},"body":"Michael Nahas skribis:\n\n> \"commit\"\n>    HEAD = new(HEAD + (NEXT-HEAD))\n>    NEXT = HEAD\n> \"commit --amend\"\n>    HEAD = new(HEAD^ + (NEXT-HEAD^))\n>    NEXT = HEAD\n\nA better notation for creating a new commit would be something that\ntakes both the contents and the parents as arguments.\n\n\"commit:\"\n  HEAD = new(NEXT, HEAD)\n  NEXT = HEAD\n\"commit --amend\"\n  HEAD = new(NEXT, all-parents-of(HEAD))\n  NEXT = HEAD\n\n> \"stash save\"\n>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)\n>    NEXT = HEAD\n>    WTREE = HEAD\n>    push(STASH)\n\n\"stash save\"\n  STASH = new(WTREE, HEAD, new(NEXT, HEAD))\n  NEXT = HEAD\n  WTREE = HEAD\n  push(STASH)\n\nAnd similar.\n\n\nPaul\n"},{"id":"169329","messageId":"201106060137.32174.jnareb@gmail.com","threadId":"27548","inReplyTo":"BANLkTik+xhd5QQ09QiPSH1bFAndzipKtrw@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-05T23:37:28Z","receivedAt":"2011-06-05T23:37:28Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Hey,\n\nOn Sun, 5 Jun 2011, Scott Chacon wrote:\n> On Sun, Jun 5, 2011 at 4:10 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n>> On Sun, 5 Jun 2011, Michael Nahas wrote:\n>>> On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:\n>>>> Michael Nahas <mike.nahas@gmail.com> writes:\n>>>>\n>>>>> Quick list of recommendations:\n>>>>>\n>>>>> 1. Pick aliases for the next commit and the working tree that act like\n>>>>>    commits on the command-line.\n>>>>\n>>>> No go.  This was asked for many times, and each time shot down.\n>>>> Those \"aliases\" / pseudo-refs looks like commits but do not behave\n>>>> exactly like commits.  This would increase connfusion.\n>>>\n>>> I'm glad it was discussed.  I think users would know that those\n>>> commits were special (they are writeable after all), but I'm sure more\n>>> informed people than I made the same arguments.\n>>\n>> Perhaps we should add conclusion / summary of this discussion either\n>> somewhere on git wiki (http://git.wiki.kernel.org), or e.g. on gitcli(7)\n>> manpage, so that it won't get reiterated again and again.  It is sort\n>> of frequently asked question^W request.\n> \n> Can you cite any of these threads please?  I also thought this was a\n> reasonable suggestion and don't remember these previous discussions.\n\nSomewhere in this thread:\n\n  \"[RFC/PATCH 0/2] New 'stage' command\"\n  http://thread.gmane.org/gmane.comp.version-control.git/115666/focus=115880\n  (STAGE and WORKTREE pseudo-ref aliases)\n\nAnd I think it was not the only one, but is the only one I have saved\n(bookmarked).  Unfortunately searching for such thread needs case sensitive\nsearch, and most searches ain't.\n\n> Also, to be fair, I've been pretty active in this community for a long\n> time now and I honestly don't ever remember seeing the 'gitcli'\n> manpage, so don't feel too bad Michael.\n\nWell, gitcli(7) is referenced only from git(1) and from git-rev-parse(1)\nmanpages, and was added in 2f7ee08 (parse-options: Add a gitcli(5) man\npage., 2007-12-13) [v1.5.4-rc2~14], as I wrote.\n\nIt should really be referenced in git tutorials and in user's manual.\n\n>>\n>>>>> 2. Adopt a (semi-)formal notation for describing what commands do.\n>>>>\n>>>> Whom it would help?  Not an ordinary user.\n>>>\n>>> I think it would help experts in discussing exactly what happens.  For\n>>> ordinary users that are hitting an intricate case (or don't know\n>>> English very well), it would be good if there was something that would\n>>> tell them mathematically what occurs.\n>>\n>> Well, semi-formal notation could help, but I am not sure if it would\n>> really be easier to understand than textual description.\n> \n> I think some notational format like this would be way, way easier to\n> understand than, for instance, the current git-reset page, which is\n> almost impossible to follow.\n\nNot all can be solved by semi-formal, semi-mathematical notation, but it,\ntogether with tables (a problem for manpages, though), and ABNF for \ntechnical documentation would help, sure.\n\nIt is unfortunate that to know what to write in manpage you need to be\na bit of expert, and when you are expert you usually loose sight on how\nto write manpage readable for new / non-expert user ;-)  Maybe it would\nbe a good task for Google Code-In?\n\n>> What about (well, more rarely used) \"git reset <commit> -- <path>\"?\n>> But I quite like \"git unadd\" alias, even if \"git unadd <commit> <path>\"\n>> looks strange; we have precedent in the form of \"git stage\" command\n>> (alias).\n> \n> I actually sort of dislike the idea of an alias, even though I'm\n> probably mostly to blame for the introduction of the 'git stage' alias\n> in the first place.\n\nWell, because of backward compatibility we would need to keep supporting\n\"git checkout -- <path>\", \"git checkout <commit> -- <path>\", and\n\"git reset -- <path>\".  That's why I used 'alias' name.\n\n> I do feel, however, that 'reset' and 'checkout' \n> are horribly and confusingly overloaded and introducing a couple of\n> new porcelain commands to do a subset of their functionality in a\n> safer and more friendly manner would be hugely helpful.\n\nWell, AFAIK responsible for some of this overloading was \"git is difficult\nbecause it has too many commands\" mantra... though I am not sure if putting\noverloading commands really helps.\n\nBut the notion of checking out file, or reseting file is quite natural...\nat least for native English speaker.  I think in most natural languages\nthere are words that have more than one meaning.\n\n\nNOTE that information in \"git status\" output, and in template for commit\nmessage is *extremely* helpful because it explains in exact detail what\nyou can do!\n\n> I would \n> actually like to start treating 'reset' as more of a plumbing command,\n> since it is so incredibly confusing and does so many different things.\n>  I think it would be better to introduce things like 'unadd' or\n> 'unstage', \n\nWould need both, most probably.  I don't know how widespread is using of\n\"stage\" command, but I think old timers are used to \"git add\".\n\n> 'revert-file' to revert file contents in the work tree, \n\nBit longish, but quite all right.\n\n> 'uncommit' to do 'reset HEAD~',\n\nNot \"git reset --soft HEAD\"?\n\n> 'unmerge' to do a 'reset --hard' but \n> check that we are in a conflicted merge state, etc.\n\nI think you meant \"git reset --merge\" here.  Nevertheless it might be\na good addition because of safety check.  Like \"git mv\" which is wrapper\naround \"git rm\" and \"mv\"/\"cp\" and \"git add\", but with safety check.\n\n> Not just aliases, but commands that run 'reset' or 'checkout' in the\n> background but have command specific options and help pages.\n\nIf proliferation of command is problem, it might be \"git add --undo\"\ninstead of \"git unadd\"... but then there is problem with \n\"git unadd <commit> <file>\".\n\n> Knowing that 'reset' is how you do all of these things is not intuitive.\n\nThanks to \"git status\" output knowledge is not really necessary.  It is\nwritten there in detail.\n\nBut it is true that guessing by ones own that forms of git-checkout and\ngit-reset is how you do it require good knowledge of \"git model\".\n\n> Knowing that some options to 'reset' and 'checkout' are work tree\n> unsafe and others are safe is not intuitive in addition to scaring\n> people into not using or figuring out the other options because\n> they're scared of the unsafe invocations.\n\nErrr... \"git checkout\" in its branch switching version is always safe,\nunless you use \"--force\".  The forms of \"checkout\" and \"reset\" that\nare about checking out and reseting file are of course this file unsafe.\nDuh.  Well, \"git reset --hard\" could get \"--force\" safety check... but\nthen it would be quite annoying and harder to use.\n\n>>> (And renaming \"git checkout -- <path>\" to some\n>>> yet-to-be-named other command.)\n>>\n>> I think this one could be left as is, at least until a really good name\n>> for said replacement appears (\"git revert\" means something else, and\n>> \"git revert-file\" is a bit long, and can be confused with currently\n>> not existing but proposed and discussed \"git revert <revision> <pathspec>\".)\n> \n> I would really like to not introduce more ways of making one command\n> do totally different things depending on if it gets a file path\n> limiter or not.\n\nYou probably don't like Perl with its context-dependency and TIMTOWTDI\n(\"there is more than one way to do it\")... ;-P\n\n>>>>> My recommendations are:\n>>>>>\n>>>>> 1. Pick aliases for the next commit and the working tree that act like\n>>>>> commits on the command-line.\n>> [...]\n>>>>> For the alias for the next commit and working tree, I suggest \"NEXT\"\n>>>>> and \"WTREE\".  Creating these aliases will make the interface more\n>>>>> regular. It will remove oddities like \"diff --cached FOO\" and replace\n>>>>> them with \"diff NEXT FOO\" and mean that \"diff\" and \"diff FOO\" can be\n>>>>> explained as \"diff WTREE NEXT\" and \"diff WTREE FOO\".\n>>>>\n>>>> This idea ws proposed multiple time on git mailing list, and every\n>>>> time it was rejected.\n>> [...]\n>>> That this idea has been brought up multiple times says that it does\n>>> have some merit.  But apparently not enough merit.\n>>\n>> No, this only means that people *think* it has merit.  And perhaps\n>> that they are poisoned by Subversion's pseudo-refs ;-P\n> \n> Just for the record, I've never used Subversion, have a pretty solid\n> understanding of Git internals and I thought this was a good idea.\n> For example, implementation details aside, I think having something\n> like WTREE and NEXT available would help users understand that there\n> are these 3 trees that are important and useful in Git and re-inforce\n> a very non-SVN style workflow in that manner.\n\nThese are not quite tree-ish, because of index stages, and of ignored\nand other (untracked not ignored) files in worktree.  And they are\nnot at all commit-ish/revision or symrefs, like name hints.\n \n> Having people learn '--cached', which just makes no sense in most\n> contexts, is confusing.  It's great that it's there, but it's not\n> necessary to know the difference to use git in almost any\n> circumstances.  I never remember what the difference is, but I rarely,\n> if ever, run into a case where I need to use one where I haven't just\n> memorized the invocation I need. For example, 'rm --cached', and 'diff\n> --cached' are just commands I use because I know what they do, not\n> because I remember the semantics of --cached over --index (if --index\n> even is applicable in these cases, which I don't think it is).\n\nBecause --index is about affecting _also_ index, i.e. about affecting\nindex and working tree _together_, it is quite rare: only \"git apply\"\nand \"git stash\" use it.\n\nSo --cached means proposed NEXT / STAGE.  It is used by \"diff\", \"grep\",\n\"ls-files\", \"rm\", \"submodule\".  From those only in \"git diff\" there\nmight be trouble remembering, because diff is about 2 endpoints.\n\nBTW. gitcli(7) manpage mentions http://marc.info/?l=git&m=116563135620359\n(talking about --cached vs --index, and why both are necessary) and\nhttp://marc.info/?l=git&m=119150393620273 (differences between --cached\nand index, and about \"git apply\" that has three modes: \"git apply\", \n\"git apply --cached\" and \"git apply --index\").\n \n>>>> BTW. both index and worktree have their own \"aliases\", namely ':0:'\n>>>> for index (stage 0), and ':' or ':/' for top tree.\n>>>\n>>> Really?  Where can these aliases be used?\n>>\n>> Well, actually they _currently_ cannot be used in many places.\n>>\n>> You can view version of file as it is in the index with\n>>\n>>  $ git show :0:path/to/file\n>>\n>> You can add file from a top of project directory (given new enough git;\n>> I think it isn't in any released git version yet) with\n>>\n>>  $ git add :/path/to/file\n>>\n>> independently on subdirectory you are in (i.e. --full-tree).\n>>\n>>\n>> But the main point was meant to be that even if there was some merit\n>> to the pseudo-tree-ish aliases, ':0:' or '::' or ':0' would be better\n>> that NEXT / STAGE / INDEX that looks like symbolic refs and therefore\n>> commits but ain't, and ':/' would be better that WORK / WTREE.\n> \n> Please be kidding.\n> \n> I just don't understand how you can honestly suggest to someone that\n> \"git show :0:/path/to/file.txt\" makes more sense to anyone then \"git\n> show NEXT:/path/to/file.txt\" would.  I have no idea if ':0:' or '::'\n> work anywhere, but if they ever do, I guarantee they will be used by\n> practically nobody.\n\nNote that it is :0:, :1:, :2:, :3:, i.e. you can refer to individual\nstages for unmerged file.  Though perhaps people use --base, --ours,\n--theirs instead... though this is not very widely supported. :0:file\nworks anywhere, because it is revspec.\n\nThe problem wit HEAD-like NEXT / STAGE pseudo-ref is that it looks like\ncommit but does not behave like commit.  Even looking at it as tree-ish\nis [slight] oversimplification.\n \n>>>> Second, it doesn't solve issue of needing --cached and/or --index\n>>>> swiches completely.  Those pseudo-almost-refs hide them for \"git diff\",\n>>>> \"git grep\", \"git ls-files\", perhaps \"git submodule\" where we *read*\n>>>> from index, but not for \"git apply\", \"git rm\" or \"git stash\" where\n>>>> those swicthes affect *writing*.\n>>>\n>>> I agree with you that it would not get rid of all switches.  I never\n>>> expected it to.  My major aim was to simplify things like the \"diff\"\n>>> command, which I have trouble remembering the different variations of.\n> \n> Nearly everybody does, which is why I also believe his argument has merit.\n\nIt's only \"git diff\" that have problems, because of peculiarity of it\nthat it comares 2 things.  What is second one, that can be confusing:\n\"git diff\", \"git diff --cached\", \"git diff HEAD\":\n\n                worktree\n                  |   \\\n                  |    \\  diff\n                  |     v\n       diff HEAD  |     index\n                  |     /\n                  |    /  diff --cached\n                  v   v\n                  HEAD   \n\n\nI don't think anybody has problems understanding and remembering \n\"git grep --cached\" and \"git rm --cached\"... and while you could use\n\"git grep NEXT\", \"git rm NEXT\" doesn't make sense -- \"--cached\" is\ntarget designator, not source designator here.\n \n>> You miss the point of this.  The issue is that you have to learn about\n>> '--cached' and '--index' *anyway* (because pseudo-almost-refs do not\n>> solve everything), and for consistency and backward compatibility we\n>> need to support '--cached' for \"git diff\" etc., so you proposal brings\n>> nothing but new thing to learn (and not only syntax, but quirks as well).\n>>\n>> So you only add to required knowledgebase, not reduce it.\n> \n> Though I already argued against this, I would reiterate it.  You do\n> not have to learn about those switches to use Git.  You don't have to\n> be able to do everything in Git before you can do anything.  I do not\n> know of a single command I've ever used where I needed to know the\n> difference - it almost never comes up in daily use for nearly all Git\n> users.  \n\nIn most cases you use \"--cached\".  Is it that much of a problem to\nremember it (with possible exception of mentioned \"git diff\" complication)\ncompared to WHATEVER (NEXT or STAGE or INDEX)?\n\n> Can you come up with an example other than 'apply' that takes \n> both options?  If a user doesn't use 'apply' (and I think the vast\n> majority doesn't), then a simpler alternative that is more universally\n> applicable would reduce the required knowledgebase for almost all Git\n> users.\n\nBut you would need both of those options for \"git apply\", and pseudo-refs\ndoes not really work here in either case - it is target designator, not\nsource designator. \n \nThere is no other command that takes both, but there is --index for stash:\n\"git stash --index apply\".\n\n>>>> Hrmmm... how this notation would explain differences between\n>>>> \"git reset --hard\", \"git reset --keep\" and \"git reset --merge\"?\n>>>\n>>> I don't understand what \"git reset --keep\" and \"git reset --merge\" do.\n>>> I've read the manpage but am still confused.  One of my reasons for\n>>> suggesting a notation is so that there is a clear mathematical\n>>> representation of what the commands do.  Once I understand them, I can\n>>> make an attempt at a notation that can explain them.\n>>\n>> What I meant here is that above notation wouldn't help explaining the\n>> differences between --hard, --keep and --merge.  Perhaps a table could\n>> help there.\n>>\n>> But IMVHO is more important for documentation to tell *when* one would\n>> use one or another, not how they work.\n> \n> Just to I also have no idea how to use --keep and --merge. I think it\n> would be useful to have both - I've read the one example of how to use\n> --keep, but I've never used it and if I ran into that specific\n> use-case, I'm sure I wouldn't even remember that something was there\n> to help.\n\n\"git reset --merge\", as the name hints, is to be used to 'nuke' botched\nmerge.  \"git reset --keep\" is safe way of rewinding which won't nuke\nyour changes by accident... as far as I understand it.  The documentation\nis suboptimal at best, I certainly agree.\n \n>>>>> 3. Move the operations \"checkout -- <file>\" and \"reset -- <file>\" to\n>>>>> their own command names\n[...]\n>>> The manpage paragraph for \"git checkout -- <file>\" has in bold that\n>>> this usage \"does not switch branches\".  So, for me, it's a completely\n>>> different usage and should be a different command.\n>>\n>> For me it is about \"checking out\" two different entities: a branch\n>> (or related case of non-branch ref, e.g. \"git checkout v1.7.3\", or\n>> \"git checkout HEAD~2\"), or a pathspec (file or directory).  Checking\n>> out branch means making it current branch, checking out file means\n>> making this version of a file current.\n>>\n>>> I wish I had a reasonable name to suggest for the new command.\n>>\n>> Good name is a required prerequisite here, unfortunately...\n> \n> Actually, I'm pretty sure even an amazing name wouldn't help here.\n\n\"Required\" prerequisite does not mean \"sufficient\" prerequisite.\n\n> I'm a bit surprised that you would reference the previous WTREE/NEXT\n> discussions, but not the discussions we've had on this topic:\n> \n> http://thread.gmane.org/gmane.comp.version-control.git/121206/focus=121317\n> \n> I've brought up splitting checkout and simplifying some commands the\n> way EasyGit has done and none other than Linus himself shot it down\n> and that was nearly 2 years ago.  Sadly, the chances of getting any UI\n> improvements of this nature in seem quite remote, and have been for\n> some time.\n\nAs I wrote above (independently), some like context-aware grammar\n(c.f. Perl), some loathe it ;-PPP\n\nBesides, now we have \"git status\" hints...\n \n> I would like to thank Michael for taking so much time to propose a\n> thoughtful response to the UI issues that so many people struggle with\n> instead of just complaining, as most do.\n\nEven if there would be no new commands like \"git unadd\", and there\nwouldn't be NEXT / STAGE / INDEX nor WTREE / WORK / WORKTREE pseudo-symrefs,\nperhaps it would lead to improved documentation; even if not pseudo-formal\nspecification, at least mentioning gitcli(7) in more places.\n \n> I would love if we could compile suggestions like these and shoot for\n> a Git 2.0 with a much nicer UI and help system.  However, it seems\n> unlikely that Junio would go for this.  It seems somewhat more likely\n> that what would happen is that a simpler, cleaner libgit2 based cli\n> would emerge at some point with an 80% most-used functionality and\n> super nice UI mentality, but that wouldn't be for some time.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169334","messageId":"7vwrgza3i2.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"BANLkTik+xhd5QQ09QiPSH1bFAndzipKtrw@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-06T06:16:37Z","receivedAt":"2011-06-06T06:16:37Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Scott Chacon <schacon@gmail.com> writes:\n\n> For example, implementation details aside, I think having something\n> like WTREE and NEXT available would help users understand that there\n> are these 3 trees that are important and useful in Git and re-inforce\n> a very non-SVN style workflow in that manner.\n\nThat's a funny thing to say. Working tree may almost always (to put it\nanother way, \"you could make it to\") act like a tree, but the index does\nnot act like a tree at all in more important situations.\n\nFor example, how would you design the user experience of \"git show NEXT\"?\nTry to write a transcript (i.e. \"The user starts from this state, runs\nthese commands, and then says 'git show NEXT'. The user will see this.\"),\ncovering various corner cases exhaustively, including what would happen\nbefore the first commit, and during a conflicted \"pull\" or \"rebase -i\".\n\nIt's not just the matter of \"internally pretend to run write-tree with\n'not committed yet' as a fake commit log message and show it as if it is\nan existing commit.\n\nI wouldn't demand \"implement 'git show NEXT'\" here, nor \"implement it\nefficiently\" here; just designing the user experience is a good first step\nto realize that the index does not act like a tree, and I do not think you\nshould spread such a misconception to the end users.\n"},{"id":"169341","messageId":"4DEC8322.6040200@drmicha.warpmail.net","threadId":"27548","inReplyTo":"7vwrgza3i2.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-06-06T07:34:58Z","receivedAt":"2011-06-06T07:34:58Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:\n> Scott Chacon <schacon@gmail.com> writes:\n> \n>> For example, implementation details aside, I think having something\n>> like WTREE and NEXT available would help users understand that there\n>> are these 3 trees that are important and useful in Git and re-inforce\n>> a very non-SVN style workflow in that manner.\n> \n> That's a funny thing to say. Working tree may almost always (to put it\n> another way, \"you could make it to\") act like a tree, but the index does\n> not act like a tree at all in more important situations.\n> \n> For example, how would you design the user experience of \"git show NEXT\"?\n> Try to write a transcript (i.e. \"The user starts from this state, runs\n> these commands, and then says 'git show NEXT'. The user will see this.\"),\n> covering various corner cases exhaustively, including what would happen\n> before the first commit, and during a conflicted \"pull\" or \"rebase -i\".\n> \n> It's not just the matter of \"internally pretend to run write-tree with\n> 'not committed yet' as a fake commit log message and show it as if it is\n> an existing commit.\n> \n> I wouldn't demand \"implement 'git show NEXT'\" here, nor \"implement it\n> efficiently\" here; just designing the user experience is a good first step\n> to realize that the index does not act like a tree, and I do not think you\n> should spread such a misconception to the end users.\n\nThat is why the other Michael suggested \"NEXT\" as opposed to \"INDEX\":\nThe index has many aspects, only one of which is \"the contents of the\nnext commit if I would issue 'git commit' right now\". (I would even go\nso far as using \"STAGE\".) Now, it's hard to argue that \"the result of a\ncommit\" is not tree-like, isn't it? And there's no question what \"git\nshow NEXT\" would do. Yes, if you repeat that command, you get a\ndifferent sha1 each time (because of the time field).\n\nI don't think anyone is seriously suggesting to replace the index by a\npseudo commit; but the one aspect which people use most could be well\nrepresented like that, and this might even help emphasizing the\ndifferent aspects of the index. Give the index an identity as an\n\"object\" (no, no new type, not in the object db, but as a ui object),\nnot something mysterious behind the scenes!\n\nAs for WTREE: git diff against work tree does not look at non-tracked\nignored files, so why should WTREE?\n\nFull disclosure: I love the index but hate the way we make it difficult\nto use sometimes, and even have to lookup myself what command and option\nto actually use if all I want to do is diff A against B, or take the\nversion of a file from A and write it to B, when A and B are a commit,\nthe index or the worktree (with a commit being the nonwritable, of course).\n\nI mean, this is really crazy: We have 4 commands (\"add\", \"rm\n[--cached]\", \"checkout [<commit>] --\", \"reset [<commit>] --\") which you\nneed to be aware of if all you want to do is moving file contents\n(content at a path) between a commit, the index and the worktree! And\nthis is actually worse than having 6 for the 6 cases.\n\nMichael\n"},{"id":"169359","messageId":"BANLkTimtkNQcpgDzdJWKtMOdMstTgBF6ow@mail.gmail.com","threadId":"27548","inReplyTo":"4DEC8322.6040200@drmicha.warpmail.net","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-06T11:45:49Z","receivedAt":"2011-06-06T11:45:49Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"Thanks for all the interest!\n\nBefore getting into the contentious topics:\n\nIs there general agreement on my item #4 that \"git branch <name>\"\nshould be replaced by \"git checkout -b <name>\" in the tutorial?\n\nConcerning the semi-formal notation for describing commands, do people\nthing it is useful?  Is this better covered at revctrl.org?\n\n\nOkay, back to NEXT/WTREE:\n\nI think Junio is right: The best way to think about NEXT and WTREE are\n_not_ as commits.  They are \"snapshots of the project\".  A commit\nobject is a snaphot + parent commit SHAs + author + message + other\nthings.  Think of NEXT and WTREE as equivalent to the tree object\npointed to by a commit object.\n\n[Perhaps \"next commit\" is a bad name for a snapshot]\n\nThese concepts of NEXT and WTREE are use by visual tools.  My favorite\nGit documentation, Visual Git Reference, uses them.  Even \"git stash\nsave\" stores the \"state of the index\" and \"state of the working tree\"\nin two commits.\n\nMy initial desire for NEXT/WTREE was to make \"git diff\" usage easier\nfor me to remember.  It ends up that this is _exactly_ the same usage\nthat inspired the previous emails that Jakub referenced.  I understand\nthat NEXT and WTREE may not have as many uses elsewhere, but I think\nthey have a lot of value for \"git diff\".\n\nI don't think users will have trouble realizing that NEXT and WTREE\nare _not_ commits.  They're writable.  Commits are not.  I do think\nthat NEXT has some value that users will realize that \"git add\nfoo.txt\" adds a particular version of foo.txt to the index and that\nfurther edits to foo.txt will not make it into the next commit, unless\n\"git add foo.txt\" is run again.\n\nIn reference as to how to report \"git show NEXT\", I would suggest that\nthe usual case would be to treat NEXT like a tree object.  I'm new to\nGit and I know enough to know that I don't know all the states of the\nindex nor even all the commands that use it.  I will read up on the\nformat of the index and try to come up with some answers for the more\ncomplex situations, but I'm also okay with saying the alias NEXT\ndoesn't work while in a merge conflict (where \"git write-tree\" would\nreturn an error.)  Perhaps other alias do work then?\nMERGE_HEAD/FETCH_HEAD come and go, right?\n\nMike\n\n\nOn Mon, Jun 6, 2011 at 3:34 AM, Michael J Gruber\n<git@drmicha.warpmail.net> wrote:\n> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:\n>> Scott Chacon <schacon@gmail.com> writes:\n>>\n>>> For example, implementation details aside, I think having something\n>>> like WTREE and NEXT available would help users understand that there\n>>> are these 3 trees that are important and useful in Git and re-inforce\n>>> a very non-SVN style workflow in that manner.\n>>\n>> That's a funny thing to say. Working tree may almost always (to put it\n>> another way, \"you could make it to\") act like a tree, but the index does\n>> not act like a tree at all in more important situations.\n>>\n>> For example, how would you design the user experience of \"git show NEXT\"?\n>> Try to write a transcript (i.e. \"The user starts from this state, runs\n>> these commands, and then says 'git show NEXT'. The user will see this.\"),\n>> covering various corner cases exhaustively, including what would happen\n>> before the first commit, and during a conflicted \"pull\" or \"rebase -i\".\n>>\n>> It's not just the matter of \"internally pretend to run write-tree with\n>> 'not committed yet' as a fake commit log message and show it as if it is\n>> an existing commit.\n>>\n>> I wouldn't demand \"implement 'git show NEXT'\" here, nor \"implement it\n>> efficiently\" here; just designing the user experience is a good first step\n>> to realize that the index does not act like a tree, and I do not think you\n>> should spread such a misconception to the end users.\n>\n> That is why the other Michael suggested \"NEXT\" as opposed to \"INDEX\":\n> The index has many aspects, only one of which is \"the contents of the\n> next commit if I would issue 'git commit' right now\". (I would even go\n> so far as using \"STAGE\".) Now, it's hard to argue that \"the result of a\n> commit\" is not tree-like, isn't it? And there's no question what \"git\n> show NEXT\" would do. Yes, if you repeat that command, you get a\n> different sha1 each time (because of the time field).\n>\n> I don't think anyone is seriously suggesting to replace the index by a\n> pseudo commit; but the one aspect which people use most could be well\n> represented like that, and this might even help emphasizing the\n> different aspects of the index. Give the index an identity as an\n> \"object\" (no, no new type, not in the object db, but as a ui object),\n> not something mysterious behind the scenes!\n>\n> As for WTREE: git diff against work tree does not look at non-tracked\n> ignored files, so why should WTREE?\n>\n> Full disclosure: I love the index but hate the way we make it difficult\n> to use sometimes, and even have to lookup myself what command and option\n> to actually use if all I want to do is diff A against B, or take the\n> version of a file from A and write it to B, when A and B are a commit,\n> the index or the worktree (with a commit being the nonwritable, of course).\n>\n> I mean, this is really crazy: We have 4 commands (\"add\", \"rm\n> [--cached]\", \"checkout [<commit>] --\", \"reset [<commit>] --\") which you\n> need to be aware of if all you want to do is moving file contents\n> (content at a path) between a commit, the index and the worktree! And\n> this is actually worse than having 6 for the 6 cases.\n>\n> Michael\n>\n"},{"id":"169360","messageId":"201106061419.34599.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DEC8322.6040200@drmicha.warpmail.net","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-06T12:19:32Z","receivedAt":"2011-06-06T12:19:32Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Mon, 6 June 2011, Michael J Gruber wrote:\n> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:\n>> Scott Chacon <schacon@gmail.com> writes:\n>> \n>>> For example, implementation details aside, I think having something\n>>> like WTREE and NEXT available would help users understand that there\n>>> are these 3 trees that are important and useful in Git and re-inforce\n>>> a very non-SVN style workflow in that manner.\n>> \n>> That's a funny thing to say. Working tree may almost always (to put it\n>> another way, \"you could make it to\") act like a tree, but the index does\n>> not act like a tree at all in more important situations.\n>> \n>> For example, how would you design the user experience of \"git show NEXT\"?\n>> Try to write a transcript (i.e. \"The user starts from this state, runs\n>> these commands, and then says 'git show NEXT'. The user will see this.\"),\n>> covering various corner cases exhaustively, including what would happen\n>> before the first commit, and during a conflicted \"pull\" or \"rebase -i\".\n>> \n>> It's not just the matter of \"internally pretend to run write-tree with\n>> 'not committed yet' as a fake commit log message and show it as if it is\n>> an existing commit.\n>> \n>> I wouldn't demand \"implement 'git show NEXT'\" here, nor \"implement it\n>> efficiently\" here; just designing the user experience is a good first step\n>> to realize that the index does not act like a tree, and I do not think you\n>> should spread such a misconception to the end users.\n> \n> That is why the other Michael suggested \"NEXT\" as opposed to \"INDEX\":\n> The index has many aspects, only one of which is \"the contents of the\n> next commit if I would issue 'git commit' right now\". (I would even go\n> so far as using \"STAGE\".) Now, it's hard to argue that \"the result of a\n> commit\" is not tree-like, isn't it? And there's no question what \"git\n> show NEXT\" would do. Yes, if you repeat that command, you get a\n> different sha1 each time (because of the time field).\n> \n> I don't think anyone is seriously suggesting to replace the index by a\n> pseudo commit; but the one aspect which people use most could be well\n> represented like that, and this might even help emphasizing the\n> different aspects of the index. Give the index an identity as an\n> \"object\" (no, no new type, not in the object db, but as a ui object),\n> not something mysterious behind the scenes!\n\nSo what you suggest would make\n\n  $ git diff NEXT WTREE\n\nbehave differently from\n\n  $ git diff\n\nand\n\n  $ git diff HEAD NEXT\n\nbehave differently from\n\n  $ git diff --cached\n\nDo you really think that it is good idea?\n\n> As for WTREE: git diff against work tree does not look at non-tracked\n> ignored files, so why should WTREE?\n\nSo we tailor WTREE do diff behavior?\n\n\nWell, actually, lets examine each command that takes --cached or --index\nand see if NEXT and WTREE would apply at all, and if apply if it would\nhelp.\n\nThe following commands support --cached:\n\n  git diff-index      # plumbing\n  git diff\n  git grep\n  git ls-files\n  git rm\n  git submodule\n\nThe following commands support --index\n\n  git checkout-index  # plumbing\n  git stash\n\nThe following command support both --cached and --index\n\n  git apply\n\nI would skip \"git submodule\" in this analysis because I don't know enough\nabout it, and let's skip for the time being purely plumbing commands.\n \nOf those, NEXT is not applicable at all and wouldn't help \"git rm\" and\n\"git stash\", nor \"git apply\" commands (3/7), isn't it?\n\nIn the case of \"git grep\" using NEXT isn't IMVHO more helpful than using\n\"--cached\".  Note that presence of (slightly misnamed) \"--no-index\" and\nbackward compatibility make some problems in interpreting \"WTREE\" for\n\"git diff\"; natural would for \"git grep WTREE\" to be current \"git grep\",\nand new \"git grep\" be \"git grep --no-index\"... or should it be in reverse,\nand \"git grep WTREE\" to mean \"git grep --no-index\"?  But then your\ninterpretation which takes into account only tracked files fails.\n\nIn the case of \"git ls-files\" the \"--cached\" option is the default;\nNEXT could only hinder here IMVHO.\n\nThat makes \"git grep\" and \"git ls-files\" places where using NEXT is\npossible, but doesn't help much. (2/7).\n\n\nSo we are left with \"git diff\", where we have the following diagram\n(perhaps it should made it into \"git diff\" manpage?):\n\n\n                worktree\n                 |   \\    diff\n                 |    \\   diff NEXT WTREE\n                 |     \\  [add]\n diff HEAD       |      v \n diff HEAD WTREE |    index\n [commit -a]     |     /\n                 |    /   diff --cached\n                 |   /    diff HEAD NEXT  # not NEXT HEAD\n                 v  v     [commit]\n                 HEAD\n\nBesides, isn't this exercise a bit academic?  New to git wouldn't use\nindex, and would use 'git commit -a' and 'git diff'... and that would\nbe enough... well, perhaps except 'git add' + 'git diff'...\n\n> Full disclosure: I love the index but hate the way we make it difficult\n> to use sometimes, and even have to lookup myself what command and option\n> to actually use if all I want to do is diff A against B, or take the\n> version of a file from A and write it to B, when A and B are a commit,\n> the index or the worktree (with a commit being the nonwritable, of course).\n\nNote that in case of saving to worktree you can always use\n\n  $ git show HEAD:./foo  >foo\n  $ git show :0:./foo    >foo     # or just :./foo\n \n> I mean, this is really crazy: We have 4 commands (\"add\", \"rm\n> [--cached]\", \"checkout [<commit>] --\", \"reset [<commit>] --\") which you\n> need to be aware of if all you want to do is moving file contents\n> (content at a path) between a commit, the index and the worktree! And\n> this is actually worse than having 6 for the 6 cases.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169365","messageId":"4DECD406.2010009@drmicha.warpmail.net","threadId":"27548","inReplyTo":"201106061419.34599.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-06-06T13:20:06Z","receivedAt":"2011-06-06T13:20:06Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jakub Narebski venit, vidit, dixit 06.06.2011 14:19:\n> On Mon, 6 June 2011, Michael J Gruber wrote:\n>> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:\n>>> Scott Chacon <schacon@gmail.com> writes:\n>>>\n>>>> For example, implementation details aside, I think having something\n>>>> like WTREE and NEXT available would help users understand that there\n>>>> are these 3 trees that are important and useful in Git and re-inforce\n>>>> a very non-SVN style workflow in that manner.\n>>>\n>>> That's a funny thing to say. Working tree may almost always (to put it\n>>> another way, \"you could make it to\") act like a tree, but the index does\n>>> not act like a tree at all in more important situations.\n>>>\n>>> For example, how would you design the user experience of \"git show NEXT\"?\n>>> Try to write a transcript (i.e. \"The user starts from this state, runs\n>>> these commands, and then says 'git show NEXT'. The user will see this.\"),\n>>> covering various corner cases exhaustively, including what would happen\n>>> before the first commit, and during a conflicted \"pull\" or \"rebase -i\".\n>>>\n>>> It's not just the matter of \"internally pretend to run write-tree with\n>>> 'not committed yet' as a fake commit log message and show it as if it is\n>>> an existing commit.\n>>>\n>>> I wouldn't demand \"implement 'git show NEXT'\" here, nor \"implement it\n>>> efficiently\" here; just designing the user experience is a good first step\n>>> to realize that the index does not act like a tree, and I do not think you\n>>> should spread such a misconception to the end users.\n>>\n>> That is why the other Michael suggested \"NEXT\" as opposed to \"INDEX\":\n>> The index has many aspects, only one of which is \"the contents of the\n>> next commit if I would issue 'git commit' right now\". (I would even go\n>> so far as using \"STAGE\".) Now, it's hard to argue that \"the result of a\n>> commit\" is not tree-like, isn't it? And there's no question what \"git\n>> show NEXT\" would do. Yes, if you repeat that command, you get a\n>> different sha1 each time (because of the time field).\n>>\n>> I don't think anyone is seriously suggesting to replace the index by a\n>> pseudo commit; but the one aspect which people use most could be well\n>> represented like that, and this might even help emphasizing the\n>> different aspects of the index. Give the index an identity as an\n>> \"object\" (no, no new type, not in the object db, but as a ui object),\n>> not something mysterious behind the scenes!\n> \n> So what you suggest would make\n> \n>   $ git diff NEXT WTREE\n> \n> behave differently from\n> \n>   $ git diff\n> \n> and\n> \n>   $ git diff HEAD NEXT\n> \n> behave differently from\n> \n>   $ git diff --cached\n> \n> Do you really think that it is good idea?\n\nI don't know where you're getting from that someone is suggesting to\nmake them different. (And even if, it's new UI, not changed.) Everyone's\nbeen suggesting to make these more accessible.\n\n>> As for WTREE: git diff against work tree does not look at non-tracked\n>> ignored files, so why should WTREE?\n> \n> So we tailor WTREE do diff behavior?\n\nThere is no WTREE and nothing to tailer. We create it so that it is most\nuseful and consistent, whatever that may be.\n\n...\n\n> Besides, isn't this exercise a bit academic?  New to git wouldn't use\n> index, and would use 'git commit -a' and 'git diff'... and that would\n> be enough... well, perhaps except 'git add' + 'git diff'...\n\nBut we want them to grasp and use the git concepts! That is why some of\nus want to make them more accessible.\n\n>> Full disclosure: I love the index but hate the way we make it difficult\n>> to use sometimes, and even have to lookup myself what command and option\n>> to actually use if all I want to do is diff A against B, or take the\n>> version of a file from A and write it to B, when A and B are a commit,\n>> the index or the worktree (with a commit being the nonwritable, of course).\n> \n> Note that in case of saving to worktree you can always use\n> \n>   $ git show HEAD:./foo  >foo\n>   $ git show :0:./foo    >foo     # or just :./foo\n\nExactly, yet another command to add to the list below, and it's not even\nall git (because of the shell redirection).\n\n>> I mean, this is really crazy: We have 4 commands (\"add\", \"rm\n>> [--cached]\", \"checkout [<commit>] --\", \"reset [<commit>] --\") which you\n>> need to be aware of if all you want to do is moving file contents\n>> (content at a path) between a commit, the index and the worktree! And\n>> this is actually worse than having 6 for the 6 cases.\n\nAdd to this craziness the fact that \"checkout -- <path>\" reads from\nindex and writes to worktree, but \"checkout <commit> -- path\" does not\nread from commit and write to worktree - it reads from commit and writes\nto index+worktree.\n\nNote that I'm not suggesting to change any of the beloved\nreset/checkout/whatever variants.\n\nBut the more I look at the commit - index - worktree triangle and the\ncommands we have the more I realize how messed up the ui is, simply\nbecause it is determined by the underlying mechanics (e.g.: checkout\nwrites the index to the worktree, possibly after updating the index from\na commit) rather than by the concepts.\n\nAnd the bad thing is that even when you look at a single command like\nreset or checkout, you can get confused easily because of the multiple\ndifferent functions they overload (e.g. checkout can change HEAD, the\nindex and/or the worktree), and also because of some different defaults\n(HEAD vs. index). I think we lost consistency here because over time\n\"useful defaults\" grew in the wild.\n\nThat is why I'm suggesting concept based variants (move this content\nfrom A to B, show me the difference between A and B).\n\nMichael\n"},{"id":"169367","messageId":"7vk4cz9i1b.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"4DEC8322.6040200@drmicha.warpmail.net","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-06T14:00:16Z","receivedAt":"2011-06-06T14:00:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:\n> ...\n>> For example, how would you design the user experience of \"git show NEXT\"?\n>> Try to write a transcript (i.e. \"The user starts from this state, runs\n>> these commands, and then says 'git show NEXT'. The user will see this.\"),\n>> covering various corner cases exhaustively, including what would happen\n>> before the first commit, and during a conflicted \"pull\" or \"rebase -i\".\n>>  ...\n> That is why the other Michael suggested \"NEXT\" as opposed to \"INDEX\":\n\nThat is why I asked what the user experience of \"git show NEXT\" as opposed\nto \"git show INDEX\" should look like. So what should it look like during a\n\"pull\" that did not finish?\n"},{"id":"169368","messageId":"4DECE147.3060808@drmicha.warpmail.net","threadId":"27548","inReplyTo":"7vk4cz9i1b.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-06-06T14:16:39Z","receivedAt":"2011-06-06T14:16:39Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 06.06.2011 16:00:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:\n>> ...\n>>> For example, how would you design the user experience of \"git show NEXT\"?\n>>> Try to write a transcript (i.e. \"The user starts from this state, runs\n>>> these commands, and then says 'git show NEXT'. The user will see this.\"),\n>>> covering various corner cases exhaustively, including what would happen\n>>> before the first commit, and during a conflicted \"pull\" or \"rebase -i\".\n>>>  ...\n>> That is why the other Michael suggested \"NEXT\" as opposed to \"INDEX\":\n> \n> That is why I asked what the user experience of \"git show NEXT\" as opposed\n> to \"git show INDEX\" should look like. So what should it look like during a\n> \"pull\" that did not finish?\n\nIf NEXT is to mean the result of a commit in the current state, and the\ncurrent state would or should not allow a commit, then trying to access\nthat pseudo-commit should error out with a helpful message.\n\nAnother option is to make NEXT/INDEX mean a tree (:0:). I have not\nthought this through (and have not made a suggestion, accordingly) but I\ndo see a problem in the UI. (I don't think we need to change the\nexisting ui in that respect but can amend and improve it.)\n\nAnyway, it's rc phase :)\n\nMichael\n"},{"id":"169376","messageId":"7vd3ir9btd.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"4DECE147.3060808@drmicha.warpmail.net","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-06T16:14:38Z","receivedAt":"2011-06-06T16:14:38Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n>> That is why I asked what the user experience of \"git show NEXT\" as opposed\n>> to \"git show INDEX\" should look like. So what should it look like during a\n>> \"pull\" that did not finish?\n>\n> If NEXT is to mean the result of a commit in the current state, and the\n> current state would or should not allow a commit, then trying to access\n> that pseudo-commit should error out with a helpful message.\n\nWhat \"helpful message\"? I asked for the user experience, not handwaving.\n\nDo you mean to say that the error message would teach the user that the\ncurrent state is not something you can create a commit? What message would\nthat give the end user?  I am hoping the following is not what will happen:\n\n  Q. I tried \"git show NEXT\" because I wanted to see what the next commit\n     would look like, but I got an error, saying NEXT is not known as I\n     haven't resolved a conflict.\n\n  A. Yes, the message is correct.\n\n  Q. But then how can I see what the next commit would look like?\n\n  A. You would say \"git diff HEAD NEXT\".\n\n  Q. Ah, that is the same as I always do before making a commit to see what\n     I have added so far look sane. Thanks.\n\n     ...after 2 minutes...\n\n  Q. Sorry, it does not work. I get the same error, that says NEXT is not\n     known yet.\n\n  A. Ok, you would say \"git diff HEAD\" the old fashioned way. The person\n     who thought NEXT would be useful didn't think things through.\n\n  Q. Now I am seeing a diff between the conflicted state and the previous\n     commit, I think I can get to where I want to go from here. Thanks.\n\n\n> Another option is to make NEXT/INDEX mean a tree (:0:). I have not\n> thought this through (and have not made a suggestion, accordingly) but I\n> do see a problem in the UI. (I don't think we need to change the\n> existing ui in that respect but can amend and improve it.)\n>\n> Anyway, it's rc phase :)\n\nRc or not rc, just repeating a fuzzy and uncooked \"idea\" around phoney\nref-looking names that will end up confusing the users, and selling that\nas if it is a logical conclusion to \"we want to give an easier to\nunderstand UI\", without presenting a solid user experience design that is\nconvincing enough that the \"idea\" will reduce confusion will not get us\nanywhere, especially when it is sprinkled with ad hominem attack at me.\n"},{"id":"169377","messageId":"7v8vtf9bds.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"201106061419.34599.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-06T16:23:59Z","receivedAt":"2011-06-06T16:23:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> On Mon, 6 June 2011, Michael J Gruber wrote:\n>\n> So what you suggest would make\n>\n>   $ git diff NEXT WTREE\n>\n> behave differently from\n>\n>   $ git diff\n>\n> and\n>\n>   $ git diff HEAD NEXT\n>\n> behave differently from\n>\n>   $ git diff --cached\n>\n> Do you really think that it is good idea?\n\nI do not know if Michael is suggesting to make it different, but if the\ndifference is an improvement, it may be a good thing. Being different from\nthe current behaviour should not be a basis for automatic rejection ---\notherwise we won't make any progress.\n\nI just don't know what the plans by advocates of this NEXT/WTREE are for\nconflicted cases [*1*] to tell how they want to make the user experience, so I\ncannot even tell if they want something different, let alone to judge if\nthe proposed difference is an improvement.\n\n[Footnote]\n\n*1* There may be other equally important corner cases, but let's tackle\none simple and obvious thing first to see where this goes.\n"},{"id":"169378","messageId":"1307378417.4321.25.camel@drew-northup.unet.maine.edu","threadId":"27548","inReplyTo":"7v8vtf9bds.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Drew Northup","fromEmail":"drew.northup@maine.edu","sentAt":"2011-06-06T16:40:16Z","receivedAt":"2011-06-06T16:40:16Z","isPatch":false,"sender":{"key":"drew.northup@maine.edu","avatar":"https://avatars.githubusercontent.com/u/18331571?v=4"},"body":"\nOn Mon, 2011-06-06 at 09:23 -0700, Junio C Hamano wrote:\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n> > On Mon, 6 June 2011, Michael J Gruber wrote:\n> >\n> > So what you suggest would make\n> >\n> >   $ git diff NEXT WTREE\n> >\n> > behave differently from\n> >\n> >   $ git diff\n> >\n> > and\n> >\n> >   $ git diff HEAD NEXT\n> >\n> > behave differently from\n> >\n> >   $ git diff --cached\n> >\n> > Do you really think that it is good idea?\n> \n> I do not know if Michael is suggesting to make it different, but if the\n> difference is an improvement, it may be a good thing. Being different from\n> the current behaviour should not be a basis for automatic rejection ---\n> otherwise we won't make any progress.\n> \n> I just don't know what the plans by advocates of this NEXT/WTREE are for\n> conflicted cases [*1*] to tell how they want to make the user experience, so I\n> cannot even tell if they want something different, let alone to judge if\n> the proposed difference is an improvement.\n> \n> [Footnote]\n> \n> *1* There may be other equally important corner cases, but let's tackle\n> one simple and obvious thing first to see where this goes.\n\nGiven the history of the thread including this:\nhttp://article.gmane.org/gmane.comp.version-control.git/172220\n\nI'd prefer not introducing any more global pseudo-refs....\n\n-- \n-Drew Northup\n________________________________________________\n\"As opposed to vegetable or mineral error?\"\n-John Pescatore, SANS NewsBites Vol. 12 Num. 59\n"},{"id":"169380","messageId":"BANLkTi=KZN3g4s9jHSgYcPHA4eM+2U3g4w@mail.gmail.com","threadId":"27548","inReplyTo":"7vd3ir9btd.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Scott Chacon","fromEmail":"schacon@gmail.com","sentAt":"2011-06-06T17:42:47Z","receivedAt":"2011-06-06T17:42:47Z","isPatch":false,"sender":{"key":"schacon@gmail.com","avatar":"https://gravatar.com/avatar/9b13a8a078e1dcf8588c4eea9554445d51ebed6c41b51f56f4d96738130b05c6?d=mp&s=160"},"body":"Hey,\n\nOn Mon, Jun 6, 2011 at 9:14 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n>\n>>> That is why I asked what the user experience of \"git show NEXT\" as opposed\n>>> to \"git show INDEX\" should look like. So what should it look like during a\n>>> \"pull\" that did not finish?\n>>\n>> If NEXT is to mean the result of a commit in the current state, and the\n>> current state would or should not allow a commit, then trying to access\n>> that pseudo-commit should error out with a helpful message.\n>\n> What \"helpful message\"? I asked for the user experience, not handwaving.\n>\n> Do you mean to say that the error message would teach the user that the\n> current state is not something you can create a commit? What message would\n> that give the end user?  I am hoping the following is not what will happen:\n>\n>  Q. I tried \"git show NEXT\" because I wanted to see what the next commit\n>     would look like, but I got an error, saying NEXT is not known as I\n>     haven't resolved a conflict.\n>\n>  A. Yes, the message is correct.\n\nI'm not sure why this wouldn't just list out the index tree, having\nsome message for entries that have more than one stage.  Like a\nporcelain-ized version of 'git ls-files --stage', maybe in this case\nwith a warning at the bottom that a subsequent commit command will not\ncomplete.  Even something similar to what would happen if you ran\n'commit' right then:\n\n  fatal: 'commit' will not be possible because you have unmerged files.\n\n>  Q. But then how can I see what the next commit would look like?\n>\n>  A. You would say \"git diff HEAD NEXT\".\n>\n>  Q. Ah, that is the same as I always do before making a commit to see what\n>     I have added so far look sane. Thanks.\n\nWhy would this look sane? I would think this would say \"* Unmerged\npath <file>\" just like 'diff --cached would do.\n\n>\n>     ...after 2 minutes...\n>\n>  Q. Sorry, it does not work. I get the same error, that says NEXT is not\n>     known yet.\n>\n>  A. Ok, you would say \"git diff HEAD\" the old fashioned way. The person\n>     who thought NEXT would be useful didn't think things through.\n\nI think the point would be that \"git diff HEAD WTREE\" would give you\nthis same output and if you had the basic concept of these three\nimportant areas of Git that you could be explicit about what you\nwanted to see or compare rather than having to look up the specific\nspecial case that will show you what you want. Consider these very\ncommon scenarios from a new user perspective: you want to see what is\nchanged in your working tree but not added yet, you want to see what\nis added but not committed, you want to see the sum total of all\nchanges since your last commit and you want to see what the index\ncurrently looks like.\n\nHere are the commands currently:\n\na) diff\nb) diff --cached\nc) diff HEAD\nd) ls-files --stage\n\nHere would be the commands with the proposed pseudo-trees.\n\na) diff NEXT WTREE\nb) diff HEAD NEXT\nc) diff HEAD WTREE\nd) show NEXT\n\nIt seems to me to be more guessable and straightforward for new users.\n But, yes, I assume there would be some difficulty in supporting it\neverywhere.\n\n>\n>  Q. Now I am seeing a diff between the conflicted state and the previous\n>     commit, I think I can get to where I want to go from here. Thanks.\n>\n>\n>> Another option is to make NEXT/INDEX mean a tree (:0:). I have not\n>> thought this through (and have not made a suggestion, accordingly) but I\n>> do see a problem in the UI. (I don't think we need to change the\n>> existing ui in that respect but can amend and improve it.)\n>>\n>> Anyway, it's rc phase :)\n>\n> Rc or not rc, just repeating a fuzzy and uncooked \"idea\" around phoney\n> ref-looking names that will end up confusing the users, and selling that\n> as if it is a logical conclusion to \"we want to give an easier to\n> understand UI\", without presenting a solid user experience design that is\n> convincing enough that the \"idea\" will reduce confusion will not get us\n> anywhere, especially when it is sprinkled with ad hominem attack at me.\n\nI think I'm the only one that mentioned your name so I apologize if\nyou saw that as an attack.  I was not saying you are unreasonable in\nnot changing the UI all the time, or that you are unreasonable for not\nliking the NEXT/WTREE - there are certainly cases I'm not considering.\n(For example, I'm more concerned about things like 'git commit-tree\nNEXT' or 'git rev-parse NEXT' if the index is in a weird state - it\nobviously has to be special-cased and I would assume only usable at\nthe porcelain level, possibly only by 'diff', 'show' and 'grep'. It's\nthe implementation I'm mainly worried about, I feel that the UI would\nbe pretty straightforward in all these cases.)\n\nRe: the ad-hominim stuff, I was simply remarking that the\n'reset'/'checkout' debate has been had several times and there is\nprecedent for it being a non-starter.  I also see and understand the\nargument from you and Linus about that, I just happen to disagree with\nit. It was not meant to be an attack.\n\nScott\n"},{"id":"169390","messageId":"7vr576943r.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"BANLkTi=KZN3g4s9jHSgYcPHA4eM+2U3g4w@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-06T19:01:12Z","receivedAt":"2011-06-06T19:01:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Scott Chacon <schacon@gmail.com> writes:\n\n> On Mon, Jun 6, 2011 at 9:14 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> ...\n>>>> That is why I asked what the user experience of \"git show NEXT\" as opposed\n>>>> to \"git show INDEX\" should look like. So what should it look like during a\n>>>> \"pull\" that did not finish?\n>>>\n>>> If NEXT is to mean the result of a commit in the current state, and the\n>>> current state would or should not allow a commit, then trying to access\n>>> that pseudo-commit should error out with a helpful message.\n>>\n>> What \"helpful message\"? I asked for the user experience, not handwaving.\n>>\n>> Do you mean to say that the error message would teach the user that the\n>> current state is not something you can create a commit? What message would\n>> that give the end user?  I am hoping the following is not what will happen:\n>>\n>>  Q. I tried \"git show NEXT\" because I wanted to see what the next commit\n>>     would look like, but I got an error, saying NEXT is not known as I\n>>     haven't resolved a conflict.\n>>\n>>  A. Yes, the message is correct.\n>\n> I'm not sure why this wouldn't just list out the index tree,...\n\nYou are not entitled to say \"I'm not sure\" ;-). I asked you to show a\ndesign of the user experience of \"git show NEXT\", as an advocate for the\nNEXT/WTREE notation.\n\nI'd take it that you would \"just list out the index tree\" as the outline\nof the user experience.\n\n>>  A. You would say \"git diff HEAD NEXT\".\n>>\n>>  Q. Ah, that is the same as I always do before making a commit to see what\n>>     I have added so far look sane. Thanks.\n>\n> Why would this look sane? I would think this would say \"* Unmerged\n> path <file>\" just like 'diff --cached would do.\n\nEither you read it too hastily or I didn't write this clear enough; \"sane\"\ndoes not refer to the command. In this story, the novice is saying \"Before\nI make a commit, I check if my changes so far matches what I wanted to\nachieve, in other words, I check the sanity of my changes. And 'git diff\nHEAD NEXT' is the command I use when I am not in this weird 'conflicted'\nstate. I am happy that I can use the same command\".\n\n> But, yes, I assume there would be some difficulty in supporting it\n> everywhere.\n\nI don't care too much about \"difficulty in uniformly implementing\". I am\ndoubting that you can _design_ uniformly for these new tokens to make\nenough sense to help the new people. That is why I've been asking for\nconcrete examples of user experience design, sample transcripts, that\ncovers known corner cases.\n\nIf NEXT/WTREE advocates cannot come up with one, or if that is just to\npunt and say \"NEXT is not defined in this case---use the traditional\ncommand\" in the error message, I don't see much point in discussing this\nfurther. It will end up with the same whine-fest as previous rounds.\n"},{"id":"169422","messageId":"BANLkTinE8tCRZ-HFP0uwm6odGNAxjZPXng@mail.gmail.com","threadId":"27548","inReplyTo":"BANLkTi=yytzDrJLvVn_ZhJOiQs-rqvKi1w@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-07T02:31:07Z","receivedAt":"2011-06-07T02:31:07Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"I think NEXT and WTREE should be like tree objects, not commits, so I\nwould argue that \"git show NEXT\" should show what it shows for a tree.\n From the man page:\n\n\"For trees, it shows the names (equivalent to git ls-tree with --name-only).\"\n\n\n\"git diff HEAD NEXT\" during a merge conflict: During the merge\nconflict there are two groups of changing files.  Some files have been\nresolved and reside in \"Stage0\".  The others have not been resolved\nand a copy resides in each of \"Stage1\", 2, and 3.  (Which I eagerly\nwant to name BASE, HEAD, and MERGE_HEAD.)\n\nMy thought is that NEXT should only represent those changing files\nthat have been resolved.  So, NEXT would be HEAD plus the files in\nStage0.  So, \"git diff HEAD NEXT\" would print out the changes in\nStage0.\n\nThe trickier question for me is what does this make \"git diff WTREE\nNEXT\"?  Well, the resolved changes are the same in WTREE and NEXT.\nThe unresolved files in NEXT are the same as in HEAD.  So, \"git diff\nWTREE NEXT\" would print out the unresolved changes between WTREE and\nHEAD.\n\nWhat I don't like about that is that at the point of conflict in each\nfile, \"git merge\" has written the changes from HEAD and MERGE_HEAD.\nSo, printing the changes between HEAD and WTREE will resulting in the\nchanges done by HEAD printed twice.  That, while understandable, isn't\nso pretty.\n\n\nI've engineered a conflicted merge and taken a look at what \"git diff\n--cached HEAD\" and \"git diff --cached\" looks like.  Can someone\nconfirm that the current behavior is equivalent to what I described\nabove?\n\n\nJunio asked: So what should it look like during a \"pull\" that did not finish?\n\nIs this the same as a conflicted merge state?  (Except possibly with\nFETCH_HEAD instead of MERGE_HEAD.)\n\n\nJunio asked: \"rebase -i\"?\n\nI know what this does (and love it!), but not how it works.  I\ncertainly don't know the state it leaves things in when it's\nconflicted.  I'll let someone else go to bat here.\n\n\nTeach a noob: What's \"rc phase\"?\n\n\nMike\n\n\n\nOn Mon, Jun 6, 2011 at 3:01 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Scott Chacon <schacon@gmail.com> writes:\n>\n> > On Mon, Jun 6, 2011 at 9:14 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> > ...\n> >>>> That is why I asked what the user experience of \"git show NEXT\" as opposed\n> >>>> to \"git show INDEX\" should look like. So what should it look like during a\n> >>>> \"pull\" that did not finish?\n> >>>\n> >>> If NEXT is to mean the result of a commit in the current state, and the\n> >>> current state would or should not allow a commit, then trying to access\n> >>> that pseudo-commit should error out with a helpful message.\n> >>\n> >> What \"helpful message\"? I asked for the user experience, not handwaving.\n> >>\n> >> Do you mean to say that the error message would teach the user that the\n> >> current state is not something you can create a commit? What message would\n> >> that give the end user?  I am hoping the following is not what will happen:\n> >>\n> >>  Q. I tried \"git show NEXT\" because I wanted to see what the next commit\n> >>     would look like, but I got an error, saying NEXT is not known as I\n> >>     haven't resolved a conflict.\n> >>\n> >>  A. Yes, the message is correct.\n> >\n> > I'm not sure why this wouldn't just list out the index tree,...\n>\n> You are not entitled to say \"I'm not sure\" ;-). I asked you to show a\n> design of the user experience of \"git show NEXT\", as an advocate for the\n> NEXT/WTREE notation.\n>\n> I'd take it that you would \"just list out the index tree\" as the outline\n> of the user experience.\n>\n> >>  A. You would say \"git diff HEAD NEXT\".\n> >>\n> >>  Q. Ah, that is the same as I always do before making a commit to see what\n> >>     I have added so far look sane. Thanks.\n> >\n> > Why would this look sane? I would think this would say \"* Unmerged\n> > path <file>\" just like 'diff --cached would do.\n>\n> Either you read it too hastily or I didn't write this clear enough; \"sane\"\n> does not refer to the command. In this story, the novice is saying \"Before\n> I make a commit, I check if my changes so far matches what I wanted to\n> achieve, in other words, I check the sanity of my changes. And 'git diff\n> HEAD NEXT' is the command I use when I am not in this weird 'conflicted'\n> state. I am happy that I can use the same command\".\n>\n> > But, yes, I assume there would be some difficulty in supporting it\n> > everywhere.\n>\n> I don't care too much about \"difficulty in uniformly implementing\". I am\n> doubting that you can _design_ uniformly for these new tokens to make\n> enough sense to help the new people. That is why I've been asking for\n> concrete examples of user experience design, sample transcripts, that\n> covers known corner cases.\n>\n> If NEXT/WTREE advocates cannot come up with one, or if that is just to\n> punt and say \"NEXT is not defined in this case---use the traditional\n> command\" in the error message, I don't see much point in discussing this\n> further. It will end up with the same whine-fest as previous rounds.\n>\n"},{"id":"169424","messageId":"7voc2a70f0.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"BANLkTinE8tCRZ-HFP0uwm6odGNAxjZPXng@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-07T04:03:47Z","receivedAt":"2011-06-07T04:03:47Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Nahas <mike.nahas@gmail.com> writes:\n\n> I think NEXT and WTREE should be like tree objects, not commits, so I\n> would argue that \"git show NEXT\" should show what it shows for a tree.\n\nSo what is the definition of such a \"tree\" during a conflicted merge?\n\nThe traditional definition is \"such a state cannot be expressed as a\ntree\". You are free to define it the same way, or for NEXT to be more\nuseful than status quo, come up with a better definition.\n\n> My thought is that NEXT should only represent those changing files\n> that have been resolved.  So, NEXT would be HEAD plus the files in\n> Stage0.  So, \"git diff HEAD NEXT\" would print out the changes in\n> Stage0.\n\nThat would mean conflicted files will all be shown as removed, or\nunchanged?  Either would be more confusing.\n"},{"id":"169429","messageId":"4DEDC124.3060302@drmicha.warpmail.net","threadId":"27548","inReplyTo":"7vd3ir9btd.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-06-07T06:11:48Z","receivedAt":"2011-06-07T06:11:48Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 06.06.2011 18:14:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>>> That is why I asked what the user experience of \"git show NEXT\" as opposed\n>>> to \"git show INDEX\" should look like. So what should it look like during a\n>>> \"pull\" that did not finish?\n>>\n>> If NEXT is to mean the result of a commit in the current state, and the\n>> current state would or should not allow a commit, then trying to access\n>> that pseudo-commit should error out with a helpful message.\n> \n> What \"helpful message\"? I asked for the user experience, not handwaving.\n\nI specified the exit behaviour, that is no handwaving.\n\n[...]\n>> Another option is to make NEXT/INDEX mean a tree (:0:). I have not\n>> thought this through (and have not made a suggestion, accordingly) but I\n>> do see a problem in the UI. (I don't think we need to change the\n>> existing ui in that respect but can amend and improve it.)\n>>\n>> Anyway, it's rc phase :)\n> \n> Rc or not rc,\n\nI spend my limited git time running builds and tests for master on\nseveral systems these days (and following changed build environments\nthere which I can't control).\n\n> just repeating a fuzzy and uncooked \"idea\" around phoney\n> ref-looking names that will end up confusing the users, and selling that\n> as if it is a logical conclusion to \"we want to give an easier to\n> understand UI\", without presenting a solid user experience design that is\n> convincing enough that the \"idea\" will reduce confusion will not get us\n> anywhere, especially when it is sprinkled with ad hominem attack at me.\n\nI've re-read all my posts in this thread and have no idea what you're\nreferring to here. If I were more sensitive I could spot attacks at\nmyself in the above, though. Just count your usage of terms like\n\"phoney\", \"fuzzy\" etc. directed at other people's ideas and arguments.\n\nI'm actually wondering whether there is any agreement on the sheer fact\nthat there is a problem in the ui, namely having too many different\ncommands or options (reset/commit/add/checkout resp. diff invocations;\nI've described that already) for different aspects of a \"similar\"\nconcept (cp content version from A to B resp. diff it).\n\nIf we don't agree that there's a problem then there's no point\ndiscussing solutions (or ideas/brainstorms thereof).\n\nMichael\n"},{"id":"169436","messageId":"BANLkTi=Wu77cJikN63NjSqb-PtB4+9BiEQ@mail.gmail.com","threadId":"27548","inReplyTo":"7voc2a70f0.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-07T11:04:31Z","receivedAt":"2011-06-07T11:04:31Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"On Tue, Jun 7, 2011 at 12:03 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Michael Nahas <mike.nahas@gmail.com> writes:\n>\n>> I think NEXT and WTREE should be like tree objects, not commits, so I\n>> would argue that \"git show NEXT\" should show what it shows for a tree.\n>\n> So what is the definition of such a \"tree\" during a conflicted merge?\n\nGood question.  You've been asking it a lot.  I answered it later in the email.\n\n> The traditional definition is \"such a state cannot be expressed as a\n> tree\". You are free to define it the same way, or for NEXT to be more\n> useful than status quo, come up with a better definition.\n>\n>> My thought is that NEXT should only represent those changing files\n>> that have been resolved.  So, NEXT would be HEAD plus the files in\n>> Stage0.  So, \"git diff HEAD NEXT\" would print out the changes in\n>> Stage0.\n\n(during a conflicted merge...)\n\"NEXT would be HEAD plus the files in Stage0\".\n\nThat is the tree.  HEAD plus the resolved files.\n\n> That would mean conflicted files will all be shown as removed, or\n> unchanged?  Either would be more confusing.\n\nConflicted files would be shown as unchanged in NEXT.\n\n\"diff NEXT HEAD\" == changes in resolved files\n\"diff WTREE NEXT\" == changes in conflicted files\n\"diff WTREE HEAD\" == all changes.\n\nThat makes a lot of sense to me.  Those are the three different\nchangesets I'd want to see and those are the logical commands using\nNEXT and WTREE to see them.\n\nI _believe_ but don't know for sure that that _is_ the current behavior for:\n\n\"diff --cached HEAD\" and\n\"diff --cached\"\n\"diff HEAD\"\n\nIf it is the current behavior, I don't see how it could be more\nconfusing.  It's exactly the same amount of confusing ... with a more\nregular syntax, IMHO.\n\n\nAnother way to think about this:  If you had a conflicted merge and\nsomeone allowed you to create the next commit with a command \"git\ncommit --force\", what would you expect to be in the created commit?\nWouldn't it be only the resolved files?  The files in Stage0?  The\nfiles in WTREE have the \"<<<<</=====/>>>>>\" blocks in them - would you\nwant to commit those?  No.  For those files, you'd prefer the versions\nyou already had in HEAD.\n\nMike\n"},{"id":"169441","messageId":"20110607114526.GA9846@elie","threadId":"27548","inReplyTo":"4DEDC124.3060302@drmicha.warpmail.net","subject":"Re: Command-line interface thoughts","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-06-07T11:45:26Z","receivedAt":"2011-06-07T11:45:26Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nMichael J Gruber wrote:\n\n> I'm actually wondering whether there is any agreement on the sheer fact\n> that there is a problem in the ui, namely having too many different\n> commands or options (reset/commit/add/checkout resp. diff invocations;\n> I've described that already) for different aspects of a \"similar\"\n> concept (cp content version from A to B resp. diff it).\n\nI agree that there is a problem --- a difficult learning curve that\nmeans for example it took a year or so before I was used to the \"git\ndiff describes the changes you are preparing\" mnemonic for the various\n0- and 1-tree git diff forms --- but I do not agree with your specific\ncharacterization of it.  If there are too many ways to spell\noperations of a certain class then we should be looking to deprecate\nsome of them, and that is a direction I do not think would be very\nfruitful.\n\nSo I'd prefer to focus on actual UI bugs, of the form, \"A reasonable\nperson tried this command, expecting this effect, and got some other\neffect instead\" or \"A reasonable person was searching for a command\nwith this effect and the only solutions she came up with were\nconvoluted\".\n\nExample:\n\nLong ago, I remember wanting to see what unstaged changes were in\nthe worktree --- that is, I wanted to compare the content of the\nindex to the worktree.  So, tell \"git diff\" to look at the index:\n\n\tgit diff --cached\n\nNo, I should have used \"git diff\" and the model of \"git diff\" I had\nwas completely wrong.  How can we avoid this confusion?\n\nOne answer would be to adapt \"git diff\" to match a familiar model,\nthat of the ordinary \"diff\" command.  \"diff\" takes two arguments,\npreimage and postimage, so that would be:\n\n\tgit diff INDEX WORKTREE\n\nIf there were an unmerged path in the index, this would do a\nthree-way diff, just like \"git diff\" currently does.\n\nThat all sounds great, but I do not find it completely satisfactory.\nOne problem is that if this is the mental model people have of\n\"git diff\", the three-way diff for a multiple stages, behavior of\n\"git diff <paths>\", and so on, however they are spelled, will look\ncompletely mystifying.  From the point of view of \"this command\nexplains the changes in the worktree\" they make sense, while from the\npoint of view of \"compare A to B\" they don't make much sense at all.\nSo this change just defers the learning process.\n\nI think part of the problem in the current UI is that the\ndocumentation never spells out the idea of what plain \"git diff\" is\nfor.  Worse, \"--cached means to look to the index in place of the\nworktree\" doesn't seem to be spelled out anywhere except gitcli(7).  I\nam not sure it is worth the headache of spelling the latter out\ninstead of changing the UI to be easier to explain.\n\nSomething like \"git diff --index-only\" would at least set people\nthinking in the right direction --- \"index only as opposed to what?\".\n\nWith an INDEX pseudo-tree,\n\n\tgit diff INDEX\n\nis a synonym for \"git diff\", and to do \"git diff --cached\" one would\nhave to write\n\n\tgit diff HEAD INDEX\n\nI like the \"rename --cached to --index-only\" proposal more but am\nnot too satisfied with it, either.  In a way it is tempting to teach\npeople\n\n\tgit diff-files -p;\t# compare worktree to index\n\tgit diff-index -p HEAD;\t# compare worktree to HEAD\n\tgit diff-index -p --cached HEAD;\t# compare index to HEAD\n\tgit diff-tree -p HEAD HEAD^;\t# compare HEAD^ to HEAD\n\nI wish there were some other alternative that can be learned more\ngracefully.\n\nSorry for the longwinded, meandering message.  Still, I hope it\nclarifies a little.\n\nJonathan\n"},{"id":"169493","messageId":"4DEE755C.8030108@ira.uka.de","threadId":"27548","inReplyTo":"20110607114526.GA9846@elie","subject":"Re: Command-line interface thoughts","fromName":"Holger Hellmuth","fromEmail":"hellmuth@ira.uka.de","sentAt":"2011-06-07T19:00:44Z","receivedAt":"2011-06-07T19:00:44Z","isPatch":false,"sender":{"key":"hellmuth@ira.uka.de","avatar":null},"body":"On 07.06.2011 13:45, Jonathan Nieder wrote:\n[...]\n> If there were an unmerged path in the index, this would do a\n> three-way diff, just like \"git diff\" currently does.\n>\n> That all sounds great, but I do not find it completely satisfactory.\n> One problem is that if this is the mental model people have of\n> \"git diff\", the three-way diff for a multiple stages, behavior of\n> \"git diff<paths>\", and so on, however they are spelled, will look\n> completely mystifying.  From the point of view of \"this command\n> explains the changes in the worktree\" they make sense, while from the\n> point of view of \"compare A to B\" they don't make much sense at all.\n> So this change just defers the learning process.\n\nIf someone finds the three-way diff completely mystifiying, how do you \nexpect him to resolve a merge conflict at all? Or recognize that there \nis one? Or find the command to use after editing out the conflict markers?\n\nA novice user will have no real mental model anyway. He will be looking \nfor simple (and easy to remember) commands for (mostly) simple needs.\n\n> I think part of the problem in the current UI is that the\n> documentation never spells out the idea of what plain \"git diff\" is\n> for.  Worse, \"--cached means to look to the index in place of the\n> worktree\" doesn't seem to be spelled out anywhere except gitcli(7).  I\n> am not sure it is worth the headache of spelling the latter out\n> instead of changing the UI to be easier to explain.\n>\n> Something like \"git diff --index-only\" would at least set people\n> thinking in the right direction --- \"index only as opposed to what?\".\n>\n> With an INDEX pseudo-tree,\n>\n> \tgit diff INDEX\n>\n> is a synonym for \"git diff\", and to do \"git diff --cached\" one would\n> have to write\n>\n> \tgit diff HEAD INDEX\n>\n> I like the \"rename --cached to --index-only\" proposal more but am\n> not too satisfied with it, either.  In a way it is tempting to teach\n> people\n>\n> \tgit diff-files -p;\t# compare worktree to index\n> \tgit diff-index -p HEAD;\t# compare worktree to HEAD\n> \tgit diff-index -p --cached HEAD;\t# compare index to HEAD\n> \tgit diff-tree -p HEAD HEAD^;\t# compare HEAD^ to HEAD\n\nif you look at the comments you put behind the commands, they look very \nmuch like the proposed diff command. How much time would a novice (and \neveryone else) need to remember your comments compared to your commands? \nA lot less.\n\nHolger.\n"},{"id":"169491","messageId":"20110607191152.GB24929@elie","threadId":"27548","inReplyTo":"4DEE755C.8030108@ira.uka.de","subject":"Re: Command-line interface thoughts","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-06-07T19:11:52Z","receivedAt":"2011-06-07T19:11:52Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Holger Hellmuth wrote:\n\n> If someone finds the three-way diff completely mystifiying, how do\n> you expect him to resolve a merge conflict at all? Or recognize that\n> there is one? Or find the command to use after editing out the\n> conflict markers?\n>\n> A novice user will have no real mental model anyway.\n\nYes, I think you're getting closer to the point I was trying to make.\nA novice will have a naive mental model, and a good user interface\nneeds to be close to it but not too close.  Close because the UI must\nbe intuitive on its own.  Not too close because a good UI will help in\nleading such a person to productive ways of thinking and working, by\nmaking common tasks convenient.\n\nSo much for generalities.\n"},{"id":"169497","messageId":"4DEE7D46.3080700@lsrfire.ath.cx","threadId":"27548","inReplyTo":"20110607114526.GA9846@elie","subject":"Re: Command-line interface thoughts","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2011-06-07T19:34:30Z","receivedAt":"2011-06-07T19:34:30Z","isPatch":false,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 07.06.2011 13:45, schrieb Jonathan Nieder:\n> Example:\n> \n> Long ago, I remember wanting to see what unstaged changes were in\n> the worktree --- that is, I wanted to compare the content of the\n> index to the worktree.  So, tell \"git diff\" to look at the index:\n> \n> \tgit diff --cached\n> \n> No, I should have used \"git diff\" and the model of \"git diff\" I had\n> was completely wrong.  How can we avoid this confusion?\n\nWould it help if a header was shown in this case, describing the\nfollowing diff, e.g. something like this:\n\n\t$ cd /tmp && mkdir repo && cd repo && git init\n\tInitialized empty Git repository in /tmp/repo/.git/\n\t$ echo a >a && git add a && git commit -m.\n\t[master (root-commit) faeefb5] .\n\t 1 files changed, 1 insertions(+), 0 deletions(-)\n\t create mode 100644 a\n\t$ echo b >a\n\t$ git diff\n\tLet's get rrready to diiiiff!!\n\tIn corner a: the INDEX!  And in corner b: the WORKTREE!\n\n\tdiff --git a/a b/a\n\tindex 7898192..6178079 100644\n\t--- a/a\n\t+++ b/a\n\t@@ -1 +1 @@\n\t-a\n\t+b\n\nSuch a prefix would be ignored by patch etc..  You would still get it\nwrong at the first try but now you'd get immediate feedback on what you\nactually compared, without having to read the manpage.\n\nRené\n"},{"id":"169499","messageId":"201106072138.50785.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DEE7D46.3080700@lsrfire.ath.cx","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-07T19:38:49Z","receivedAt":"2011-06-07T19:38:49Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"René Scharfe wrote:\n\n> Would it help if a header was shown in this case, describing the\n> following diff, e.g. something like this:\n> \n> \t$ cd /tmp && mkdir repo && cd repo && git init\n> \tInitialized empty Git repository in /tmp/repo/.git/\n> \t$ echo a >a && git add a && git commit -m.\n> \t[master (root-commit) faeefb5] .\n> \t 1 files changed, 1 insertions(+), 0 deletions(-)\n> \t create mode 100644 a\n> \t$ echo b >a\n> \t$ git diff\n> \tLet's get rrready to diiiiff!!\n> \tIn corner a: the INDEX!  And in corner b: the WORKTREE!\n> \n> \tdiff --git a/a b/a\n> \tindex 7898192..6178079 100644\n> \t--- a/a\n> \t+++ b/a\n> \t@@ -1 +1 @@\n> \t-a\n> \t+b\n> \n> Such a prefix would be ignored by patch etc..  You would still get it\n> wrong at the first try but now you'd get immediate feedback on what you\n> actually compared, without having to read the manpage.\n\nWe have `diff.mnemonicprefix`, though it is not header... and is not set\nby default ;-)\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169504","messageId":"201106072233.28244.jnareb@gmail.com","threadId":"27548","inReplyTo":"20110607191152.GB24929@elie","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-07T20:33:27Z","receivedAt":"2011-06-07T20:33:27Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Tue, 7 June 2011, Jonathan Nieder wrote:\n> Holger Hellmuth wrote:\n> \n> > If someone finds the three-way diff completely mystifiying, how do\n> > you expect him to resolve a merge conflict at all? Or recognize that\n> > there is one? Or find the command to use after editing out the\n> > conflict markers?\n> >\n> > A novice user will have no real mental model anyway.\n> \n> Yes, I think you're getting closer to the point I was trying to make.\n> A novice will have a naive mental model, and a good user interface\n> needs to be close to it but not too close.  Close because the UI must\n> be intuitive on its own.  Not too close because a good UI will help in\n> leading such a person to productive ways of thinking and working, by\n> making common tasks convenient.\n> \n> So much for generalities.\n\nTo reiterate; perhaps it is not stated clearly in documentation:\n\n1. \"git diff\" is about examining _your_ changes.  This short form is the\n   same in every SCM.\n\n   Because of explicit index (cache, staging area) one needs to know if\n   it is working area against index, or working area against HEAD. \n   Thinking about merge conflict case helps to remember; in such case\n   you want your changes against partially resolved merge.\n\n   Also advanced users can use index to hide fully cooked changes from\n   having to browse during review.\n\n   Novice users which do not use index (and use \"git commit -a\") would\n   never notice the difference, if not for the complication of newly\n   added files: in other SCM you would see on \"<scm> diff\" creation\n   diff (well, there is \"git add -N\").  Same with removal if one uses\n   \"git rm\" and not simply \"rm\".\n\n2. \"git diff --cached\" is about cached (staged) changes, therefore\n   it is index against HEAD.\n\n3. \"git diff <commit>\" in general, and \"git diff HEAD\" in particular,\n   is about your changes (worktree), compared to given commit.\n\nAt in no place I _have_ to explain what is compared with what to explain \nwhen and what for to use \"git diff\", \"git diff --cached\" and \"git diff \nHEAD\".\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169593","messageId":"201106081312.46377.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DEDC124.3060302@drmicha.warpmail.net","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-08T11:12:45Z","receivedAt":"2011-06-08T11:12:45Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Tue, 7 June 2011, Michael J Gruber wrote:\n> Junio C Hamano venit, vidit, dixit 06.06.2011 18:14:\n \n> > just repeating a fuzzy and uncooked \"idea\" around phoney\n> > ref-looking names that will end up confusing the users, and selling that\n> > as if it is a logical conclusion to \"we want to give an easier to\n> > understand UI\", without presenting a solid user experience design that is\n> > convincing enough that the \"idea\" will reduce confusion will not get us\n> > anywhere, especially when it is sprinkled with ad hominem attack at me.\n> \n> I've re-read all my posts in this thread and have no idea what you're\n> referring to here.\n\nI think one can see __ad hominem__ attack in *implication* that the idea\ngot shot down because of Junio (and Linus) _personal_ resistance to\nfresh ideas.  And that is Junio stubborness than stand in the way of\nnew ideas.  Certainly somebody more sensitive might read it as such.\n\n> If I were more sensitive I could spot attacks at \n> myself in the above, though. Just count your usage of terms like\n> \"phoney\", \"fuzzy\" etc. directed at other people's ideas and arguments.\n\nThose \"attacks\" are at ideas and arguments, not at people.\n\n> I'm actually wondering whether there is any agreement on the sheer fact\n> that there is a problem in the ui, namely having too many different\n> commands or options (reset/commit/add/checkout resp. diff invocations;\n> I've described that already) for different aspects of a \"similar\"\n> concept (cp content version from A to B resp. diff it).\n> \n> If we don't agree that there's a problem then there's no point\n> discussing solutions (or ideas/brainstorms thereof).\n\nWell, some of current overloading might be leftover result of \"git is too\ncomplicated, see how many commands it have [in $PATH]\" criticism of git\nand comparison with other (D)VCS... and in reducing number of commands\nthe pendulum perhaps went too far in opposite direction.\n\nI don't quite think that we need \"git diff NEXT WTREE\"; the short\nand sweet \"git diff\" is short for a reason, see my other response in this\nthread:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/175061/focus=175265\n\nand that the pseudo-almost-ref notation it would require for each such\npseudo-ref considering many corner cases:\n\n  git diff <pseudo-ref-A> <pseudo-ref-B>\n  git diff <commit or tree> <pseudo-ref>\n  git diff <pseudo-ref>\n  git show <pseudo-ref>\n\nin normal and in conflicted case.\n\n\nI am also not sure if replacing \"context-sensitive\" git-checkout behavior\nby \"git revert-file\" (or rather \"git revert-path\", as you can use pathspec,\nc.f. \"git checkout .\"), is something to consider without rock-solid UI\ndesign and a very good name.  True, context dependent grammars are harder\nthan context-free grammars, but people do understand context, don't they?\n\nAnyway, if one does not remember \"git checkout -- <file>\", one can always\nuse obvious alternative, namely \"git show :./<file> > <file>\"...\n\n\nBUT I quite like \"git unadd\" (and/or \"git unstage\") idea.  \n\nIt is not obvious that \"git reset\" can be used for files, and it requires\nbit of analysis that it resets index from HEAD: \n1. \"git reset [<options>]\" always resets from commit (defaults to HEAD),\n2. \"git reset\" == \"git reset --mixed\" modifies current branch and index\n   (HEAD -> index -> worktree progression of --soft -> --mixed -> --hard\n   et al.),\n3. modifying branch tip doesn't make sense for checking out file, so\n4. \"git reset -- <file>\" must set index version of file from HEAD.\n\nTruth to be told I really just follow what \"git status\" tells me ;-)\n\nThough I am always wondering why there isn't \"git reset --hard <file>\"\nto mean the same as \"git checkout HEAD <file>\".\n\nSo +1 from me for \"git unadd [<commit>] [--] <path>...\" (and \"git unstage\")\nto do _exactly the same_ as \"git reset [<commit>] [--] <path>...\".\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169597","messageId":"BANLkTinoQCZhyhgw61u7c3eF4e5MEf+eFA@mail.gmail.com","threadId":"27548","inReplyTo":"201106081312.46377.jnareb@gmail.com","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-08T11:39:16Z","receivedAt":"2011-06-08T11:39:16Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n> I don't quite think that we need \"git diff NEXT WTREE\"; the short\n> and sweet \"git diff\" is short for a reason,\n\nTo be clear, I'm not advocating and have never advocated getting rid\nof zero-argument \"git diff\".  I've advocated that every (whole\nproject) diff command should be expressible by a \"git diff TREE1\nTREE2\".  I'm fine with defaults if one or zero trees are specified.\nSo \"git diff\" would default to \"git diff NEXT WTREE\".\n\n\n> It is not obvious that \"git reset\" can be used for files, and it requires\n> bit of analysis that it resets index from HEAD:\n...\n> 4. \"git reset -- <file>\" must set index version of file from HEAD.\n>\n> Truth to be told I really just follow what \"git status\" tells me ;-)\n\nI love those messages but if a user is relying on just copying a\nwarning message, then they are learning anything.  They're parroting.\nI believe a user interface should have concepts and commands that make\nsense, so that user will learn them and be able to apply them in other\nareas.\n\n> --\n> Jakub Narebski\n> Poland\n>\n"},{"id":"169601","messageId":"201106081442.37849.jnareb@gmail.com","threadId":"27548","inReplyTo":"BANLkTinoQCZhyhgw61u7c3eF4e5MEf+eFA@mail.gmail.com","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-08T12:42:37Z","receivedAt":"2011-06-08T12:42:37Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Wed, Jun 8, 2011, Michael Nahas wrote:\n> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n\n> > I don't quite think that we need \"git diff NEXT WTREE\"; the short\n> > and sweet \"git diff\" is short for a reason,\n> \n> To be clear, I'm not advocating and have never advocated getting rid\n> of zero-argument \"git diff\".  I've advocated that every (whole\n> project) diff command should be expressible by a \"git diff TREE1\n> TREE2\".  I'm fine with defaults if one or zero trees are specified.\n\nThose pseudo-almost-refs (almost-tree-ish) are to help new users, isn't it?\nBut shouldn't new user learn that he/she should use \"git diff\" to review\nhis changes, rather than use \"git diff NEXT WTREE\" to compare staged\ncontents with working area?\n\n> So \"git diff\" would default to \"git diff NEXT WTREE\".\n\nYou mean that \"git diff NEXT WTREE\" output be the same as \"git diff\",\nexcept for corner cases (merge conflict), isn't it?\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169604","messageId":"4DEF7378.20307@ira.uka.de","threadId":"27548","inReplyTo":"201106072233.28244.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Holger Hellmuth","fromEmail":"hellmuth@ira.uka.de","sentAt":"2011-06-08T13:04:56Z","receivedAt":"2011-06-08T13:04:56Z","isPatch":false,"sender":{"key":"hellmuth@ira.uka.de","avatar":null},"body":"On 07.06.2011 22:33, Jakub Narebski wrote:\n> To reiterate; perhaps it is not stated clearly in documentation:\n >\n> 1. \"git diff\" is about examining _your_ changes.  This short form is the\n>     same in every SCM.\n\nyou are right, more explicit mention in the docs would help about this.\n\nBut other SCMs don't have the additional target 'index'. Much easier to \nreason there. Also, wouldn't Joe User then conclude that 'git diff' must \nbe comparing working area against HEAD ?\n\n>     Because of explicit index (cache, staging area) one needs to know if\n>     it is working area against index, or working area against HEAD.\n>     Thinking about merge conflict case helps to remember; in such case\n>     you want your changes against partially resolved merge.\n\nThis is far from a straightforward reasoning that would pop up in \nanyones mind. In truth, I can't follow that reasoning even now. In case \nof a merge conflict the working area doesn't concern me at all, I would \nwant a diff between 'ours' and 'theirs'\n\nSince perl has been brought up as example of this DWIM philosophy: In \nperl commands have their defaults, but you always can specify exactly \nwhat you want if you are not sure or want to make it explicit. You can \nuse 'chomp' or you can use 'chomp $_'. But I can't make it explicit \nwhich two targets I want to compare with 'git diff'.\n\n>     Also advanced users can use index to hide fully cooked changes from\n>     having to browse during review.\n>\n>     Novice users which do not use index (and use \"git commit -a\") would\n>     never notice the difference, if not for the complication of newly\n>     added files: in other SCM you would see on \"<scm>  diff\" creation\n>     diff (well, there is \"git add -N\").  Same with removal if one uses\n>     \"git rm\" and not simply \"rm\".\n\n> 2. \"git diff --cached\" is about cached (staged) changes, therefore\n>     it is index against HEAD.\n\nWe use three words to talk about the index: cache, stage, index. So \napart from having an additional target for diff that target also is \ndiffused by three words. Sure, index is the real designation and cached \nand staged are used as verbs, but that is just one more confusing bit. \nAlso 'cache' in computer science is a transparent buffer to access data \nfaster (wikipedia definition). Not what I would think of the index.\n\nProbably there are good reasons to not use \"git diff --index\" and \nprobably they have been discussed a few times, but it doesn't make using \ndiff easier. But that's a side issue.\n\nIf someone sees 'git diff --cached' he might know one target, the index. \nBut how does he get the other? By reasoning that 'git diff' alone is \nalready index against working area? But for that he would have first to \nconclude that 'git diff' is not working area against HEAD (as it is in \nother SCMs), see above.\n\n> 3. \"git diff<commit>\" in general, and \"git diff HEAD\" in particular,\n>     is about your changes (worktree), compared to given commit.\n>\n> At in no place I _have_ to explain what is compared with what to explain\n> when and what for to use \"git diff\", \"git diff --cached\" and \"git diff\n> HEAD\".\n>\n\nI'm sure every part of the user interface of gimp can be rationalized in \nthe same way by someone deeply involved in the concepts and the \nstructure of gimp, but still it is perceived as difficult by nearly \neveryone else. You look at it from inside and it looks logical. Others \njust don't have all the pieces to make that reasoning really work.\n\nHolger.\n"},{"id":"169605","messageId":"201106081510.02701.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DECD406.2010009@drmicha.warpmail.net","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-08T13:10:02Z","receivedAt":"2011-06-08T13:10:02Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Mon, 6 Jun 2011, Michael J Gruber wrote:\n> Jakub Narebski venit, vidit, dixit 06.06.2011 14:19:\n>> On Mon, 6 June 2011, Michael J Gruber wrote:\n>>> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:\n>>>> Scott Chacon <schacon@gmail.com> writes:\n\n[...]\n>>> That is why the other Michael suggested \"NEXT\" as opposed to \"INDEX\":\n>>> The index has many aspects, only one of which is \"the contents of the\n>>> next commit if I would issue 'git commit' right now\". (I would even go\n>>> so far as using \"STAGE\".) Now, it's hard to argue that \"the result of a\n>>> commit\" is not tree-like, isn't it? And there's no question what \"git\n>>> show NEXT\" would do. Yes, if you repeat that command, you get a\n>>> different sha1 each time (because of the time field).\n>>>\n>>> I don't think anyone is seriously suggesting to replace the index by a\n>>> pseudo commit; but the one aspect which people use most could be well\n>>> represented like that, and this might even help emphasizing the\n>>> different aspects of the index. Give the index an identity as an\n>>> \"object\" (no, no new type, not in the object db, but as a ui object),\n>>> not something mysterious behind the scenes!\n>> \n>> So what you suggest would make\n>> \n>>   $ git diff NEXT WTREE\n>> \n>> behave differently from\n>> \n>>   $ git diff\n>> \n>> and\n>> \n>>   $ git diff HEAD NEXT\n>> \n>> behave differently from\n>> \n>>   $ git diff --cached\n>> \n>> Do you really think that it is good idea?\n> \n> I don't know where you're getting from that someone is suggesting to\n> make them different. (And even if, it's new UI, not changed.) Everyone's\n> been suggesting to make these more accessible.\n\nHere:\n\n  That is why the other Michael suggested \"NEXT\" as opposed to \"INDEX\":\n\nIt was in response to question how \"git diff NEXT WTREE\" etc. and\n\"git show NEXT\" would look like _in presence of merge conflicts_, as\ncompared to \"git diff\" etc. and \"git ls-files\" / \"git ls-files --stage\".\n\n>>> As for WTREE: git diff against work tree does not look at non-tracked\n>>> ignored files, so why should WTREE?\n>> \n>> So we tailor WTREE do diff behavior?\n> \n> There is no WTREE and nothing to tailer. We create it so that it is most\n> useful and consistent, whatever that may be.\n\nBut what if \"most useful\" contradicts \"consistent\" (and \"user friendly\")\nand vice versa?  That is the problem with designing this UI.\n\n>> Besides, isn't this exercise a bit academic?  New to git wouldn't use\n>> index, and would use 'git commit -a' and 'git diff'... and that would\n>> be enough... well, perhaps except 'git add' + 'git diff'...\n> \n> But we want them to grasp and use the git concepts! That is why some of\n> us want to make them more accessible.\n\nI don't think that making stage/index and working area look like tree-ish\n(which they ain't), or using tree-ish like keyword for some ways of \naccessing/addressing index and worktree would make them grasp git concepts.\n \nAll the corner cases of proposed UI must be addressed in detail, and\nexamined to tell if it would make git [concepts] more accessible, or if\nit would just move difficulty in other place.\n\n>>> Full disclosure: I love the index but hate the way we make it difficult\n>>> to use sometimes, and even have to lookup myself what command and option\n>>> to actually use if all I want to do is diff A against B, or take the\n>>> version of a file from A and write it to B, when A and B are a commit,\n>>> the index or the worktree (with a commit being the nonwritable, of course).\n>> \n>> Note that in case of saving to worktree you can always use\n>> \n>>   $ git show HEAD:./foo>foo\n>>   $ git show :0:./foo  >foo     # or just :./foo\n> \n> Exactly, yet another command to add to the list below, and it's not even\n> all git (because of the shell redirection).\n\nOrthogonality is good in theory, but having more than one way to do\nsomething (like Perl's TIMTOWTDI) is a good thing, especially for UI.\n \n>>> I mean, this is really crazy: We have 4 commands (\"add\", \"rm\n>>> [--cached]\", \"checkout [<commit>] --\", \"reset [<commit>] --\") which you\n>>> need to be aware of if all you want to do is moving file contents\n>>> (content at a path) between a commit, the index and the worktree! And\n>>> this is actually worse than having 6 for the 6 cases.\n> \n> Add to this craziness the fact that \"checkout -- <path>\" reads from\n> index and writes to worktree, but \"checkout <commit> -- path\" does not\n> read from commit and write to worktree - it reads from commit and writes\n> to index+worktree.\n> \n> Note that I'm not suggesting to change any of the beloved\n> reset/checkout/whatever variants.\n> \n> But the more I look at the commit - index - worktree triangle and the\n> commands we have the more I realize how messed up the ui is, simply\n> because it is determined by the underlying mechanics (e.g.: checkout\n> writes the index to the worktree, possibly after updating the index from\n> a commit) rather than by the concepts.\n\nActually it is not determined by underlying mechanics, but by requiring\nsane behavior.  Updating worktree from HEAD without updating index is\nusually something that you do not want, generating unexpected result.\n\nAlso, IMVHO the concepts are simple to understand / remember.  All\ncheckout variants check out to working area; all reset variants reset\nfrom HEAD / commit:\n\n                 checkout    reset\n                  /--^--\\   /--^--\\\n\n  HEAD              |         ||v\n                    |         ||\n  index             ||        |v\n                    ||        |\n  working area      vv        v\n\nAnd all those update intermediate stages.\n\n> And the bad thing is that even when you look at a single command like\n> reset or checkout, you can get confused easily because of the multiple\n> different functions they overload (e.g. checkout can change HEAD, the\n> index and/or the worktree), and also because of some different defaults\n> (HEAD vs. index). I think we lost consistency here because over time\n> \"useful defaults\" grew in the wild.\n> \n> That is why I'm suggesting concept based variants (move this content\n> from A to B, show me the difference between A and B).\n\nLike \"git put\" proposal by Jeff King (Peff)?\n\n  [RFC/PATCH] git put: an alternative to add/reset/checkout\n  http://thread.gmane.org/gmane.comp.version-control.git/175262\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169611","messageId":"BANLkTik_yw1awh6wM6hmUUxbgW5iVuOzCQ@mail.gmail.com","threadId":"27548","inReplyTo":"201106081442.37849.jnareb@gmail.com","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-08T14:15:45Z","receivedAt":"2011-06-08T14:15:45Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"On Wed, Jun 8, 2011 at 8:42 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n> On Wed, Jun 8, 2011, Michael Nahas wrote:\n>> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n>\n>> > I don't quite think that we need \"git diff NEXT WTREE\"; the short\n>> > and sweet \"git diff\" is short for a reason,\n>>\n>> To be clear, I'm not advocating and have never advocated getting rid\n>> of zero-argument \"git diff\".  I've advocated that every (whole\n>> project) diff command should be expressible by a \"git diff TREE1\n>> TREE2\".  I'm fine with defaults if one or zero trees are specified.\n>\n> Those pseudo-almost-refs (almost-tree-ish) are to help new users, isn't it?\n> But shouldn't new user learn that he/she should use \"git diff\" to review\n> his changes, rather than use \"git diff NEXT WTREE\" to compare staged\n> contents with working area?\n\nI think we need a new term that refers to NEXT, WTREE, and commits.\nIt could be \"snapshots\", but that is closely associated with commit\nand has a feeling of being read-only.  Maybe \"root-tree\"?\n\nI think most users - new or ortherwise - should use \"git diff\".  It's\nthe shorter command.  I think a man page saying \"git diff\" is\nequivalent to \"git diff NEXT WTREE\" is (1) very specific as to what\nthe command does and (2) illuminates new users to the concepts, so\nthat when they see \"git diff HEAD NEXT\" or \"git diff HEAD WTREE\", they\ncan imagine what is going on.\n\n>> So \"git diff\" would default to \"git diff NEXT WTREE\".\n>\n> You mean that \"git diff NEXT WTREE\" output be the same as \"git diff\",\n> except for corner cases (merge conflict), isn't it?\n\nI've addressed the conflict case already.  NEXT should contain HEAD\nplus all the resolved files.\n\nAs far as I can tell, with that definition, \"git diff NEXT WTREE\" \"git\ndiff HEAD NEXT\" and \"git diff HEAD WTREE\" would produce the same\nresults as the current implementation of \"git diff\", \"git diff\n--cached\" and \"git diff HEAD\" --- even in a conflicted state.\n\nI've only been able to check that by experimentation; I asked if\nsomeone who knew the code could confirm it.\n\n>\n> --\n> Jakub Narebski\n> Poland\n>\n"},{"id":"169617","messageId":"20110608150537.GC7805@sigill.intra.peff.net","threadId":"27548","inReplyTo":"BANLkTinoQCZhyhgw61u7c3eF4e5MEf+eFA@mail.gmail.com","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-08T15:05:37Z","receivedAt":"2011-06-08T15:05:37Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jun 08, 2011 at 07:39:16AM -0400, Michael Nahas wrote:\n\n> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n> > I don't quite think that we need \"git diff NEXT WTREE\"; the short\n> > and sweet \"git diff\" is short for a reason,\n> \n> To be clear, I'm not advocating and have never advocated getting rid\n> of zero-argument \"git diff\".  I've advocated that every (whole\n> project) diff command should be expressible by a \"git diff TREE1\n> TREE2\".  I'm fine with defaults if one or zero trees are specified.\n\nI agree with this, but...\n\n> So \"git diff\" would default to \"git diff NEXT WTREE\".\n\nIsn't this going to be behavior change, since your NEXT is not quite the\nsame as the index? How do I now get an n-way combined diff of the\nunmerged files in the index?\n\n-Peff\n"},{"id":"169680","messageId":"201106082056.38774.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DEF7378.20307@ira.uka.de","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-08T18:56:37Z","receivedAt":"2011-06-08T18:56:37Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Wed, 8 Jun 2011, Holger Hellmuth wrote:\n> On 07.06.2011 22:33, Jakub Narebski wrote:\n\n> > To reiterate; perhaps it is not stated clearly in documentation:\n> >\n> > 1. \"git diff\" is about examining _your_ changes.  This short form is the\n> >     same in every SCM.\n> \n> you are right, more explicit mention in the docs would help about this.\n> \n> But other SCMs don't have the additional target 'index'. Much easier to \n> reason there. Also, wouldn't Joe User then conclude that 'git diff' must \n> be comparing working area against HEAD ?\n\nWell, actually it should be that \"git diff\" is about examining _your_\n*remaining* changes.\n\nIf Joe User doesn't use index, then \"git diff\" and \"git diff HEAD\" shows\nthe same contents (modulo \"git add\" / \"git add -N\" trouble).  So Joe\ndoesn't need to worry if it is worktree versus index, or versus HEAD;\nit is enought to know when it is used.\n \n> >     Because of explicit index (cache, staging area) one needs to know if\n> >     it is working area against index, or working area against HEAD.\n> >     Thinking about merge conflict case helps to remember; in such case\n> >     you want your changes against partially resolved merge.\n> \n> This is far from a straightforward reasoning that would pop up in \n> anyones mind. In truth, I can't follow that reasoning even now. In case \n> of a merge conflict the working area doesn't concern me at all, I would \n> want a diff between 'ours' and 'theirs'.\n\nWhat you want is irrelevant ;-)  Because in the case of merge conflict\nentries in index is populated automatically, *your* changes are changes\nagains index.  So there.\n\nAnd what \"git diff\" would show in that case is --cc diff of file with\nmerge markers against stages '1' and '2' in index, which is quite useful.\nWhich is 3-way diff between 'ours' and 'theirs'.\n\n\nNb. I don't know how to get _remaining_ diff between 'ours' and 'theirs',\nbut the NEXT proposal doesn't address it either...\n\n> \n> Since perl has been brought up as example of this DWIM philosophy: In \n> perl commands have their defaults, but you always can specify exactly \n> what you want if you are not sure or want to make it explicit. You can \n> use 'chomp' or you can use 'chomp $_'.\n\nBy TIMTOWTDI I rather meant here that you can write\n\n  if (...) {\n     ...\n  }\n\nor\n\n  ... if (...);\n\nor\n\n  ... or ...;\n\n\nI wasn't saying anything about DWIM-mery, just TIMTOWTDI and context...\n\n> But I can't make it explicit which two targets I want to compare with\n> 'git diff'. \n\nFor me it looks XY problem; instead of wanting to compare two explicit\ntargets, you should specify what you want to see ;-).\n \n> >     Also advanced users can use index to hide fully cooked changes from\n> >     having to browse during review.\n\nWhat is where \"remaining\" in 'examining your remaining changes' come\nfrom.  Advanced users can \"git add <file>\" (or \"git add -p\" even) when\nsome change is fully cooked and ready to be included, to reduce size of\ndiff when reviewing remaining changes.\n\n> >     Novice users which do not use index (and use \"git commit -a\") would\n> >     never notice the difference, if not for the complication of newly\n> >     added files: in other SCM you would see on \"<scm>  diff\" creation\n> >     diff (well, there is \"git add -N\").  Same with removal if one uses\n> >     \"git rm\" and not simply \"rm\".\n> \n> > 2. \"git diff --cached\" is about cached (staged) changes, therefore\n> >     it is index against HEAD.\n> \n> We use three words to talk about the index: cache, stage, index. So \n> apart from having an additional target for diff that target also is \n> diffused by three words. Sure, index is the real designation and cached \n> and staged are used as verbs, but that is just one more confusing bit. \n> Also 'cache' in computer science is a transparent buffer to access data \n> faster (wikipedia definition). Not what I would think of the index.\n\nAt the very beginning it was named 'dircache'... ;-)))\n\nThere was an attempt to introduce 'to stage', 'staged contents' and\n'staging area', and you can use \"git diff --staged\" instead... but\nsupport might be incomplete.\n\n\nThe area is called 'the index', but you examine 'cached' contents,\nnot 'indexed' contents.  One of resons for the index is making git\nfaster, so it is the cache as well (keeps e.g. cached stats info to\nmake it possible for git to swiftly find which files changed).\n \n> Probably there are good reasons to not use \"git diff --index\" and \n> probably they have been discussed a few times, but it doesn't make using \n> diff easier. But that's a side issue.\n\nThe issue is with \"git apply\" and \"git stash\", where --index means\n'use staging area in addition to working directory' and not like\n--cached for \"git apply\" 'use staging area _instead_ of working\ndirectory\" (though _instead_ is not very precise here).\n \n> If someone sees 'git diff --cached' he might know one target, the index. \n> But how does he get the other? By reasoning that 'git diff' alone is \n> already index against working area? But for that he would have first to \n> conclude that 'git diff' is not working area against HEAD (as it is in \n> other SCMs), see above.\n\n\"git diff --cached\" / \"git diff --staged\" is about 'what changes are\nin index' (are 'staged'), i.e. what you \"git add\"-ed / \"git stage\"-d.\nBecause changes always go working directory -> staging area -> repository\n(commit) it is abvious that those are \"staging area -> repository\"\nchanges.\n \n> > 3. \"git diff<commit>\" in general, and \"git diff HEAD\" in particular,\n> >     is about your changes (worktree), compared to given commit.\n> >\n> > At in no place I _have_ to explain what is compared with what to explain\n> > when and what for to use \"git diff\", \"git diff --cached\" and \"git diff\n> > HEAD\".\n> \n> I'm sure every part of the user interface of gimp can be rationalized in \n> the same way by someone deeply involved in the concepts and the \n> structure of gimp, but still it is perceived as difficult by nearly \n> everyone else. You look at it from inside and it looks logical. Others \n> just don't have all the pieces to make that reasoning really work.\n\nWhat I wanted to say here that instead of teaching / trying to teach\nnew people something like the following:\n\n  There is working area, index and current commit (HEAD).  To compare\n  workdir with index use this, to compare index with HEAD use that, to\n  compare workdir with HEAD use this one.\n\nwe better do explaining higher level concepts\n\n  To examine your remaining changes, i.e. what you can \"git stage\",\n  use \"git diff\".  To examine staged changes, i.e. what you \n  \"git stage\"-d, use \"git diff --staged\"; that is what \"git commit\"\n  will create.  To compare working version with given older version,\n  use \"git diff <revision>\", in particular to compare with last version\n  use \"git diff HEAD\"; that is what \"git commit --all\" would create.\n\n\nThe \"git diff NEXT WTREE\" looks like training wheels to me.  And like\ntraining wheels they could become obstacles and not help to learning\ngit.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169681","messageId":"BANLkTinibF0xmibeuJ6f9FUjaMmxavMJig@mail.gmail.com","threadId":"27548","inReplyTo":"20110608150537.GC7805@sigill.intra.peff.net","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-08T18:57:09Z","receivedAt":"2011-06-08T18:57:09Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"On Wed, Jun 8, 2011 at 11:05 AM, Jeff King <peff@peff.net> wrote:\n> On Wed, Jun 08, 2011 at 07:39:16AM -0400, Michael Nahas wrote:\n>\n>> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n>> > I don't quite think that we need \"git diff NEXT WTREE\"; the short\n>> > and sweet \"git diff\" is short for a reason,\n>>\n>> To be clear, I'm not advocating and have never advocated getting rid\n>> of zero-argument \"git diff\".  I've advocated that every (whole\n>> project) diff command should be expressible by a \"git diff TREE1\n>> TREE2\".  I'm fine with defaults if one or zero trees are specified.\n>\n> I agree with this, but...\n>\n>> So \"git diff\" would default to \"git diff NEXT WTREE\".\n>\n> Isn't this going to be behavior change, since your NEXT is not quite the\n> same as the index? How do I now get an n-way combined diff of the\n> unmerged files in the index?\n>\n> -Peff\n\nThe index is a file in .git/ that serves many purposes.  NEXT is an\nimage of the whole project.  NEXT can be computed from the index and\nHEAD.\n\nDuring a conflicted merge, stage 0 of the index holds the resolved\nfiles.  WTREE holds all merge files: the resolved and the unresolved\n(which have <<<< ==== >>>> blocks in them).  I propose that during a\nconflicted merge, that NEXT be computed as HEAD plus the resolved\nfiles, that is, the files in stage 0 of the index.\n\n\"git diff HEAD NEXT\" would print the resolved changes.\n\"git diff NEXT WTREE\" would print the unresolved changes\n\"git diff HEAD WTREE\" would print all changes.\n\nI believe that is the same behaviour as \"git diff\", \"git diff\n--cached\" and \"git diff HEAD\" during a conflicted merge.\n\nI do not know how \"n-way\" merge works.  I saw somewhere that indicated\nthat it was a series of N-1 two-way merges.\n\n\nMike\n"},{"id":"169718","messageId":"20110609004347.GC19715@sigill.intra.peff.net","threadId":"27548","inReplyTo":"BANLkTinibF0xmibeuJ6f9FUjaMmxavMJig@mail.gmail.com","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-09T00:43:47Z","receivedAt":"2011-06-09T00:43:47Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jun 08, 2011 at 02:57:09PM -0400, Michael Nahas wrote:\n\n> > Isn't this going to be behavior change, since your NEXT is not quite the\n> > same as the index? How do I now get an n-way combined diff of the\n> > unmerged files in the index?\n> \n> The index is a file in .git/ that serves many purposes.  NEXT is an\n> image of the whole project.  NEXT can be computed from the index and\n> HEAD.\n> \n> During a conflicted merge, stage 0 of the index holds the resolved\n> files.  WTREE holds all merge files: the resolved and the unresolved\n> (which have <<<< ==== >>>> blocks in them).  I propose that during a\n> conflicted merge, that NEXT be computed as HEAD plus the resolved\n> files, that is, the files in stage 0 of the index.\n\nOK. So NEXT actually has less information than the whole index, because\nit doesn't contain information on what was on either side of the merge\noriginally (or in the merge base).\n\n> \"git diff HEAD NEXT\" would print the resolved changes.\n> \"git diff NEXT WTREE\" would print the unresolved changes\n> \"git diff HEAD WTREE\" would print all changes.\n> \n> I believe that is the same behaviour as \"git diff\", \"git diff\n> --cached\" and \"git diff HEAD\" during a conflicted merge.\n\nI assume you don't mean respectively here, but rather:\n\n  git diff          => git diff NEXT WTREE\n  git diff --cached => git diff HEAD NEXT\n  git diff HEAD     => git diff HEAD WTREE\n\nBut even still, I don't think \"git diff\" is the same. Try this:\n\n  git init repo && cd repo\n  echo one >file && git add file && git commit -m one &&\n  echo two >file && git add file && git commit -m two &&\n  git checkout -b other HEAD^ &&\n  echo three >file && git add file && git commit -m three &&\n  ! git merge master &&\n  git diff\n\nI get:\n\n  diff --cc file\n  index 2bdf67a,f719efd..0000000\n  --- a/file\n  +++ b/file\n  @@@ -1,1 -1,1 +1,5 @@@\n  ++<<<<<<< HEAD\n   +three\n  ++=======\n  + two\n  ++>>>>>>> master\n\nNote that this is _not_ a diff between NEXT and the working tree.  It is a\n3-way \"combined\" diff of what's in the working tree compared to each side of\nthe merge.\n\nIf NEXT is a tree that contains HEAD plus stage 0 files, then we would\nsee a 2-way diff of the HEAD version of \"file\" and the working tree\nversion. I.e., the same as \"git diff HEAD -- file\":\n\n  diff --git a/file b/file\n  index 2bdf67a..087e97e 100644\n  --- a/file\n  +++ b/file\n  @@ -1 +1,5 @@\n  +<<<<<<< HEAD\n   three\n  +=======\n  +two\n  +>>>>>>> master\n\nwhich looks similar, because we haven't started resolving anything yet.\nBut try resolving it like this:\n\n  cat >file <<'EOF'\n  three\n  and\n  two\n  EOF\n\nNow try \"git diff\" again. You should get:\n\n  diff --cc file\n  index 2bdf67a,f719efd..0000000\n  --- a/file\n  +++ b/file\n  @@@ -1,1 -1,1 +1,3 @@@\n   +three\n  ++and\n  + two\n\nThis shows us that \"three\" came from one side of the merge, \"two\" from\nthe other, and that \"and\" was found in neither side.\n\nCompare to the 2-way that shows:\n\n  diff --git a/file b/file\n  index 2bdf67a..1ecff7e 100644\n  --- a/file\n  +++ b/file\n  @@ -1 +1,3 @@\n   three\n  +and\n  +two\n\nThere's nothing to distinguish added code pulled from the other side of\nthe merge versus changes that were made as part of the resolution.\n\nI think this is what Junio was talking about when he said that the index\nis more than a tree. There may be times when you want to treat the items\nin stage 0 as a tree, but diffing against the index is more than just\ndiffing against that tree.\n\n> I do not know how \"n-way\" merge works.  I saw somewhere that indicated\n> that it was a series of N-1 two-way merges.\n\nGit history can represent a merge of any number of branches (an \"octopus\nmerge\"), because the commits store only the final state and a list of\nparent commits. The combined diff format is capable of handling an\narbitrary number of parents.\n\nI should have just said \"3-way\", though, because it's not relevant here.\nThe index only has 2 stage bits, so we can only represent four stages\n(\"resolved\", \"base\", \"ours\", and \"theirs\"). So you can't represent an\nn-way merge in the index.\n\nSo \"git merge\" just punts on an octopus merge if there are actual merge\nconflicts that would need to go in the index. So in practice, people\njust tend to do N-1 pair-wise merges.\n\nYou can see some example octopus merges (and their combined diff) if you\nhave a recent git (that supports --min-parents) with:\n\n  git log --min-parents=3 -p --cc\n\nin both git.git and linux-2.6.git.\n\n-Peff\n"},{"id":"169722","messageId":"BANLkTikamzsiSJqkRjA7nDjRoyEbd32rvw@mail.gmail.com","threadId":"27548","inReplyTo":"20110609004347.GC19715@sigill.intra.peff.net","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-09T01:56:08Z","receivedAt":"2011-06-09T01:56:08Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"Hi Peff,\n\nFirst, thanks for correcting my diff-without-NEXT-and-WTREE to\ndiff-with-NEXT-and-WTREE pairing.\n\nSecond, I agree that the index is more than just NEXT.  There were\ngood reasons behind calling it \"NEXT\" and not \"INDEX\".\n\nThird, I didn't know for sure that \"git diff\" during a merge conflict\nwould produce a three-way-diff result, but I suspected it would.  (You\nreally didn't have to produce all that code - I would have accepted\nyour word as an expert.  But thanks!)  So, yes, the two-way merge\nresult of \"git diff NEXT WTREE\" would be different.\n\nI could argue that git should allow a 4-way diff where \"git diff NEXT\nWTREE OURS THEIR\" prints all the unresolved changes as coming from\nOURS or THEIR or neither.  But I think that's silly.\n\nI will say that \"git diff NEXT WTREE\" will tell you what's left\nunresolved and most of it is in <<<<====>>>>> blocks that tell you\nwhether it came from OURS or THEIRS.  If the user has any discipline,\nthey won't introduce unnecessary changes that were not necessary for\nthe merge.  If they don't have discipline, we really can't help them.\n\nI'm not saying there is no use for a 3-way merge.  In fact, I'd guess\nit's a requirement so that Alice can check Bob's merge before Bob\ncommits.  But I'm fine with making it \"git diff --3-way\" or the silly\n\"git diff NEXT WTREE OURS THEIRS\" because I think its \"git diff NEXT\nWTREE\" will be good enough 99% of the time.\n\n\n\nOn Wed, Jun 8, 2011 at 8:43 PM, Jeff King <peff@peff.net> wrote:\n> On Wed, Jun 08, 2011 at 02:57:09PM -0400, Michael Nahas wrote:\n>\n>> > Isn't this going to be behavior change, since your NEXT is not quite the\n>> > same as the index? How do I now get an n-way combined diff of the\n>> > unmerged files in the index?\n>>\n>> The index is a file in .git/ that serves many purposes.  NEXT is an\n>> image of the whole project.  NEXT can be computed from the index and\n>> HEAD.\n>>\n>> During a conflicted merge, stage 0 of the index holds the resolved\n>> files.  WTREE holds all merge files: the resolved and the unresolved\n>> (which have <<<< ==== >>>> blocks in them).  I propose that during a\n>> conflicted merge, that NEXT be computed as HEAD plus the resolved\n>> files, that is, the files in stage 0 of the index.\n>\n> OK. So NEXT actually has less information than the whole index, because\n> it doesn't contain information on what was on either side of the merge\n> originally (or in the merge base).\n>\n>> \"git diff HEAD NEXT\" would print the resolved changes.\n>> \"git diff NEXT WTREE\" would print the unresolved changes\n>> \"git diff HEAD WTREE\" would print all changes.\n>>\n>> I believe that is the same behaviour as \"git diff\", \"git diff\n>> --cached\" and \"git diff HEAD\" during a conflicted merge.\n>\n> I assume you don't mean respectively here, but rather:\n>\n>  git diff          => git diff NEXT WTREE\n>  git diff --cached => git diff HEAD NEXT\n>  git diff HEAD     => git diff HEAD WTREE\n>\n> But even still, I don't think \"git diff\" is the same. Try this:\n>\n>  git init repo && cd repo\n>  echo one >file && git add file && git commit -m one &&\n>  echo two >file && git add file && git commit -m two &&\n>  git checkout -b other HEAD^ &&\n>  echo three >file && git add file && git commit -m three &&\n>  ! git merge master &&\n>  git diff\n>\n> I get:\n>\n>  diff --cc file\n>  index 2bdf67a,f719efd..0000000\n>  --- a/file\n>  +++ b/file\n>  @@@ -1,1 -1,1 +1,5 @@@\n>  ++<<<<<<< HEAD\n>   +three\n>  ++=======\n>  + two\n>  ++>>>>>>> master\n>\n> Note that this is _not_ a diff between NEXT and the working tree.  It is a\n> 3-way \"combined\" diff of what's in the working tree compared to each side of\n> the merge.\n>\n> If NEXT is a tree that contains HEAD plus stage 0 files, then we would\n> see a 2-way diff of the HEAD version of \"file\" and the working tree\n> version. I.e., the same as \"git diff HEAD -- file\":\n>\n>  diff --git a/file b/file\n>  index 2bdf67a..087e97e 100644\n>  --- a/file\n>  +++ b/file\n>  @@ -1 +1,5 @@\n>  +<<<<<<< HEAD\n>   three\n>  +=======\n>  +two\n>  +>>>>>>> master\n>\n> which looks similar, because we haven't started resolving anything yet.\n> But try resolving it like this:\n>\n>  cat >file <<'EOF'\n>  three\n>  and\n>  two\n>  EOF\n>\n> Now try \"git diff\" again. You should get:\n>\n>  diff --cc file\n>  index 2bdf67a,f719efd..0000000\n>  --- a/file\n>  +++ b/file\n>  @@@ -1,1 -1,1 +1,3 @@@\n>   +three\n>  ++and\n>  + two\n>\n> This shows us that \"three\" came from one side of the merge, \"two\" from\n> the other, and that \"and\" was found in neither side.\n>\n> Compare to the 2-way that shows:\n>\n>  diff --git a/file b/file\n>  index 2bdf67a..1ecff7e 100644\n>  --- a/file\n>  +++ b/file\n>  @@ -1 +1,3 @@\n>   three\n>  +and\n>  +two\n>\n> There's nothing to distinguish added code pulled from the other side of\n> the merge versus changes that were made as part of the resolution.\n>\n> I think this is what Junio was talking about when he said that the index\n> is more than a tree. There may be times when you want to treat the items\n> in stage 0 as a tree, but diffing against the index is more than just\n> diffing against that tree.\n>\n>> I do not know how \"n-way\" merge works.  I saw somewhere that indicated\n>> that it was a series of N-1 two-way merges.\n>\n> Git history can represent a merge of any number of branches (an \"octopus\n> merge\"), because the commits store only the final state and a list of\n> parent commits. The combined diff format is capable of handling an\n> arbitrary number of parents.\n>\n> I should have just said \"3-way\", though, because it's not relevant here.\n> The index only has 2 stage bits, so we can only represent four stages\n> (\"resolved\", \"base\", \"ours\", and \"theirs\"). So you can't represent an\n> n-way merge in the index.\n>\n> So \"git merge\" just punts on an octopus merge if there are actual merge\n> conflicts that would need to go in the index. So in practice, people\n> just tend to do N-1 pair-wise merges.\n>\n> You can see some example octopus merges (and their combined diff) if you\n> have a recent git (that supports --min-parents) with:\n>\n>  git log --min-parents=3 -p --cc\n>\n> in both git.git and linux-2.6.git.\n>\n> -Peff\n>\n"},{"id":"169746","messageId":"4DF08D30.7070603@alum.mit.edu","threadId":"27548","inReplyTo":"7vwrgza3i2.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-06-09T09:06:56Z","receivedAt":"2011-06-09T09:06:56Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 06/06/2011 08:16 AM, Junio C Hamano wrote:\n> Scott Chacon <schacon@gmail.com> writes:\n>> For example, implementation details aside, I think having something\n>> like WTREE and NEXT available would help users understand that there\n>> are these 3 trees that are important and useful in Git and re-inforce\n>> a very non-SVN style workflow in that manner.\n> \n> That's a funny thing to say. Working tree may almost always (to put it\n> another way, \"you could make it to\") act like a tree, but the index does\n> not act like a tree at all in more important situations.\n\nMy naive understanding is that in the case of a merge commit, the index\ncontains information equivalent to *multiple* trees:\n\nNEXT -- HEAD plus the files that have been resolved\nBASE -- the contents of the common ancestor\nOURS -- equivalent to the tree from HEAD\nTHEIRS -- equivalent to the tree from MERGE_HEAD\n\nIf my understanding is correct, then it would be logical to allow *any*\nof these pseudo-trees to participate in a \"git diff\" during a conflicted\nmerge.\n\nIf I'm incorrect, then I expect a learning-experience-by-flame :-)\n\nFWIW, when I was learning git, I struggled with exactly the problems\nthat Michael is trying to address.  My most frustrating moments always\ninvolved trying to get my working tree and index from some existing\nstate to some desired state, because operations that seemed (in my\nmental model) to be similar typically required using entirely different\ngit commands and/or command options.  Having a uniform nomenclature for\nthese concepts would be a big improvement (if the resulting abstraction\ndoes not leak too badly).  I also think that the proposal for \"git put\"\nwould be a great help and would work nicely with the proposed changes to\n\"git diff\".\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"169750","messageId":"201106091148.35114.jnareb@gmail.com","threadId":"27548","inReplyTo":"BANLkTinibF0xmibeuJ6f9FUjaMmxavMJig@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-09T09:48:34Z","receivedAt":"2011-06-09T09:48:34Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Wed, 8 June 2011, Michael Nahas wrote:\n> On Wed, Jun 8, 2011 at 11:05 AM, Jeff King <peff@peff.net> wrote:\n>> On Wed, Jun 08, 2011 at 07:39:16AM -0400, Michael Nahas wrote:\n>>\n>>> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n>>>> I don't quite think that we need \"git diff NEXT WTREE\"; the short\n>>>> and sweet \"git diff\" is short for a reason,\n>>>\n>>> To be clear, I'm not advocating and have never advocated getting rid\n>>> of zero-argument \"git diff\".  I've advocated that every (whole\n>>> project) diff command should be expressible by a \"git diff TREE1\n>>> TREE2\".  I'm fine with defaults if one or zero trees are specified.\n>>\n>> I agree with this, but...\n>>\n>>> So \"git diff\" would default to \"git diff NEXT WTREE\".\n>>\n>> Isn't this going to be behavior change, since your NEXT is not quite the\n>> same as the index? How do I now get an n-way combined diff of the\n>> unmerged files in the index?\n> \n> The index is a file in .git/ that serves many purposes.  NEXT is an\n> image of the whole project.  NEXT can be computed from the index and\n> HEAD.\n> \n> During a conflicted merge, stage 0 of the index holds the resolved\n> files.\n\nIt is simply not true.  During a conflicted merge, for conflicted files\nthere is _no_ stage 0!!!  Conflicted files have stage 1 == base, 2 == ours\nand 3 == theirs, where those stages have all conflicts that can be resolved\nautomatically resolved, and places where there is conflict replaced by\nmerge-base ('base'), current branch into which we merge ('ours') and\nmerged branch ('theirs').\n\n> WTREE holds all merge files: the resolved and the unresolved \n> (which have <<<< ==== >>>> blocks in them).\n\nWorktree version has files with conflict merge markers added in place\nwhere there is conflict.\n\n\n> I propose that during a \n> conflicted merge, that NEXT be computed as HEAD plus the resolved \n> files, that is, the files in stage 0 of the index.\n\nWhy _HEAD_?\n \n> \"git diff HEAD NEXT\" would print the resolved changes.\n> \"git diff NEXT WTREE\" would print the unresolved changes\n> \"git diff HEAD WTREE\" would print all changes.\n> \n> I believe that is the same behaviour as \"git diff\", \"git diff\n> --cached\" and \"git diff HEAD\" during a conflicted merge.\n\n\"git diff NEXT WTREE\" would not behave (with your proposal) like\n\"git diff\", but like \"git diff --ours\".\n\n\"git diff HEAD NEXT\" would not behave like \"git diff --cached\"\n(which shows only '*Unmerged path foo').\n\n\"git diff HEAD WTREE\" would be the same as \"git diff HEAD\" (just\nlonger to write), only because it doesn't involve index at all.\n \n\n> I do not know how \"n-way\" merge works.  I saw somewhere that indicated\n> that it was a series of N-1 two-way merges.\n\nWhere this \"n-way merge\" came from?  Peff wrote about \"n-way combined\ndiff\", which is something different.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169751","messageId":"4DF09A3D.8040908@op5.se","threadId":"27548","inReplyTo":"4DF08D30.7070603@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2011-06-09T10:02:37Z","receivedAt":"2011-06-09T10:02:37Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"On 06/09/2011 11:06 AM, Michael Haggerty wrote:\n> On 06/06/2011 08:16 AM, Junio C Hamano wrote:\n>> Scott Chacon<schacon@gmail.com>  writes:\n>>> For example, implementation details aside, I think having something\n>>> like WTREE and NEXT available would help users understand that there\n>>> are these 3 trees that are important and useful in Git and re-inforce\n>>> a very non-SVN style workflow in that manner.\n>>\n>> That's a funny thing to say. Working tree may almost always (to put it\n>> another way, \"you could make it to\") act like a tree, but the index does\n>> not act like a tree at all in more important situations.\n> \n> My naive understanding is that in the case of a merge commit, the index\n> contains information equivalent to *multiple* trees:\n> \n> NEXT -- HEAD plus the files that have been resolved\n> BASE -- the contents of the common ancestor\n> OURS -- equivalent to the tree from HEAD\n> THEIRS -- equivalent to the tree from MERGE_HEAD\n> \n\nExcept there might be any number of THEIRS in the case of an octopus\nmerge. The most common case is just one though.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n\nConsidering the successes of the wars on alcohol, poverty, drugs and\nterror, I think we should give some serious thought to declaring war\non peace.\n"},{"id":"169755","messageId":"BANLkTimir5nQYJk+GuNQOzmTWMEXb2kWqQ@mail.gmail.com","threadId":"27548","inReplyTo":"201106091148.35114.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-09T11:44:18Z","receivedAt":"2011-06-09T11:44:18Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"On Thu, Jun 9, 2011 at 5:48 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n> On Wed, 8 June 2011, Michael Nahas wrote:\n>> On Wed, Jun 8, 2011 at 11:05 AM, Jeff King <peff@peff.net> wrote:\n>>> On Wed, Jun 08, 2011 at 07:39:16AM -0400, Michael Nahas wrote:\n>>>\n>>>> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n>>>>> I don't quite think that we need \"git diff NEXT WTREE\"; the short\n>>>>> and sweet \"git diff\" is short for a reason,\n>>>>\n>>>> To be clear, I'm not advocating and have never advocated getting rid\n>>>> of zero-argument \"git diff\".  I've advocated that every (whole\n>>>> project) diff command should be expressible by a \"git diff TREE1\n>>>> TREE2\".  I'm fine with defaults if one or zero trees are specified.\n>>>\n>>> I agree with this, but...\n>>>\n>>>> So \"git diff\" would default to \"git diff NEXT WTREE\".\n>>>\n>>> Isn't this going to be behavior change, since your NEXT is not quite the\n>>> same as the index? How do I now get an n-way combined diff of the\n>>> unmerged files in the index?\n>>\n>> The index is a file in .git/ that serves many purposes.  NEXT is an\n>> image of the whole project.  NEXT can be computed from the index and\n>> HEAD.\n>>\n>> During a conflicted merge, stage 0 of the index holds the resolved\n>> files.\n>\n> It is simply not true.  During a conflicted merge, for conflicted files\n> there is _no_ stage 0!!!  Conflicted files have stage 1 == base, 2 == ours\n> and 3 == theirs, where those stages have all conflicts that can be resolved\n> automatically resolved, and places where there is conflict replaced by\n> merge-base ('base'), current branch into which we merge ('ours') and\n> merged branch ('theirs').\n\n\"resolved files\" means \"NOT conflicted files\".  The merge conflicts if\nany one file conflicts, but there may be other files that resolve\nimmediately.  And any conflicted files can be resolved by the user\nrunning \"git add\" or \"git rm\"\n\nIf a file is resolved - either immediately or by user action - it\nexists only in stage 0.\n\n>> WTREE holds all merge files: the resolved and the unresolved\n>> (which have <<<< ==== >>>> blocks in them).\n>\n> Worktree version has files with conflict merge markers added in place\n> where there is conflict.\n\nI assumed most people knew what I meant by <<<<====>>>> blocks.  But,\nyes, I meant that the working tree has both versions present at\nlocations of conflicts.\n\n>> I propose that during a\n>> conflicted merge, that NEXT be computed as HEAD plus the resolved\n>> files, that is, the files in stage 0 of the index.\n>\n> Why _HEAD_?\n\nBecause we merged changed from another branch into HEAD.\nOr we pull changes from a remote branch into HEAD.\n\nWhen a commit is written, it will be part of the branch referenced by HEAD.\n\n>> \"git diff HEAD NEXT\" would print the resolved changes.\n>> \"git diff NEXT WTREE\" would print the unresolved changes\n>> \"git diff HEAD WTREE\" would print all changes.\n>>\n>> I believe that is the same behaviour as \"git diff\", \"git diff\n>> --cached\" and \"git diff HEAD\" during a conflicted merge.\n>\n> \"git diff NEXT WTREE\" would not behave (with your proposal) like\n> \"git diff\", but like \"git diff --ours\".\n\nOURS and HEAD are the same thing, so I doubt a command that does not\ninvolve \"HEAD\" would behave like \"--ours\"\n\n> \"git diff HEAD NEXT\" would not behave like \"git diff --cached\"\n> (which shows only '*Unmerged path foo').\n>\n> \"git diff HEAD WTREE\" would be the same as \"git diff HEAD\" (just\n> longer to write), only because it doesn't involve index at all.\n\nI refer you to any of my previous emails to which I kindly replied.\nYES, \"git diff HEAD\" and \"git diff HEAD WTREE\" would be equivalent.\nI, myself, would probably use \"git diff HEAD\" most of the time.\nNonetheless, saying \"git diff\" ALWAYS takes two arguments and saying\nthat if an argument is unspecified that there is a default is much\nclearer and more regular interface than special casing everything and\nusing command-line options to say what you want, which is what we have\nnow.\n\n\n>> I do not know how \"n-way\" merge works.  I saw somewhere that indicated\n>> that it was a series of N-1 two-way merges.\n>\n> Where this \"n-way merge\" came from?  Peff wrote about \"n-way combined\n> diff\", which is something different.\n\nN-way merge exists.  It would be bad to say that I was answering a\nquestion about conflicted merges if I didn't produce an answer for\nN-way merges.  Unfortunately, I don't have enough information about\nN-way merges to answer the question so I decided it was best to\nacknowledge my ignorance and that I was giving an incomplete answer.\n\n\n\n> --\n> Jakub Narebski\n> Poland\n>\n"},{"id":"169756","messageId":"4DF0B4B2.7080007@ira.uka.de","threadId":"27548","inReplyTo":"201106082056.38774.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Holger Hellmuth","fromEmail":"hellmuth@ira.uka.de","sentAt":"2011-06-09T11:55:30Z","receivedAt":"2011-06-09T11:55:30Z","isPatch":false,"sender":{"key":"hellmuth@ira.uka.de","avatar":null},"body":"On 08.06.2011 20:56, Jakub Narebski wrote:\n[...]\n>>>      Because of explicit index (cache, staging area) one needs to know if\n>>>      it is working area against index, or working area against HEAD.\n>>>      Thinking about merge conflict case helps to remember; in such case\n>>>      you want your changes against partially resolved merge.\n          --------\n>>\n>> This is far from a straightforward reasoning that would pop up in\n>> anyones mind. In truth, I can't follow that reasoning even now. In case\n>> of a merge conflict the working area doesn't concern me at all, I would\n>> want a diff between 'ours' and 'theirs'.\n>\n> What you want is irrelevant ;-)\n\nNo, because you used my wants in your reasoning above. Makes them highly \nrelevant ;-)\n\n> Because in the case of merge conflict\n> entries in index is populated automatically, *your* changes are changes\n> agains index.  So there.\n>\n> And what \"git diff\" would show in that case is --cc diff of file with\n> merge markers against stages '1' and '2' in index, which is quite useful.\n> Which is 3-way diff between 'ours' and 'theirs'.\n\nAh okay. This detail about the merge process never really registered \nwith me. Which shows that your logic deduction what 'git diff' does is \noften not possible for the casual user\n\n[...]\n>> But I can't make it explicit which two targets I want to compare with\n>> 'git diff'.\n>\n> For me it looks XY problem; instead of wanting to compare two explicit\n> targets, you should specify what you want to see ;-).\n\nThen don't call the command 'diff' (... I proclaim in the knowledge that \nthat isn't possible). 'diff' is the short form of 'difference' which \nmeans literally a comparison between *two* things. If someone wants to \nsee something he would pick the words 'show' or 'list'. So user \nexpectation is different from what you want diff to be.\n\nAlso there are no good words for what someone wants to see in this case. \nAt least I would assume the git project would have found them if they \nexisted. '--cached' is definitely not one of them. But we have fitting \nand widely known names for the targets, i.e 'working tree', 'index' and \n'head'.\n\n[...]\n>>> At in no place I _have_ to explain what is compared with what to explain\n>>> when and what for to use \"git diff\", \"git diff --cached\" and \"git diff\n>>> HEAD\".\n>>\n>> I'm sure every part of the user interface of gimp can be rationalized in\n>> the same way by someone deeply involved in the concepts and the\n>> structure of gimp, but still it is perceived as difficult by nearly\n>> everyone else. You look at it from inside and it looks logical. Others\n>> just don't have all the pieces to make that reasoning really work.\n>\n> What I wanted to say here that instead of teaching / trying to teach\n> new people something like the following:\n>\n>    There is working area, index and current commit (HEAD).  To compare\n>    workdir with index use this, to compare index with HEAD use that, to\n>    compare workdir with HEAD use this one.\n\nIf they know working area, index and head, you don't have to tell them \nthree times how to compare this with that, they just have to know they \ncan compare any which way they want. In fact, the situation *now* is \nexactly what you describe, you have to tell everyone for any of the 3 \ncombinations the command to use because it is not obvious.\n\n> we better do explaining higher level concepts\n>\n>    To examine your remaining changes, i.e. what you can \"git stage\",\n>    use \"git diff\".  To examine staged changes, i.e. what you\n>    \"git stage\"-d, use \"git diff --staged\"; that is what \"git commit\"\n>    will create.  To compare working version with given older version,\n>    use \"git diff<revision>\", in particular to compare with last version\n>    use \"git diff HEAD\"; that is what \"git commit --all\" would create.\n\nDo you realize that you are just enumerating all the possible \ncombinations again, exactly what you wanted to avoid? Ok, unfair \nargument, you want to just make it clear how to remember the commands. \nBut if I already need 3 emails from you to see the concept behind these \ncommands (and lets assume my slow-wittedness is par for the course) many \nothers will probably have the same problems. It may be a nice concept, \nbut the relation to the user interface is only detectable by close \nexamination.\n\nTeaching concepts is good. But if git is only usable after having \nlearned all those concepts, the entry barrier is much too big. With \ncommands like 'git put' and an improved diff people can use git first, \nthen learn the concepts while using git. Which is what most people have \nto do anyway if they encounter git at the work place for example.\n\n> The \"git diff NEXT WTREE\" looks like training wheels to me.  And like\n> training wheels they could become obstacles and not help to learning\n> git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))\n>\n\nIf your goal is that anyone who uses git is a git expert, they may be a \nhindrance (as are all the porcelain commands really). If you also want \nto make git friendly to people who will never get past intermediate or \nbeginner stage or will only use a small part of git or use git seldomly, \ntraining wheels are good.\n\nHolger.\n"},{"id":"169757","messageId":"201106091445.55601.jnareb@gmail.com","threadId":"27548","inReplyTo":"BANLkTimir5nQYJk+GuNQOzmTWMEXb2kWqQ@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-09T12:45:54Z","receivedAt":"2011-06-09T12:45:54Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, Jun 9, 2011, Michael Nahas wrote:\n> On Thu, Jun 9, 2011 at 5:48 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n>> On Wed, 8 June 2011, Michael Nahas wrote:\n>>> On Wed, Jun 8, 2011 at 11:05 AM, Jeff King <peff@peff.net> wrote:\n\n>>>> Isn't this going to be behavior change, since your NEXT is not quite the\n>>>> same as the index?\n\n[...]\n>>> I propose that during a\n>>> conflicted merge, that NEXT be computed as HEAD plus the resolved\n>>> files, that is, the files in stage 0 of the index.\n>>\n>> Why _HEAD_?\n> \n> Because we merged changed from another branch into HEAD.\n> Or we pull changes from a remote branch into HEAD.\n> \n> When a commit is written, it will be part of the branch referenced\n> by HEAD. \n\nAnd by selecting HEAD for diff's NEXT you would have problems with rebase,\nwhere you also can have conflicts, where 'ours' and 'theirs' are switched\naround (at least from one point of view).\n \n>>> \"git diff HEAD NEXT\" would print the resolved changes.\n>>> \"git diff NEXT WTREE\" would print the unresolved changes\n>>> \"git diff HEAD WTREE\" would print all changes.\n>>>\n>>> I believe that is the same behaviour as \"git diff\", \"git diff\n>>> --cached\" and \"git diff HEAD\" during a conflicted merge.\n>>\n>> \"git diff NEXT WTREE\" would not behave (with your proposal) like\n>> \"git diff\", but like \"git diff --ours\".\n> \n> OURS and HEAD are the same thing, so I doubt a command that does not\n> involve \"HEAD\" would behave like \"--ours\"\n\nOURS and HEAD are not the same thing.  In OURS you have _conflicted_\nchunks replaced with HEAD ('ours') version, but chunks that can be\nresolved sutomatically are resolved; sometimes to 'theirs' version.\n\n\"git diff\" in case of conflict prints 3-way combined diff between\n'ours', 'theirs' and working area version.  As \"git diff NEXT WTREE\"\ndoesn't print 3-way combined diff, it would be different for conflicts\nfrom \"git diff\".\n\n\"git diff --ours\" for nonconflicted entry (stage 0 in index) would\nprint ordinary diff between index and working area, just like\n\"git diff NEXT WTREE\".  What I just realized that at least from what\nyou wrote (corner case!) in case of conflicts it would be different\nfrom \"git diff NEXT WTREE\", as ours != HEAD.\n\n[...]\n>>> I do not know how \"n-way\" merge works.  I saw somewhere that indicated\n>>> that it was a series of N-1 two-way merges.\n>>\n>> Where this \"n-way merge\" came from?  Peff wrote about \"n-way combined\n>> diff\", which is something different.\n> \n> N-way merge exists.  It would be bad to say that I was answering a\n> question about conflicted merges if I didn't produce an answer for\n> N-way merges.  Unfortunately, I don't have enough information about\n> N-way merges to answer the question so I decided it was best to\n> acknowledge my ignorance and that I was giving an incomplete answer.\n\nActually while git can do n-way merge (so called \"octopus\" merge), it\neither resolves it cleanly, or refuses merge; it does not try to resolve\nconflict and present conflicts in the index.  So it is always \"3-way\ncombined diff\".\n\nBut you didn't answer about _combined diff_...\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169759","messageId":"201106091506.31511.jnareb@gmail.com","threadId":"27548","inReplyTo":"201106091445.55601.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-09T13:06:30Z","receivedAt":"2011-06-09T13:06:30Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jakub Narebski wrote:\n> On Thu, Jun 9, 2011, Michael Nahas wrote:\n>> On Thu, Jun 9, 2011 at 5:48 AM, Jakub Narebski <jnareb@gmail.com> wrote:\n>>> On Wed, 8 June 2011, Michael Nahas wrote:\n\n[...]\n>>>> \"git diff HEAD NEXT\" would print the resolved changes.\n>>>> \"git diff NEXT WTREE\" would print the unresolved changes\n>>>> \"git diff HEAD WTREE\" would print all changes.\n>>>>\n>>>> I believe that is the same behaviour as \"git diff\", \"git diff\n>>>> --cached\" and \"git diff HEAD\" during a conflicted merge.\n>>>\n>>> \"git diff NEXT WTREE\" would not behave (with your proposal) like\n>>> \"git diff\", but like \"git diff --ours\".\n>> \n>> OURS and HEAD are the same thing, so I doubt a command that does not\n>> involve \"HEAD\" would behave like \"--ours\"\n> \n> OURS and HEAD are not the same thing.  In OURS you have _conflicted_\n> chunks replaced with HEAD ('ours') version, but chunks that can be\n> resolved sutomatically are resolved; sometimes to 'theirs' version.\n\nI'm very sorry, my mistake.  I have actually checked and OURS is the\nsame as HEAD version.\n\nYou wrote that NEXT contains either stage 0 for resolved files, or\nOURS (HEAD) version for files with conflicts.  But that is exactly\nwhat \"git diff --ours\" show.\n\n> \"git diff\" in case of conflict prints 3-way combined diff between\n> 'ours', 'theirs' and working area version.  As \"git diff NEXT WTREE\"\n> doesn't print 3-way combined diff, it would be different for conflicts\n> from \"git diff\".\n> \n> \"git diff --ours\" for nonconflicted entry (stage 0 in index) would\n> print ordinary diff between index and working area, just like\n> \"git diff NEXT WTREE\". [...]\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169762","messageId":"201106091530.43555.trast@student.ethz.ch","threadId":"27548","inReplyTo":"4DF09A3D.8040908@op5.se","subject":"Re: Command-line interface thoughts","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2011-06-09T13:30:43Z","receivedAt":"2011-06-09T13:30:43Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Andreas Ericsson wrote:\n> On 06/09/2011 11:06 AM, Michael Haggerty wrote:\n> > THEIRS -- equivalent to the tree from MERGE_HEAD\n> \n> Except there might be any number of THEIRS in the case of an octopus\n> merge. The most common case is just one though.\n\nNot really, the current implementation bails out and tells you not to\nuse an octopus:\n\n  Trying simple merge with t/man-unquote-apos-3\n  Simple merge did not work, trying automatic merge.\n  Auto-merging Documentation/Makefile\n  ERROR: content conflict in Documentation/Makefile\n  Auto-merging Makefile\n  fatal: merge program failed\n  Automated merge did not work.\n  Should not be doing an Octopus.\n  Merge with strategy octopus failed.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"169785","messageId":"20110609161832.GB25885@sigill.intra.peff.net","threadId":"27548","inReplyTo":"4DF08D30.7070603@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-09T16:18:32Z","receivedAt":"2011-06-09T16:18:32Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 09, 2011 at 11:06:56AM +0200, Michael Haggerty wrote:\n\n> My naive understanding is that in the case of a merge commit, the index\n> contains information equivalent to *multiple* trees:\n> \n> NEXT -- HEAD plus the files that have been resolved\n> BASE -- the contents of the common ancestor\n> OURS -- equivalent to the tree from HEAD\n> THEIRS -- equivalent to the tree from MERGE_HEAD\n\nAlmost. Remember that as part of the merge resolution process,\nhigher-level stages will collapse down to 0. So the \"theirs\" stage of\nthe index is equivalent to MERGE_HEAD only if you have a conflict in\nevery file and have resolved nothing. Otherwise, any resolved entries\nwill not have a \"theirs\" entry at all.\n\nSo when I do \"git diff\", we will see for resolved entries that the\nworking tree matches stage 0 in the index, and show nothing. Whereas\nunresolved entries will have their diff shown. But with \"git diff\nMERGE_HEAD\", we will see differences from the other branch, even if\nthose differences are simply resolutions or even changes made on the\n\"ours\" branch.\n\nSo the index is not quite simply a set of four trees. The presence of\nvarious stages for each entry tells us the progress of resolution.\n\n-Peff\n"},{"id":"169794","messageId":"BANLkTinyYjXeg_khoU1dJVenP0mO2++hsw@mail.gmail.com","threadId":"27548","inReplyTo":"20110609161832.GB25885@sigill.intra.peff.net","subject":"Re: Command-line interface thoughts","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2011-06-09T17:15:38Z","receivedAt":"2011-06-09T17:15:38Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Thu, Jun 9, 2011 at 12:18 PM, Jeff King <peff@peff.net> wrote:\n> On Thu, Jun 09, 2011 at 11:06:56AM +0200, Michael Haggerty wrote:\n>\n>> My naive understanding is that in the case of a merge commit, the index\n>> contains information equivalent to *multiple* trees:\n>>\n>> NEXT -- HEAD plus the files that have been resolved\n>> BASE -- the contents of the common ancestor\n>> OURS -- equivalent to the tree from HEAD\n>> THEIRS -- equivalent to the tree from MERGE_HEAD\n>\n> Almost. Remember that as part of the merge resolution process,\n> higher-level stages will collapse down to 0. So the \"theirs\" stage of\n> the index is equivalent to MERGE_HEAD only if you have a conflict in\n> every file and have resolved nothing. Otherwise, any resolved entries\n> will not have a \"theirs\" entry at all.\n>\n> So when I do \"git diff\", we will see for resolved entries that the\n> working tree matches stage 0 in the index, and show nothing. Whereas\n> unresolved entries will have their diff shown. But with \"git diff\n> MERGE_HEAD\", we will see differences from the other branch, even if\n> those differences are simply resolutions or even changes made on the\n> \"ours\" branch.\n>\n> So the index is not quite simply a set of four trees. The presence of\n> various stages for each entry tells us the progress of resolution.\n\nHowever, it would be useful I think to expose it as four separate\ntrees. During conflict resolution, I often want to look at the\nconflicted files in these various states, and end up using various\nincantations that are somewhat baroque.\n\ne.g.:\n\n  $ git diff ...MERGE_HEAD -- /path/to/file\n\nis probably less clear than:\n\n  $ git diff BASE THEIRS -- /path/to/file\n\nIn fact, my first step after a conflicted merge is:\n\n  $ git tag -f ours HEAD\n  $ git tag -f theirs MERGE_HEAD\n  $ git tag -f base $(git merge-base HEAD MERGE_HEAD)\n\nj.\n"},{"id":"169793","messageId":"20110609172000.GA30983@sigill.intra.peff.net","threadId":"27548","inReplyTo":"BANLkTinyYjXeg_khoU1dJVenP0mO2++hsw@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-09T17:20:00Z","receivedAt":"2011-06-09T17:20:00Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 09, 2011 at 01:15:38PM -0400, Jay Soffian wrote:\n\n> > So the index is not quite simply a set of four trees. The presence of\n> > various stages for each entry tells us the progress of resolution.\n> \n> However, it would be useful I think to expose it as four separate\n> trees. During conflict resolution, I often want to look at the\n> conflicted files in these various states, and end up using various\n> incantations that are somewhat baroque.\n\nOh, I do agree that giving easier access to those things when you want\nthem is reasonable. I just think that it can't _replace_ diffing with\nthe index, which is able to look at all of the trees at once and present\nyou with a useful subset.\n\n> In fact, my first step after a conflicted merge is:\n> \n>   $ git tag -f ours HEAD\n>   $ git tag -f theirs MERGE_HEAD\n>   $ git tag -f base $(git merge-base HEAD MERGE_HEAD)\n\nDo note that this last one is only almost true. There may be multiple\nbases, and what merge-recursive does with them may mean that what ends\nup in the \"base\" index stage for a file may not match what is in the\nfirst first merge-base (e.g., if a recursive virtual merge creates a new\nbase).\n\nBut most of the time, it is right. :)\n\n-Peff\n"},{"id":"169797","messageId":"7vd3imykj1.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"BANLkTinyYjXeg_khoU1dJVenP0mO2++hsw@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-09T17:36:18Z","receivedAt":"2011-06-09T17:36:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> In fact, my first step after a conflicted merge is:\n>\n>   $ git tag -f ours HEAD\n>   $ git tag -f theirs MERGE_HEAD\n>   $ git tag -f base $(git merge-base HEAD MERGE_HEAD)\n\nThat looks like quite a convoluted set-up, I would think, than\nnecessary. You only need to remember these:\n\n # what does the result look if I said \"commit -a\" now?\n $ git diff HEAD\t  \n\n # I want to also see comparison with the original\n $ git checkout --conflict=diff3 <conflicted paths>...\n $ git diff\n\n # What did they do since they forked from my history?\n $ git diff ...MERGE_HEAD\n\n # What did I do since I forked from them?\n $ git diff MERGE_HEAD...\n\n # I want step-by-step explanation of how these paths were touched\n $ git log -p --left-right --merge [<conflicted paths>...]\n"},{"id":"169800","messageId":"4DF10ADA.5070206@alum.mit.edu","threadId":"27548","inReplyTo":"20110609161832.GB25885@sigill.intra.peff.net","subject":"Re: Command-line interface thoughts","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-06-09T18:03:06Z","receivedAt":"2011-06-09T18:03:06Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 06/09/2011 06:18 PM, Jeff King wrote:\n> On Thu, Jun 09, 2011 at 11:06:56AM +0200, Michael Haggerty wrote:\n> \n>> My naive understanding is that in the case of a merge commit, the index\n>> contains information equivalent to *multiple* trees:\n>>\n>> NEXT -- HEAD plus the files that have been resolved\n>> BASE -- the contents of the common ancestor\n>> OURS -- equivalent to the tree from HEAD\n>> THEIRS -- equivalent to the tree from MERGE_HEAD\n> \n> Almost. Remember that as part of the merge resolution process,\n> higher-level stages will collapse down to 0. So the \"theirs\" stage of\n> the index is equivalent to MERGE_HEAD only if you have a conflict in\n> every file and have resolved nothing. Otherwise, any resolved entries\n> will not have a \"theirs\" entry at all.\n\nThanks for the correction.  So one interesting pseudo-tree would be\n\nOURS -- The NEXT version of any file that has been resolved; and the\nstage 2 version of any file that has not yet been resolved.  The name\nseems consistent with what is meant by, e.g., \"git checkout --ours\".\n\nAnother interesting pseudo-tree would be\n\nTHEIRS -- The NEXT version of any file that has been resolved; and the\nstage 3 version of any file that has not yet been resolved.  The name\nseems consistent with \"git checkout --theirs\".\n\nThe other trees HEAD and MERGE_HEAD are already accessible under those\nnames, and so there is no need to make a special provision to access them.\n\nBASE should presumably be something like the NEXT version of any file\nthat has been resolved and the stage 1 version of any file that has not\nbeen resolved.\n\n> So the index is not quite simply a set of four trees. The presence of\n> various stages for each entry tells us the progress of resolution.\n\nWouldn't the four trees described above contain information equivalent\nto the contents of the index?  For example, the resolution work that\nremains to be done that can be inquired using old-fashioned \"git diff\"\n(3-way diff) could also be accessed via\n\n    git diff NEXT OURS\n    git diff NEXT THEIRS\n\nor even\n\n    git diff NEXT WTREE\n\nif you want to see the remaining conflicts in <<<<<======>>>>>> format.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"169802","messageId":"BANLkTikLWuENTpCF9BXPJWawLUpKW0077A@mail.gmail.com","threadId":"27548","inReplyTo":"7vd3imykj1.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2011-06-09T18:20:29Z","receivedAt":"2011-06-09T18:20:29Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Thu, Jun 9, 2011 at 1:36 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jay Soffian <jaysoffian@gmail.com> writes:\n>\n>> In fact, my first step after a conflicted merge is:\n>>\n>>   $ git tag -f ours HEAD\n>>   $ git tag -f theirs MERGE_HEAD\n>>   $ git tag -f base $(git merge-base HEAD MERGE_HEAD)\n>\n> That looks like quite a convoluted set-up, I would think, than\n> necessary. You only need to remember these:\n\nMy merges are fairly complex, involving a code base of 20k+ files with\nmerges bringing several hundred commits at a time. So, they require\nlots of amending after conflict resolution to get into shape, where I\noften have to look at either side of the merge. I prefer to tag at the\ntime of the merge so that I can use ours, theirs, and before and after\nthe merge (otherwise it's HEAD MERGE_HEAD vs HEAD^ and HEAD^2).\n\n>  # what does the result look if I said \"commit -a\" now?\n>  $ git diff HEAD\n\nI never use commit -a.\n\n>  # I want to also see comparison with the original\n>  $ git checkout --conflict=diff3 <conflicted paths>...\n>  $ git diff\n\nI have merge.conflictstyle diff3 in my .gitconfig.\n\n>  # What did they do since they forked from my history?\n>  $ git diff ...MERGE_HEAD\n>\n>  # What did I do since I forked from them?\n>  $ git diff MERGE_HEAD...\n\nSure, I already suggested that, but if I want to do the same after the\nmerge I can use the tags I've already set up.\n\n>  # I want step-by-step explanation of how these paths were touched\n>  $ git log -p --left-right --merge [<conflicted paths>...]\n\nNow that's one I haven't used before. I usually use log ..MERGE_HEAD\nand log MERGE_HEAD.. on the paths.\n\nj.\n"},{"id":"169803","messageId":"7v8vtayhnm.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"4DF10ADA.5070206@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-09T18:38:21Z","receivedAt":"2011-06-09T18:38:21Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> Wouldn't the four trees described above contain information equivalent\n> to the contents of the index?\n\nIn the same sense that you can re-create the state in the index by running\nthe merge again between HEAD and MERGE_HEAD, yes, they probably do, but is\nthat a useful question to ask?\n\nI think this mega-thread served its purpose. It started to explore \"will\nit make it easier to understand and explain if we use these tokens to name\ntrees that do not exist in reality?\" which is a worthy thing to do.  The\nconclusion appears to be \"well we do not even know what exactly these\ntokens mean in certain situations.\" but at least people tried, and along\nthe way a few new people seem to have become more aware of the index, so\noverall we didn't lose that much.\n"},{"id":"169804","messageId":"4DF11C3B.4000804@alum.mit.edu","threadId":"27548","inReplyTo":"7v8vtayhnm.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-06-09T19:17:15Z","receivedAt":"2011-06-09T19:17:15Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 06/09/2011 08:38 PM, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n>> Wouldn't the four trees described above contain information equivalent\n>> to the contents of the index?\n> \n> In the same sense that you can re-create the state in the index by running\n> the merge again between HEAD and MERGE_HEAD, yes, they probably do, but is\n> that a useful question to ask?\n\nThe questions is obviously not useful if the only answer is the one that\nyou give.\n\nBut it seems to me that the four pseudo-trees NEXT, OURS, THEIRS, and\nBASE are a complete and self-consistent alternative representation of\nthe information contained in the index.  If this is true, then I claim\nthat this representation would be much easier to understand and remember\nthan the index stages (with its highly mnemonic names 0, 1, 2, and 3!)\nand the irregular myriad of commands and options currently needed to\naccess it.\n\n> I think this mega-thread served its purpose. It started to explore \"will\n> it make it easier to understand and explain if we use these tokens to name\n> trees that do not exist in reality?\" which is a worthy thing to do.  The\n> conclusion appears to be \"well we do not even know what exactly these\n> tokens mean in certain situations.\"\n\nWhy do you reach that conclusion?  Are you claiming that the proposed\ndefinitions of the four pseudo-trees upthread are incorrect or\ninsufficiently defined?\n\nWe are about to introduce git at my company, and this is one of the\npoints that makes me cringe when I think of explaining it to developers\n(let alone non-developers).  Even here on the git mailing list, where\nmost people are numbed to the git UI, there has been a lot of confusion\nabout how to get needed information from the index.  And I truly believe\nthat the commands currently needed to access the information in the\nindex are so nonuniform that half of the participants in this discussion\nwill have to look them up *again* the next time they need them.\n\nPlease throw us struggling users a bone :-)\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"169805","messageId":"7v4o3yyesc.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"BANLkTikLWuENTpCF9BXPJWawLUpKW0077A@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-09T19:40:19Z","receivedAt":"2011-06-09T19:40:19Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n>>  # what does the result look if I said \"commit -a\" now?\n>>  $ git diff HEAD\n>\n> I never use commit -a.\n\nWell I said 'commit -a' only so that any newbie can understand what I\nmeant, and certainly didn't mean to suggest you to use 'commit -a'.  You\ncan rephrase it as: \"Now I _think_ I have good state in my working tree;\nwhat is the change since HEAD, i.e. the result of the merge?\".\n\n\n>>  # I want to also see comparison with the original\n>>  $ git checkout --conflict=diff3 <conflicted paths>...\n>>  $ git diff\n>\n> I have merge.conflictstyle diff3 in my .gitconfig.\n\nGood for you.\n\n> ...\n> Now that's one I haven't used before.\n\nSurely there is room for everybody to learn something every day ;-).\n"},{"id":"169806","messageId":"20110609194104.GA4026@sigill.intra.peff.net","threadId":"27548","inReplyTo":"4DF10ADA.5070206@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-09T19:41:05Z","receivedAt":"2011-06-09T19:41:05Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 09, 2011 at 08:03:06PM +0200, Michael Haggerty wrote:\n\n> Thanks for the correction.  So one interesting pseudo-tree would be\n> \n> OURS -- The NEXT version of any file that has been resolved; and the\n> stage 2 version of any file that has not yet been resolved.  The name\n> seems consistent with what is meant by, e.g., \"git checkout --ours\".\n\nYeah, that makes sense to me as a definition.\n\n> > So the index is not quite simply a set of four trees. The presence of\n> > various stages for each entry tells us the progress of resolution.\n> \n> Wouldn't the four trees described above contain information equivalent\n> to the contents of the index?\n\nTaken together, yes, I think you could represent the whole index. But\neach taken alone is missing some information that might be useful in a\ndiff.\n\nFor example, if I do \"git diff THEIRS WTREE\" during a merge conflict,\nthat is a 2-way diff that is going to show things in THEIRS going away,\nand both things brought by OURS and things that are part of a resolution\nbeing added. That's less information than \"git diff INDEX WTREE\" (i.e.,\nwhat is currently spelled as \"git diff\") provides, because when looking\nat the whole index we can do a combined diff showing which part came\nfrom which parent.\n\n> For example, the resolution work that remains to be done that can be\n> inquired using old-fashioned \"git diff\" (3-way diff) could also be\n> accessed via\n> \n>     git diff NEXT OURS\n>     git diff NEXT THEIRS\n\nBut you don't get to see it together. You have to do two separate diffs,\nwhich means you will see conflicted regions twice. Try:\n\n  git log --merges -p --cc\n\non a repo of your choice, and compare with:\n\n  git log --merges -p -m\n\nThe former is what \"git diff\" would show just before marking paths as\nresolved, and the latter is what your two diffs above would show.\n\n> or even\n> \n>     git diff NEXT WTREE\n> \n> if you want to see the remaining conflicts in <<<<<======>>>>>> format.\n\nAs I mentioned in an earlier email, this doesn't show which parts are\npart of the resolution process (including conflict markers), and which\ncame from either side of the merge.\n\n-Peff\n"},{"id":"169807","messageId":"20110609200403.GA3955@sigill.intra.peff.net","threadId":"27548","inReplyTo":"7v8vtayhnm.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-09T20:04:03Z","receivedAt":"2011-06-09T20:04:03Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 09, 2011 at 11:38:21AM -0700, Junio C Hamano wrote:\n\n> I think this mega-thread served its purpose. It started to explore \"will\n> it make it easier to understand and explain if we use these tokens to name\n> trees that do not exist in reality?\" which is a worthy thing to do.  The\n> conclusion appears to be \"well we do not even know what exactly these\n> tokens mean in certain situations.\" but at least people tried, and along\n> the way a few new people seem to have become more aware of the index, so\n> overall we didn't lose that much.\n\nI think there are actually two questions here:\n\n  1. Will it be easier for people to understand \"git diff\" if we use\n     tokens to describe non-treeish sources and destinations?\n\n  2. Are there better tokens to use to break down parts of the index?\n\nI don't have a big problem with (1). Allowing things like:\n\n  git diff INDEX WTREE\n\nallows one to explain what is going on with the diff syntax in a very\nclear and verbose manner. I wouldn't want to type that every day, but\nthat's OK; \"git diff\" will always mean the same thing as it always has,\nbut can now be explained to people who have trouble seeing it in terms\nof \"git diff INDEX WTREE\".\n\nThere's still a bit of magic in that INDEX is _not_ a tree, but I think\nthat's a good thing. When there are no merge conflicts, it will behave\nidentically to the proposed NEXT tree. And when there are conflicts, it\nwill show you something even more useful.\n\nIt does have the potential to confuse in that \"INDEX\" is not actually a\ntree, and so we can't expect to use it as a tree-ish everywhere. So now\ndiff feels a little inconsistent with other parts of git. One idea,\nwhich I think is probably too crazy, would be to let INDEX be used as a\ntree-ish everywhere, but only if all entries are at stage 0. Otherwise,\nit will die with an error. That would make it more or less a more\nverbose version of \":\" (e.g., I can do \"git show :Makefile\", but it will\ndie with an error if Makefile exists only at higher stages).\n\n\nI'm less sure about these new tokens, for a few reasons:\n\n  1. You get less useful answers in some situations by treating each\n     stage as a separate tree (e.g., lack of combined diff). So why\n     would I want to use them?\n\n  2. Their answers are different than what diffing against the INDEX\n     could give. So in theory they could be more useful in different\n     situations than a diff against the index. But I haven't seen a good\n     example of what such a situation would be.\n\n  3. They're supposed to introduce consistency in explaining diff\n     behavior. But we're not going to change what \"git diff\" does to not\n     use the whole index. So \"git diff\" isn't actually expressible using\n     these tokens.\n\n  4. They're supposed to be simpler to understand than index stages. But\n     are they? The latest definitions seem to be:\n\n       OURS is a tree of each path in the index, either from stage 2 if\n       it exists, or from NEXT otherwise.\n\n       NEXT is a tree of each path in the index, either from stage 0 if\n       it exists, or from HEAD otherwise.\n\n     But that doesn't seem any simpler to me than just saying \"the index\n     has numbered stages, and they correspond to resolved, base, ours,\n     and theirs\".\n\nI agree that \":2:Makefile\" is not exactly an intuitive way to ask for\n\"ours\". Didn't we have a patch at one point a year or two ago to allow\nusing names instead of numbered stages? If we allowed \"INDEX\" as a\nverbose noise-word in front of \":\", then you could say:\n\n  git show INDEX:OURS:Makefile\n\nwhich is identical to what I wrote above, but is perhaps easier to\nexplain.\n\n-Peff\n"},{"id":"169815","messageId":"4DF13D00.2060000@alum.mit.edu","threadId":"27548","inReplyTo":"20110609200403.GA3955@sigill.intra.peff.net","subject":"Re: Command-line interface thoughts","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-06-09T21:37:04Z","receivedAt":"2011-06-09T21:37:04Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 06/09/2011 10:04 PM, Jeff King wrote:\n> I'm less sure about these new tokens, for a few reasons:\n> \n>   1. You get less useful answers in some situations by treating each\n>      stage as a separate tree (e.g., lack of combined diff). So why\n>      would I want to use them?\n\nWouldn't it be nice to be able to do a combined diff between *any* two\ntrees?  Then the nonuniform merge behavior of \"git diff\" would be a\nspecial case of a general concept:\n\n    git diff3 OURS NEXT THEIRS\n\n>   4. They're supposed to be simpler to understand than index stages. But\n>      are they? The latest definitions seem to be:\n> \n>        OURS is a tree of each path in the index, either from stage 2 if\n>        it exists, or from NEXT otherwise.\n> \n>        NEXT is a tree of each path in the index, either from stage 0 if\n>        it exists, or from HEAD otherwise.\n> \n>      But that doesn't seem any simpler to me than just saying \"the index\n>      has numbered stages, and they correspond to resolved, base, ours,\n>      and theirs\".\n\nThere is no need to explain the pseudotrees in terms of the index\nstages; the pseudotrees are easier to understand and should therefore\nbecome the primary way to describe the index.  Let me give it a try, at\ntutorial level.  Assume that the concepts HEAD and WTREE have already\nbeen introduced:\n\n  The \"index\" is a special area that can hold one or more temporary\n  snapshots of your version-controlled content.  Each snapshot is\n  called a \"tree\" because it is analogous to a filesystem tree such\n  as the working tree [1].\n\n  Usually the index holds a single tree called \"NEXT\".  NEXT is a\n  snapshot of the state of the working tree that is ready to be\n  committed.  This usually consists of the contents from the commit\n  that was last checked out (HEAD), plus any changes that have been\n  staged for commit using \"git stage\".\n\n  It is possible to use \"git diff\" to view the difference between any\n  two trees, whether they be trees in the index, trees in commits, or\n  the working tree.  For example, to see the difference between the\n  last commit and the working tree, use\n\n      git diff HEAD WTREE\n\n  If you would like to see the changes that are ready to be committed,\n  type\n\n      git diff HEAD NEXT\n\n  To see the changes in your working tree that have not yet been staged\n  for commit, use\n\n      git diff NEXT WTREE\n\n  (The previous command can be abbreviated to \"git diff\".)\n\n  However, things become more complicated during a merge, when the\n  index is used to keep track of the merge's progress.  During a\n  merge, the index contains four trees: \"NEXT\", \"OURS\", \"THEIRS\", and\n  \"BASE\".  These four trees are modified as merge conflicts are\n  resolved.\n\n  NEXT, as usual, contains the contents that are ready to be committed.\n  Specifically, NEXT contains:\n\n    * the original contents of the branch being merged into\n    * plus the merged versions of any files that merged cleanly\n    * plus any changes that have been staged for commit using\n      \"git stage\"; for example, files whose conflicts have been\n      resolved manually.\n\n  OURS contains all of the resolved merges from NEXT, with any\n  remaining conflicts resolved by using the version from the branch\n  being merged *into*.\n\n  THEIRS contains all of the resolved merges from NEXT, with any\n  remaining conflicts resolved by using the content from the branch\n  being merged *from*.\n\n  BASE contains all of the resolved merges from NEXT, with any\n  remaining conflicts resolved by using the content from the most\n  recent ancestor of the two branches being merged.\n\n  As before, \"git diff\" can be used to view the differences between\n  these various trees.  For example, the following command displays the\n  conflicts that still have to be resolved:\n\n      git diff NEXT WTREE\n\n  To see how the resolved version differs from the contents of each of\n  the original branches, use\n\n      git diff HEAD NEXT\n      git diff MERGE_HEAD NEXT\n\n  The \"git diff3\" command can be used to compare three trees at once:\n\n      git diff3 OURS NEXT THEIRS\n\n  The previous command can be abbreviated to \"git diff3\".\n\n  [1] The trees that are stored in the index are in an internal format\n      that is optimized for efficiency.  They are not stored as\n      individual files like in your working copy.\n\nThoughts?\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"169816","messageId":"201106100004.58040.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DF13D00.2060000@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-09T22:04:56Z","receivedAt":"2011-06-09T22:04:56Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 9 Jan 2011, Michael Haggerty wrote:\n> On 06/09/2011 10:04 PM, Jeff King wrote:\n> > I'm less sure about these new tokens, for a few reasons:\n> > \n> >   1. You get less useful answers in some situations by treating each\n> >      stage as a separate tree (e.g., lack of combined diff). So why\n> >      would I want to use them?\n> \n> Wouldn't it be nice to be able to do a combined diff between *any* two\n> trees?  Then the nonuniform merge behavior of \"git diff\" would be a\n> special case of a general concept:\n> \n>     git diff3 OURS NEXT THEIRS\n                ^^^^^^^^^^^^^^^^ -- ???\n\nFirst, it is unnecessary power, unnecessary complication.  WTF. you are\ndoing comparing _abitrary_ trees?\n\nSecond, for files with merge conflicts \"git diff\" is the same as\n\"git diff3 OURS THEIRS WTREE\", not \"git diff3 OURS NEXT THEIRS\".\nAs you can see it is very easy to construct wrong options to git-diff,\nand end up with nonsense!\n\nThird, \"git diff\" is not \"git diff3 OURS THEIRS WTREE\" in general,\nbecause for resolved files it is \"git diff NEXT WTREE\", which is\nvery useful.  \n\nI could agree with STAGE being possibly multi-stage thingy, so that\n\"git diff STAGE WTREE\" in case of merge conflict is _exactly the same_\nas \"git diff\".\n\n> >   4. They're supposed to be simpler to understand than index stages. But\n> >      are they? The latest definitions seem to be:\n> > \n> >        OURS is a tree of each path in the index, either from stage 2 if\n> >        it exists, or from NEXT otherwise.\n> > \n> >        NEXT is a tree of each path in the index, either from stage 0 if\n> >        it exists, or from HEAD otherwise.\n> > \n> >      But that doesn't seem any simpler to me than just saying \"the index\n> >      has numbered stages, and they correspond to resolved, base, ours,\n> >      and theirs\".\n> \n> There is no need to explain the pseudotrees in terms of the index\n> stages; the pseudotrees are easier to understand and should therefore\n> become the primary way to describe the index.  Let me give it a try, at\n> tutorial level.  Assume that the concepts HEAD and WTREE have already\n> been introduced:\n> \n>   The \"index\" is a special area that can hold one or more temporary\n>   snapshots of your version-controlled content.  Each snapshot is\n>   called a \"tree\" because it is analogous to a filesystem tree such\n>   as the working tree [1].\n> \n>   Usually the index holds a single tree called \"NEXT\".  NEXT is a\n>   snapshot of the state of the working tree that is ready to be\n>   committed.  This usually consists of the contents from the commit\n>   that was last checked out (HEAD), plus any changes that have been\n>   staged for commit using \"git stage\".\n> \n>   It is possible to use \"git diff\" to view the difference between any\n>   two trees, whether they be trees in the index, trees in commits, or\n>   the working tree.  For example, to see the difference between the\n>   last commit and the working tree, use\n> \n>       git diff HEAD WTREE\n\n[cut very long explanation]\n \nI won't repear the THIRD time simple and around *three times shorter*\nexplanation on _when_ to use which form: \"git diff\" for your own remaining\nchanges that can be \"git add\"-ef, \"git diff --staged\" for which changes\nare staged i.e. what you have \"git add\"-ed, and \"git diff HEAD\" to compare\ncurrent with last.\n\nThose pseudo-trees might be useful if you know what you want to compare,\nbut are not useful if you know what you want to see (you have to remember\nwhat to compare with which).  Never mind they are longer to write...\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169817","messageId":"20110609222144.GA7413@sigill.intra.peff.net","threadId":"27548","inReplyTo":"4DF13D00.2060000@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-09T22:21:44Z","receivedAt":"2011-06-09T22:21:44Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 09, 2011 at 11:37:04PM +0200, Michael Haggerty wrote:\n\n> On 06/09/2011 10:04 PM, Jeff King wrote:\n> > I'm less sure about these new tokens, for a few reasons:\n> > \n> >   1. You get less useful answers in some situations by treating each\n> >      stage as a separate tree (e.g., lack of combined diff). So why\n> >      would I want to use them?\n> \n> Wouldn't it be nice to be able to do a combined diff between *any* two\n> trees?  Then the nonuniform merge behavior of \"git diff\" would be a\n> special case of a general concept:\n> \n>     git diff3 OURS NEXT THEIRS\n\nYou can almost already do that with \"git diff\". For example:\n\n  merge=456a4c08b8d8ddefda939014c15877ace3e3f499\n  git diff $merge $merge^1 $merge^2\n\nwhich should show the same diff as \"git show $merge\".\n\nTo do that in the index case, I think you would want:\n\n  git diff WTREE HEAD MERGE_HEAD\n\nexcept that you can't say \"WTREE\" yet.\n\nYou might want:\n\n  git diff NEXT HEAD MERGE_HEAD\n\nbut I'm not sure it is going to be useful. For resolved paths, it makes\nsense: show the combined diff that would happen if I committed this\nright now. But for unmerged paths, NEXT is going to default to HEAD, so\nit's going to be the combined diff as if you threw out all of the\nchanges from both branches. Which is probably not helpful.\n\nI'm not sure about OURS and THEIRS versus HEAD and MERGE_HEAD. They also\ndefault to HEAD, so I guess that:\n\n  git diff NEXT OURS THEIRS\n\nwould omit unresolved paths and give you only the \"what would happen if\nI committed this\". Which is not something I have ever heard of somebody\nwanting, but is at least something you can't calculate with current git.\n\nI'd be curious to see more concrete examples of situations where these\ntokens could help.\n\n> There is no need to explain the pseudotrees in terms of the index\n> stages; the pseudotrees are easier to understand and should therefore\n> become the primary way to describe the index.  Let me give it a try, at\n> tutorial level.  Assume that the concepts HEAD and WTREE have already\n> been introduced:\n> [...]\n\nNot too bad. It's long, but I don't think any single concept in it is\nhard. Of course I already understand the index, so maybe I'm not a good\njudge.\n\nI would be most worried about the following spots in terms of confusing\nusers:\n\n>   The \"index\" is a special area that can hold one or more temporary\n>   snapshots of your version-controlled content.  Each snapshot is\n>   called a \"tree\" because it is analogous to a filesystem tree such\n>   as the working tree [1].\n\nThis is giving the user a different mental model than what is actually\nin the index. I haven't yet convinced myself whether that mental model\nis completely isomorphic to what is actually being stored or not. If it\nisn't, then what are the cases where the abstraction is going to leak,\nand what problems is it going to cause?\n\nIOW, I am worried about the moment where somebody does a diff with one\nof these trees, and it _doesn't_ do what they expect, and the\nexplanation for what did happen involves explaining how the index is\nactually stored.\n\n>   NEXT, as usual, contains the contents that are ready to be committed.\n>   Specifically, NEXT contains:\n> \n>     * the original contents of the branch being merged into\n>     * plus the merged versions of any files that merged cleanly\n>     * plus any changes that have been staged for commit using\n>       \"git stage\"; for example, files whose conflicts have been\n>       resolved manually.\n> \n>   OURS contains all of the resolved merges from NEXT, with any\n>   remaining conflicts resolved by using the version from the branch\n>   being merged *into*.\n> \n>   THEIRS contains all of the resolved merges from NEXT, with any\n>   remaining conflicts resolved by using the content from the branch\n>   being merged *from*.\n> \n>   BASE contains all of the resolved merges from NEXT, with any\n>   remaining conflicts resolved by using the content from the most\n>   recent ancestor of the two branches being merged.\n\nSo now we have primitive definitions, which is good. They're clear,\nunambiguous, and easy to understand. But what worries me is whether\npeople will be able to extrapolate that those definitions mean to the\nvarious diffs.\n\nIt's nice that you give examples of how to ask for some common things,\nbut I wonder if we are creating the same situation of \"here's the magic\nincantation to show you what you want\" without actually creating more\nunderstanding in the average user. That is, will \"git diff NEXT OURS\nTHEIRS\" be any less magical to most users than \"git diff\"? Understanding\n_why_ they work seems as difficult to me as understanding the index in\nthe first place.\n\n>   As before, \"git diff\" can be used to view the differences between\n>   these various trees.  For example, the following command displays the\n>   conflicts that still have to be resolved:\n> \n>       git diff NEXT WTREE\n\nI wouldn't recommend this; the 3-way diff contains more information. I\nknow why you introduced this one first. It fits the path of your\nnarrative better. But it seems like it is also being recommended as the\nright way to get this information.\n\n-Peff\n"},{"id":"169818","messageId":"BANLkTinAxWfAgBOOF0gkYDWmXDCRH+6zYg@mail.gmail.com","threadId":"27548","inReplyTo":"4DF13D00.2060000@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-09T22:27:11Z","receivedAt":"2011-06-09T22:27:11Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"I dunno Michael, your idea sounds dangerous.\n\nYou're saying that the user interface should be defined with concepts\nthat have nothing to do with the plumbing.  That's crazy talk!  Next\nyou'll be arguing that users don't need to know that the Index file\nhas 4 stages!\n\n;)\n\n\nJakub: \"it is unnecessary power\"\nYeah, like that an argument that anyone here will listen to.  \"I can't\nlet you have diff3.  It's too much power for you.  You might trash the\nrepository with ... uh... diff3.\"\n\nPeff: \"... use tokens to describe non-treeish sources and destinations\"\nWhat defines \"tree-ish\"ness?\nWhat is non-treeish about NEXT/WTREE/etc.?\nDo you know of anything in the INDEX file that would not be visible\nfrom NEXT/WTREE/OURS/THEIRS?\n\nMike\n\n\nOn Thu, Jun 9, 2011 at 5:37 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> On 06/09/2011 10:04 PM, Jeff King wrote:\n>> I'm less sure about these new tokens, for a few reasons:\n>>\n>>   1. You get less useful answers in some situations by treating each\n>>      stage as a separate tree (e.g., lack of combined diff). So why\n>>      would I want to use them?\n>\n> Wouldn't it be nice to be able to do a combined diff between *any* two\n> trees?  Then the nonuniform merge behavior of \"git diff\" would be a\n> special case of a general concept:\n>\n>    git diff3 OURS NEXT THEIRS\n>\n>>   4. They're supposed to be simpler to understand than index stages. But\n>>      are they? The latest definitions seem to be:\n>>\n>>        OURS is a tree of each path in the index, either from stage 2 if\n>>        it exists, or from NEXT otherwise.\n>>\n>>        NEXT is a tree of each path in the index, either from stage 0 if\n>>        it exists, or from HEAD otherwise.\n>>\n>>      But that doesn't seem any simpler to me than just saying \"the index\n>>      has numbered stages, and they correspond to resolved, base, ours,\n>>      and theirs\".\n>\n> There is no need to explain the pseudotrees in terms of the index\n> stages; the pseudotrees are easier to understand and should therefore\n> become the primary way to describe the index.  Let me give it a try, at\n> tutorial level.  Assume that the concepts HEAD and WTREE have already\n> been introduced:\n>\n>  The \"index\" is a special area that can hold one or more temporary\n>  snapshots of your version-controlled content.  Each snapshot is\n>  called a \"tree\" because it is analogous to a filesystem tree such\n>  as the working tree [1].\n>\n>  Usually the index holds a single tree called \"NEXT\".  NEXT is a\n>  snapshot of the state of the working tree that is ready to be\n>  committed.  This usually consists of the contents from the commit\n>  that was last checked out (HEAD), plus any changes that have been\n>  staged for commit using \"git stage\".\n>\n>  It is possible to use \"git diff\" to view the difference between any\n>  two trees, whether they be trees in the index, trees in commits, or\n>  the working tree.  For example, to see the difference between the\n>  last commit and the working tree, use\n>\n>      git diff HEAD WTREE\n>\n>  If you would like to see the changes that are ready to be committed,\n>  type\n>\n>      git diff HEAD NEXT\n>\n>  To see the changes in your working tree that have not yet been staged\n>  for commit, use\n>\n>      git diff NEXT WTREE\n>\n>  (The previous command can be abbreviated to \"git diff\".)\n>\n>  However, things become more complicated during a merge, when the\n>  index is used to keep track of the merge's progress.  During a\n>  merge, the index contains four trees: \"NEXT\", \"OURS\", \"THEIRS\", and\n>  \"BASE\".  These four trees are modified as merge conflicts are\n>  resolved.\n>\n>  NEXT, as usual, contains the contents that are ready to be committed.\n>  Specifically, NEXT contains:\n>\n>    * the original contents of the branch being merged into\n>    * plus the merged versions of any files that merged cleanly\n>    * plus any changes that have been staged for commit using\n>      \"git stage\"; for example, files whose conflicts have been\n>      resolved manually.\n>\n>  OURS contains all of the resolved merges from NEXT, with any\n>  remaining conflicts resolved by using the version from the branch\n>  being merged *into*.\n>\n>  THEIRS contains all of the resolved merges from NEXT, with any\n>  remaining conflicts resolved by using the content from the branch\n>  being merged *from*.\n>\n>  BASE contains all of the resolved merges from NEXT, with any\n>  remaining conflicts resolved by using the content from the most\n>  recent ancestor of the two branches being merged.\n>\n>  As before, \"git diff\" can be used to view the differences between\n>  these various trees.  For example, the following command displays the\n>  conflicts that still have to be resolved:\n>\n>      git diff NEXT WTREE\n>\n>  To see how the resolved version differs from the contents of each of\n>  the original branches, use\n>\n>      git diff HEAD NEXT\n>      git diff MERGE_HEAD NEXT\n>\n>  The \"git diff3\" command can be used to compare three trees at once:\n>\n>      git diff3 OURS NEXT THEIRS\n>\n>  The previous command can be abbreviated to \"git diff3\".\n>\n>  [1] The trees that are stored in the index are in an internal format\n>      that is optimized for efficiency.  They are not stored as\n>      individual files like in your working copy.\n>\n> Thoughts?\n>\n> Michael\n>\n> --\n> Michael Haggerty\n> mhagger@alum.mit.edu\n> http://softwareswirl.blogspot.com/\n>\n"},{"id":"169821","messageId":"20110609223825.GA7771@sigill.intra.peff.net","threadId":"27548","inReplyTo":"BANLkTinAxWfAgBOOF0gkYDWmXDCRH+6zYg@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-09T22:38:25Z","receivedAt":"2011-06-09T22:38:25Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 09, 2011 at 06:27:11PM -0400, Michael Nahas wrote:\n\n> I dunno Michael, your idea sounds dangerous.\n> \n> You're saying that the user interface should be defined with concepts\n> that have nothing to do with the plumbing.  That's crazy talk!  Next\n> you'll be arguing that users don't need to know that the Index file\n> has 4 stages!\n> \n> ;)\n\nI know you are being sarcastic, but it _is_ a dangerous thing. One of\nthe great things about git is that it exposes the details of its data\nstructures. So you rarely run into corner cases where the UI has given\nyou an inaccurate mental model, and you have to reconcile what is\nactually happening with your mental model. The tradeoff, of course, is\nthat you get exposed to the full complexity of what is happening.\n\nAnd note that I'm not saying it's impossible, or it's something we\ndefinitely shouldn't do. Only that we should be aware of what\ninaccuracies we might be feeding to the user, and asking questions about\nhow that might bite is. Like: how likely is the user to run into a\ncorner case where git does something unexpected? If it does happen, how\nmuch worse will explaining the behavior be than simply having exposed\nthem to lower-level constructs in the first place?\n\nAlso note that I'm not even sure that this token proposal is in fact\nintroducing inaccuracies, and is not simply an alternate but equivalent\nmental model. But these are the types of things I think people should be\nthinking about in a proposal like this.\n\n> Jakub: \"it is unnecessary power\"\n> Yeah, like that an argument that anyone here will listen to.  \"I can't\n> let you have diff3.  It's too much power for you.  You might trash the\n> repository with ... uh... diff3.\"\n\nIt's also wrong. Diff already does combined diff on arbitrary trees. So\nunnecessary, perhaps, but already there.\n\n> Peff: \"... use tokens to describe non-treeish sources and destinations\"\n> What defines \"tree-ish\"ness?\n\nI was using tree-ish there in the sense that it is used in the git\ndocumentation, which is: a reference that can resolve to a git\ntree object. So a tree sha1, a commit sha1 (which would resolve to its\ntree), a tag that points to a tree or commit, a ref that points to any\nof the above, and so on.\n\nI think it is actually dying out from git documentation, though.  I was\nwriting to Junio there, who I know understands that term, but I should\nhave been more mindful that other readers of the thread wouldn't.\n\n> What is non-treeish about NEXT/WTREE/etc.?\n\nThey don't resolve to git tree objects. :)\n\n> Do you know of anything in the INDEX file that would not be visible\n> from NEXT/WTREE/OURS/THEIRS?\n\nThe stat information, but that is usually ignored in porcelain, anyway\n(we refresh the state information at the beginning of most porcelain\ncommands, so you can just assume everything is up to date with the\nworking tree and will be shown as such).\n\n-Peff\n"},{"id":"169824","messageId":"201106100056.00256.jnareb@gmail.com","threadId":"27548","inReplyTo":"20110609223825.GA7771@sigill.intra.peff.net","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-09T22:55:59Z","receivedAt":"2011-06-09T22:55:59Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Fri, 10 Jun 2011, Jeff King wrote:\n> On Thu, Jun 09, 2011 at 06:27:11PM -0400, Michael Nahas wrote:\n\n> > Jakub: \"it is unnecessary power\"\n> > Yeah, like that an argument that anyone here will listen to.  \"I can't\n> > let you have diff3.  It's too much power for you.  You might trash the\n> > repository with ... uh... diff3.\"\n> \n> It's also wrong. Diff already does combined diff on arbitrary trees. So\n> unnecessary, perhaps, but already there.\n\nBTW. I should have written \"too much flexibility\", not \"too much power\".\nWhat I had in mind is _convention_-based branching model in Subversion,\nand its svn:mergeinfo property... which allow things like recording\ncherry-picking, partial merges (of subtree), comitting on a tag or\ncommits over more than one branch... but which things are usually user's\nerror, not prevented by a tool.\n \n> > Peff: \"... use tokens to describe non-treeish sources and destinations\"\n> > What defines \"tree-ish\"ness?\n> \n> I was using tree-ish there in the sense that it is used in the git\n> documentation, which is: a reference that can resolve to a git\n> tree object. So a tree sha1, a commit sha1 (which would resolve to its\n> tree), a tag that points to a tree or commit, a ref that points to any\n> of the above, and so on.\n> \n> I think it is actually dying out from git documentation, though.  I was\n> writing to Junio there, who I know understands that term, but I should\n> have been more mindful that other readers of the thread wouldn't.\n\nHistorical note: \"tree-ish\" (now just \"tree\") were once called \"ents\" :-)\nc.f. 3f0073a (Axe the last ent, 2006-08-21)\n\n    Axe the last ent\n    \n    In the name of Standardization, this cleanses the last usage string of\n    mystical creatures.  But they still dwell deep within the source and in\n    some debug messages, it is said.\n\n> > Do you know of anything in the INDEX file that would not be visible\n> > from NEXT/WTREE/OURS/THEIRS?\n> \n> The stat information, but that is usually ignored in porcelain, anyway\n> (we refresh the state information at the beginning of most porcelain\n> commands, so you can just assume everything is up to date with the\n> working tree and will be shown as such).\n\nHmmm... there is additional complication that I haven't thought about,\nnamely assume-unchanged bit, and partial checkouts.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169825","messageId":"4DF150FB.9070304@alum.mit.edu","threadId":"27548","inReplyTo":"201106100004.58040.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-06-09T23:02:19Z","receivedAt":"2011-06-09T23:02:19Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 06/10/2011 12:04 AM, Jakub Narebski wrote:\n> On Thu, 9 Jan 2011, Michael Haggerty wrote:\n>> On 06/09/2011 10:04 PM, Jeff King wrote:\n>>> I'm less sure about these new tokens, for a few reasons:\n>>>\n>>>   1. You get less useful answers in some situations by treating each\n>>>      stage as a separate tree (e.g., lack of combined diff). So why\n>>>      would I want to use them?\n>>\n>> Wouldn't it be nice to be able to do a combined diff between *any* two\n>> trees?  Then the nonuniform merge behavior of \"git diff\" would be a\n>> special case of a general concept:\n>>\n>>     git diff3 OURS NEXT THEIRS\n>                 ^^^^^^^^^^^^^^^^ -- ???\n> \n> First, it is unnecessary power, unnecessary complication.  WTF. you are\n> doing comparing _abitrary_ trees?\n> \n> Second, for files with merge conflicts \"git diff\" is the same as\n> \"git diff3 OURS THEIRS WTREE\", not \"git diff3 OURS NEXT THEIRS\".\n> As you can see it is very easy to construct wrong options to git-diff,\n> and end up with nonsense!\n\nSince there is currently no \"git diff3\" command, I decided to orient the\nhypothetical \"git diff3\" command based on diff3(1), which uses\n\n    diff3 [OPTION]... MYFILE OLDFILE YOURFILE\n\nBy using a new command (diff3) that is somewhat familiar to some users,\nwe could reduce the amount of overloading of \"git diff\".  I, for one,\nwas surprised and confused the first few times I typed \"git diff\" during\na merge and got a three-way diff rather than what I expected, namely the\ntwo-way diff that is called \"git diff NEXT WTREE\" in the proposed notation.\n\n> I won't repear the THIRD time simple and around *three times shorter*\n> explanation on _when_ to use which form: \"git diff\" for your own remaining\n> changes that can be \"git add\"-ef, \"git diff --staged\" for which changes\n> are staged i.e. what you have \"git add\"-ed, and \"git diff HEAD\" to compare\n> current with last.\n\nYou don't need to repeat for my benefit the existing version of the\ncommands; I knew them long before this discussion started.  And\nrepeating them does not make them more obvious.\n\nFor a beginner, the main goal is not brevity.  It is discoverability and\nmemorability.  Obviously our priorities and tastes differ and we will\nnot come to agreement.  I would be very interested what people with a\nfresh memory of struggling to learn the git CLI think would have been\neasier to learn.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"169826","messageId":"BANLkTim7ZAGHO3a-G6cBwKjg4wKzskbVTg@mail.gmail.com","threadId":"27548","inReplyTo":"20110609223825.GA7771@sigill.intra.peff.net","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-10T00:00:12Z","receivedAt":"2011-06-10T00:00:12Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"On Thu, Jun 9, 2011 at 6:38 PM, Jeff King <peff@peff.net> wrote:\n> On Thu, Jun 09, 2011 at 06:27:11PM -0400, Michael Nahas wrote:\n>\n>> I dunno Michael, your idea sounds dangerous.\n>>\n>> You're saying that the user interface should be defined with concepts\n>> that have nothing to do with the plumbing.  That's crazy talk!  Next\n>> you'll be arguing that users don't need to know that the Index file\n>> has 4 stages!\n>>\n>> ;)\n>\n> I know you are being sarcastic, but it _is_ a dangerous thing. One of\n> the great things about git is that it exposes the details of its data\n> structures. So you rarely run into corner cases where the UI has given\n> you an inaccurate mental model, and you have to reconcile what is\n> actually happening with your mental model. The tradeoff, of course, is\n> that you get exposed to the full complexity of what is happening.\n>\n> And note that I'm not saying it's impossible, or it's something we\n> definitely shouldn't do. Only that we should be aware of what\n> inaccuracies we might be feeding to the user, and asking questions about\n> how that might bite is. Like: how likely is the user to run into a\n> corner case where git does something unexpected? If it does happen, how\n> much worse will explaining the behavior be than simply having exposed\n> them to lower-level constructs in the first place?\n>\n> Also note that I'm not even sure that this token proposal is in fact\n> introducing inaccuracies, and is not simply an alternate but equivalent\n> mental model. But these are the types of things I think people should be\n> thinking about in a proposal like this.\n\nThe beauty of building a level of abstraction is that you don't need\nto know about the lower level.  Git's plumbing is built on files, and\ndirectories, and communication libraries, but, in general, we don't\ntalk about manipulating the plumbing in those terms.  We talk in the\nconcepts of the higher level: commits, trees, branches, pushes, and\npulls.\n\nI don't know what are the right concepts are for the porcelain.  I\nhave a feeling that a lot of the concepts will map 1-to-1 will\nconcepts in the plumbing, which is what makes the two hard to\nseparate.  At the moment, the NEXT and HEAD concepts \"feel\" right.\nBut I also think they're just part of the solution.\n\nA partial step towards the right idea is not always a good thing.  It\ncould leave users confused or give them the power to create a mess but\nnot fix it.  We should be careful, but not fearful.\n\n\n>> Peff: \"... use tokens to describe non-treeish sources and destinations\"\n>> What is non-treeish about NEXT/WTREE/etc.?\n>\n> They don't resolve to git tree objects. :)\n\nTouchee'.\nActually, nice succinct definition.\n\nTree objects have SHAs and are long lasting.  Good differences to keep in mind.\n\n>> Do you know of anything in the INDEX file that would not be visible\n>> from NEXT/WTREE/OURS/THEIRS?\n>\n> The stat information, but that is usually ignored in porcelain, anyway\n> (we refresh the state information at the beginning of most porcelain\n> commands, so you can just assume everything is up to date with the\n> working tree and will be shown as such).\n\nI took a quick look at some documentation.  The index has almost all\nthe stats about a file that are directly available from a file in the\nworking tree.  It also looks like the index has far more stats than\ncan be stored in a tree object entry.  Is that right?\n\nMike\n"},{"id":"169827","messageId":"20110610000818.GA10872@sigill.intra.peff.net","threadId":"27548","inReplyTo":"BANLkTim7ZAGHO3a-G6cBwKjg4wKzskbVTg@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-10T00:08:19Z","receivedAt":"2011-06-10T00:08:19Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 09, 2011 at 08:00:12PM -0400, Michael Nahas wrote:\n\n> A partial step towards the right idea is not always a good thing.  It\n> could leave users confused or give them the power to create a mess but\n> not fix it.  We should be careful, but not fearful.\n\nYeah, that was what I was trying get at. We do need to be careful not to\nmake things worse.\n\n> I took a quick look at some documentation.  The index has almost all\n> the stats about a file that are directly available from a file in the\n> working tree.  It also looks like the index has far more stats than\n> can be stored in a tree object entry.  Is that right?\n\nYeah. The index does double duty by holding both the sha1 of what is at\neach stage, but also the stat cache for files in the worktree. That's\nwhat lets us avoid even opening unchanged files during a diff (we lstat\nthem and check the size, modification time, etc).\n\nIn general, that particular duty probably doesn't have a place in the UI\nfor porcelain. Most commands will transparently go through the cache,\nfind any stat-dirty entries, and actually open and check what's in the\nfile.\n\n-Peff\n"},{"id":"169838","messageId":"201106101219.18497.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DF150FB.9070304@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-10T10:19:17Z","receivedAt":"2011-06-10T10:19:17Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Fri, 10 Jun 2011, Michael Haggerty wrote:\n> On 06/10/2011 12:04 AM, Jakub Narebski wrote:\n>> On Thu, 9 Jan 2011, Michael Haggerty wrote:\n>>> On 06/09/2011 10:04 PM, Jeff King wrote:\n>>>> I'm less sure about these new tokens, for a few reasons:\n>>>>\n>>>>   1. You get less useful answers in some situations by treating each\n>>>>      stage as a separate tree (e.g., lack of combined diff). So why\n>>>>      would I want to use them?\n>>>\n>>> Wouldn't it be nice to be able to do a combined diff between *any* two\n>>> trees?  Then the nonuniform merge behavior of \"git diff\" would be a\n>>> special case of a general concept:\n>>>\n>>>     git diff3 OURS NEXT THEIRS\n>>                ^^^^^^^^^^^^^^^^ -- ???\n[...]\n\n>> Second, for files with merge conflicts \"git diff\" is the same as\n>> \"git diff3 OURS THEIRS WTREE\", not \"git diff3 OURS NEXT THEIRS\".\n>> As you can see it is very easy to construct wrong options to git-diff,\n>> and end up with nonsense!\n> \n> Since there is currently no \"git diff3\" command, I decided to orient the\n> hypothetical \"git diff3\" command based on diff3(1), which uses\n> \n>     diff3 [OPTION]... MYFILE OLDFILE YOURFILE\n> \n> By using a new command (diff3) that is somewhat familiar to some users,\n> we could reduce the amount of overloading of \"git diff\".\n\nBut here, by using \"git diff3\" which does not work at all like diff3, and\nwhich output is very different from \"git diff --cc\" combined diff format,\nyou increase confusion, not decrease it.  By using somewhat familiar name\nthat behaves differently from said familiar tool, you make user's life\nunnecessary harder.\n\nLet me explain how \"git diff --cc\" is diferent from \"diff3\".\n\nFirst, \"git diff --cc\" works differently than \"diff3\";\n\n * \"git diff --cc\" can do combined diff of arbitrary number of 3 things\n   or more; \"diff3\" is limited to 3.\n\n * \"git diff --cc\" is about comparing merge results with its sources\n   (parents) and the like; \"diff3\" is about comparing two divergent\n   versions with their ancestor (merge base) -- opposite direction of\n   following parent links.\n\n * therefore natural ordering for \"git diff --cc\" is 'PARENT^1 PARENT^2\n   MERGE' (like 'FROM TO'), while \"diff3\" uses arbitrary ordering of\n   'MYFILE OLDFILE YOURFILE'... which I always have to check in docs.\n\nSecond, \"diff3\" output is different from \"git diff --cc\" output... and\nas you see above rightly so.\n\nThird, it was still a mistake to write\n\n  git diff3 OURS NEXT THEIRS\n\nIn result of combined diff that \"git diff\" shows in case of merge conflict\ndifferences between OURS, THEIRS, and WTREE version; NEXT isn't there,\nand you didn't mention WTREE though it is here.  But see also the next point.\n\nFourth, with \"git diff3 OURS NEXT THEIRS\" / \"git diff3 OURS THEIRS WTREE\"\nyou either introduce interface inefficiency, or UI inconsistency, or UI\ncomplication.\n\nIn the case of conflict \"git diff\" shows 3-way combined diff for files\nwith conflict (OURS, THEIRS, WTREE), but it shows ordinary diff from\nstage '0' (NEXT, WTREE) for files which resolved cleanly; the fact that\nfile resolved cleanly doesn't necessarily mean that it resolved correctly...\n\nSo you either make \"git diff3 OURS NEXT THEIRS\" show only 3-way combined\ndiff part, consistent with 'diff3' name, but making for an *inefficient*\nuser interface -- now you have to use two commands for single piece of\ninformation.\n\nOr you make \"git diff3 OURS NEXT THEIRS\" behave like current \"git diff\",\ni.e. show the whole diff from index, be it conflict or a fixup, which is\nefficient but *inconsistent*.\n\nOr you make \"git diff3 OURS NEXT THEIRS\" compare stage 0 (NEXT?) with\nworktree if there is no conflict, and stages 'ours' and 'theirs' with\nworktree if there is conflict... which is *weird*, especially that you\ndefined OURS as \"'ours' or stage 0\" (union of stage 'ours' and stage 0),\ncovering all resolved and unresolved files.\n\n> I, for one, \n> was surprised and confused the first few times I typed \"git diff\" during\n> a merge and got a three-way diff rather than what I expected, namely the\n> two-way diff that is called \"git diff NEXT WTREE\" in the proposed notation.\n\nThis three way diff is more useful...\n \n>> I won't repear the THIRD time simple and around *three times shorter*\n>> explanation on _when_ to use which form: \"git diff\" for your own remaining\n>> changes that can be \"git add\"-ef, \"git diff --staged\" for which changes\n>> are staged i.e. what you have \"git add\"-ed, and \"git diff HEAD\" to compare\n>> current with last.\n> \n> You don't need to repeat for my benefit the existing version of the\n> commands; I knew them long before this discussion started.  And\n> repeating them does not make them more obvious.\n> \n> For a beginner, the main goal is not brevity.  It is discoverability and\n> memorability.  Obviously our priorities and tastes differ and we will\n> not come to agreement.  I would be very interested what people with a\n> fresh memory of struggling to learn the git CLI think would have been\n> easier to learn.\n\nYou say that user would think something like that:\n\n  \"I need to compare staged contents and working area.  To do that I use\n   'git diff NEXT WTREE' / have to look up documentation to find that it\n   is 'git diff'\".\n\nI say that I guess user would think something like that:\n\n  \"I want to check if and what remaining changes are.  To do that I use\n   'git diff' / have to look up documentation which stages I have to\n   compare to find that it is 'git diff NEXT WTREE'\".\n\n'git diff' / 'git diff --cached' / 'git diff HEAD' is about use cases\n(or \"user stories\").  'git diff NEXT WTREE' / 'git diff HEAD NEXT' /\n/ 'git diff HEAD WTREE' are about mechanism.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169840","messageId":"BANLkTikHkTHP7eJ=_wPosi7yj4BX=c1gaA@mail.gmail.com","threadId":"27548","inReplyTo":"201106101219.18497.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-10T11:06:02Z","receivedAt":"2011-06-10T11:06:02Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"> 'git diff' / 'git diff --cached' / 'git diff HEAD' is about use cases\n> (or \"user stories\").  'git diff NEXT WTREE' / 'git diff HEAD NEXT' /\n> / 'git diff HEAD WTREE' are about mechanism.\n\nWould you say that the UNIX commands \"find\", \"grep\", and \"xargs\" are\nabout use cases?  I rarely use them by themselves.  They clearly\nmanipulate concepts: files and lines.  So, it's easy for me to think\nwhat this does:\n\nfind . | grep \"\\.h\" | xargs grep MyClass | grep public\n\nI'm trying to find concepts the concepts that git manipulates and I\nthink NEXT and WTREE are part of those concepts.\n\nIt is my opinion that if we focus on concepts, we'll be able to create\ngeneral commands and that the user will be able to combine the\ncommands in new and interesting ways, like I combined the UNIX\ncommands above.\n\nI believe in \"common\" use cases.  The common case should be fast.  I\nhave always recommended still allowing \"git diff\" by itself.\n\n\nBUT if we focus only on use cases, we'll create tools that are\nspecific to ONE thing and are NOT general.  They will be harder for\nusers to conceptualize and harder to combine in new and interesting\nways.\n"},{"id":"169842","messageId":"201106101420.12892.jnareb@gmail.com","threadId":"27548","inReplyTo":"BANLkTikHkTHP7eJ=_wPosi7yj4BX=c1gaA@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-10T12:20:12Z","receivedAt":"2011-06-10T12:20:12Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Fri, 10 Jul 2011, Michael Nahas wrote:\n> Jakub Narebski wrote:\n\n> > 'git diff' / 'git diff --cached' / 'git diff HEAD' is about use cases\n> > (or \"user stories\").  'git diff NEXT WTREE' / 'git diff HEAD NEXT' /\n> > / 'git diff HEAD WTREE' are about mechanism.\n> \n> Would you say that the UNIX commands \"find\", \"grep\", and \"xargs\" are\n> about use cases?  I rarely use them by themselves.  They clearly\n> manipulate concepts: files and lines.  So, it's easy for me to think\n> what this does:\n> \n> find . | grep \"\\.h\" | xargs grep MyClass | grep public\n\nYou do know that this is way suboptimal, even if you don't have 'ack'\ninstalled, and don't use \"git grep --no-index\"?\n\n> \n> I'm trying to find concepts the concepts that git manipulates and I\n> think NEXT and WTREE are part of those concepts.\n> \n> It is my opinion that if we focus on concepts, we'll be able to create\n> general commands and that the user will be able to combine the\n> commands in new and interesting ways, like I combined the UNIX\n> commands above.\n> \n> I believe in \"common\" use cases.  The common case should be fast.  I\n> have always recommended still allowing \"git diff\" by itself.\n> \n> \n> BUT if we focus only on use cases, we'll create tools that are\n> specific to ONE thing and are NOT general.  They will be harder for\n> users to conceptualize and harder to combine in new and interesting\n> ways.\n\nBut if it is the angle you want to play, then don't advertise it as\na feature meant for _new users_!  But if you go that route (e.g. as a way\nto compare BASE with THEIRS, for whatever reason), then you probably\nwould need to invent some notation that is obvious that these are not\nrefs, like HEAD, ORIG_HEAD, MERGE_HEAD and FETCH_HEAD are.  Something\nthat is easy to remember, won't go in the way of either git or shell;\nsee e.g.\n\n  http://thread.gmane.org/gmane.comp.version-control.git/175262/focus=175407\n\nin \"[RFC/PATCH] git put: an alternative to add/reset/checkout\" thread.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169846","messageId":"201106101729.34270.jnareb@gmail.com","threadId":"27548","inReplyTo":"BANLkTikamzsiSJqkRjA7nDjRoyEbd32rvw@mail.gmail.com","subject":"Re: Command-line interface thoughts (ad-hominem attacks)","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-10T15:29:32Z","receivedAt":"2011-06-10T15:29:32Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 9 Jun 2011, Michael Nahas wrote:\n\n> Hi Peff,\n> \n> First, thanks for correcting my diff-without-NEXT-and-WTREE to\n> diff-with-NEXT-and-WTREE pairing.\n> \n> Second, I agree that the index is more than just NEXT.  There were\n> good reasons behind calling it \"NEXT\" and not \"INDEX\".\n\nNEXT has to be _well defined_ (is it tree-ish or a multi-tree in some \ncases), and definition examined if it is _useful_ (e.g. if you can get\nresults of \"git diff\" with \"git diff NEXT <sth>...\" both for conflicted \nand resolved cleanly entries).\n \nThis thread served to specify original handwavy definition of NEXT...\n\n> Third, I didn't know for sure that \"git diff\" during a merge conflict\n> would produce a three-way-diff result, but I suspected it would.  (You\n> really didn't have to produce all that code - I would have accepted\n> your word as an expert.  But thanks!)  So, yes, the two-way merge\n> result of \"git diff NEXT WTREE\" would be different.\n> \n> I could argue that git should allow a 4-way diff where \"git diff NEXT\n> WTREE OURS THEIR\" prints all the unresolved changes as coming from\n> OURS or THEIR or neither.  But I think that's silly.\n\nIt would be \"git diff NEXT OURS THEIRS WTREE\" or \"git diff BASE OURS \nTHEIRS WTREE\" -- the putative merge results should be last; the \nconvention of combined diff format is like for ordinary diff: first \nsource(s), then destination.\n\n> \n> I will say that \"git diff NEXT WTREE\" will tell you what's left\n> unresolved and most of it is in <<<<====>>>>> blocks that tell you\n> whether it came from OURS or THEIRS.  If the user has any discipline,\n> they won't introduce unnecessary changes that were not necessary for\n> the merge.  If they don't have discipline, we really can't help them.\n\nWhat if he/she removed conflict markers, test compiled... and realized\nthat it was mismerge, then fixed?  Then to examine current fixed \ncontents he/she doesn't have help of <<<< ==== >>>> blocks...\n\n> \n> I'm not saying there is no use for a 3-way merge.  In fact, I'd guess\n> it's a requirement so that Alice can check Bob's merge before Bob\n> commits.  But I'm fine with making it \"git diff --3-way\" or the silly\n> \"git diff NEXT WTREE OURS THEIRS\" because I think its \"git diff NEXT\n> WTREE\" will be good enough 99% of the time.\n\n\"git diff --cc\".  But I think with having to say explicitly \n\"git diff --3way\" / \"git diff --cc\" Alice wouldn't know that it has such \nuseful tool...\n\n\nP.S. Could you not quote text in bulk, if you are not answering to it \nblock by block?  It is unnecessary download, and burden of scrolling \ndown to check if there is anything added at bottom.\n-- \nJakub Narebski\nPoland\n"},{"id":"169847","messageId":"201106101844.16146.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DF0B4B2.7080007@ira.uka.de","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-10T16:44:14Z","receivedAt":"2011-06-10T16:44:14Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 9 Jun 2011, Holger Hellmuth wrote:\n> On 08.06.2011 20:56, Jakub Narebski wrote:\n\n[...]\n> >> But I can't make it explicit which two targets I want to compare with\n> >> 'git diff'.\n> >\n> > For me it looks XY problem; instead of wanting to compare two explicit\n> > targets, you should specify what you want to see ;-).\n> \n> Then don't call the command 'diff' (... I proclaim in the knowledge that \n> that isn't possible). 'diff' is the short form of 'difference' which \n> means literally a comparison between *two* things.\n\nBlame CVS (I think) on that.  It introduced no arguments \"cvs diff\" to\nget current changes, and other version control systems picked this\nconvention up, including Git.\n \n\"diff\" is 'are there any differences', or 'are there any changes'.\nImplicit rules (targets) are very useful.\n\n> If someone wants to \n> see something he would pick the words 'show' or 'list'. So user \n> expectation is different from what you want diff to be.\n\nThere is always \"git status\"...\n\n> Also there are no good words for what someone wants to see in this case. \n> At least I would assume the git project would have found them if they \n> existed. '--cached' is definitely not one of them. But we have fitting \n> and widely known names for the targets, i.e 'working tree', 'index' and \n> 'head'.\n\n\"I want to see if there are any remiaining changes\", \"I want to see what\n'git commit' would bring\", \"I want to see what 'git commit -a' would bring\".\nNeither of those is about targets for diff.\n\n[...]\n> > The \"git diff NEXT WTREE\" looks like training wheels to me.  And like\n> > training wheels they could become obstacles and not help to learning\n> > git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))\n> \n> If your goal is that anyone who uses git is a git expert, they may be a \n> hindrance (as are all the porcelain commands really). If you also want \n> to make git friendly to people who will never get past intermediate or \n> beginner stage or will only use a small part of git or use git seldomly, \n> training wheels are good.\n\nThose \"training wheels\" are useless for beginner, and might be not very\nuseful to middle expert user either, depending on corner cases.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169849","messageId":"4DF25D50.5020107@ira.uka.de","threadId":"27548","inReplyTo":"201106101844.16146.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Holger Hellmuth","fromEmail":"hellmuth@ira.uka.de","sentAt":"2011-06-10T18:07:12Z","receivedAt":"2011-06-10T18:07:12Z","isPatch":false,"sender":{"key":"hellmuth@ira.uka.de","avatar":null},"body":"On 10.06.2011 18:44, Jakub Narebski wrote:\n> On Thu, 9 Jun 2011, Holger Hellmuth wrote:\n>> Also there are no good words for what someone wants to see in this case.\n>> At least I would assume the git project would have found them if they\n>> existed. '--cached' is definitely not one of them. But we have fitting\n>> and widely known names for the targets, i.e 'working tree', 'index' and\n>> 'head'.\n>\n> \"I want to see if there are any remiaining changes\", \"I want to see what\n> 'git commit' would bring\", \"I want to see what 'git commit -a' would bring\".\n> Neither of those is about targets for diff.\n\nAre you proposing a command \"git \n--I-want-to-see-if-there-are-any-remaining-changes\" ? ;-). I was looking \nfor short command or parameter names that are easy to remember, not for \ndefinitions of the output of cryptic commands.\n\nBut lets see. If I didn't know much git, where would I look for the \nright command for your three needs? Where would I expect the solution? \n(note I'm not proposing any of these commands)\n\n\"I want to see if there are any remiaining changes\"?\ngit status\ngit status --full\ngit status --detailed\n\n\"I want to see what 'git commit' would bring\"\ngit commit --dry-run\n\n\"I want to see what 'git commit -a' would bring\"\ngit commit -a --dry-run\n\nNow I'll add a question I would want to ask:\n\"I want to see the changes between what I have in my working tree and \nwhat I already added to the index\"\ngit diff WTREE INDEX\n\n\nBtw. even the 'git diff' man page emphasizes that diff is about a \ncomparision between two things. Citation: \"Show changes *between* two \ntrees, a tree and the working tree, a tree and the index file,...\".\n\n\n> [...]\n>>> The \"git diff NEXT WTREE\" looks like training wheels to me.  And like\n>>> training wheels they could become obstacles and not help to learning\n>>> git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))\n>>\n>> If your goal is that anyone who uses git is a git expert, they may be a\n>> hindrance (as are all the porcelain commands really). If you also want\n>> to make git friendly to people who will never get past intermediate or\n>> beginner stage or will only use a small part of git or use git seldomly,\n>> training wheels are good.\n>\n> Those \"training wheels\" are useless for beginner, and might be not very\n> useful to middle expert user either, depending on corner cases.\n\n\"useless for beginner\". No reasoning, just a fat road block for my opinion?\nAs git expert you are so far removed from any beginner status. Are you \nsure you still know how a beginner thinks?\n\nHolger.\n"},{"id":"169850","messageId":"201106102035.42525.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DF25D50.5020107@ira.uka.de","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-10T18:35:41Z","receivedAt":"2011-06-10T18:35:41Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Dnia piątek 10. czerwca 2011 20:07, Holger Hellmuth napisał:\n> On 10.06.2011 18:44, Jakub Narebski wrote:\n> > On Thu, 9 Jun 2011, Holger Hellmuth wrote:\n> >> Also there are no good words for what someone wants to see in this case.\n> >> At least I would assume the git project would have found them if they\n> >> existed. '--cached' is definitely not one of them. But we have fitting\n> >> and widely known names for the targets, i.e 'working tree', 'index' and\n> >> 'head'.\n> >\n> > \"I want to see if there are any remiaining changes\", \"I want to see what\n> > 'git commit' would bring\", \"I want to see what 'git commit -a' would bring\".\n> > Neither of those is about targets for diff.\n> \n> Are you proposing a command \"git \n> --I-want-to-see-if-there-are-any-remaining-changes\" ? ;-). I was looking \n> for short command or parameter names that are easy to remember, not for \n> definitions of the output of cryptic commands.\n> \n> But lets see. If I didn't know much git, where would I look for the \n> right command for your three needs? Where would I expect the solution? \n> (note I'm not proposing any of these commands)\n> \n> \"I want to see if there are any remaining changes\"?\n> git status\n> git status --full\n> git status --detailed\n\n\"Any differences\"?\n\ngit diff\n\n\n\"I want to see what I staged\"\n\ngit diff --staged\n\n\nIsn't it simpler than \"I want to see the changes between what I already\nstaged, which is put in place called index, but must refer to it by NEXT,\nand the changes I didn't staged, in my working area, which I refer to by\nWORK... no, it is TREE... oh, wait, it is WTREE\" :-)  I am exaggerating\nmuch here, but I think you can see what I want to point out.\n\n> Now I'll add a question I would want to ask:\n> \"I want to see the changes between what I have in my working tree and \n> what I already added to the index\"\n\nThat's not a beginner question.\n\n> git diff WTREE INDEX\n           ^^^^^^^^^^^ --- reverse to \"git diff\"\n\nIn this direction it is surely suprising... you see, how again and again\nhaving to explicitely state what to compare with which leads to mistakes\nsuch like this one, and the one in few mails earlier.\n \n> \n> Btw. even the 'git diff' man page emphasizes that diff is about a \n> comparision between two things. Citation: \"Show changes *between* two \n> trees, a tree and the working tree, a tree and the index file,...\".\n \nThat's more about explaining result of command.  Besides manpages are\nreference documentation; new users should start with user's manual, or\ntutorial (or \"Pro Git\"), not manpages.\n \n> > [...]\n> >>> The \"git diff NEXT WTREE\" looks like training wheels to me.  And like\n> >>> training wheels they could become obstacles and not help to learning\n> >>> git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))\n> >>\n> >> If your goal is that anyone who uses git is a git expert, they may be a\n> >> hindrance (as are all the porcelain commands really). If you also want\n> >> to make git friendly to people who will never get past intermediate or\n> >> beginner stage or will only use a small part of git or use git seldomly,\n> >> training wheels are good.\n> >\n> > Those \"training wheels\" are useless for beginner, and might be not very\n> > useful to middle expert user either, depending on corner cases.\n> \n> \"useless for beginner\". No reasoning, just a fat road block for my opinion?\n> As git expert you are so far removed from any beginner status. Are you \n> sure you still know how a beginner thinks?\n\nWell, that depends by what you mean by beginner.  Beginner to git, but\nnot beginner to version control knows about \"<scm> diff\" form to check\nfor one's changes, for example.\n\nBut I don't think that beginner knows that there is such thing like the\nindex, and know that he/she has to compare the index to the working area.\nWhen he/she starts to use the index, probably he/she isn't a beginner\nanymore.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169864","messageId":"7v4o3xwe5z.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"20110609200403.GA3955@sigill.intra.peff.net","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-10T21:48:56Z","receivedAt":"2011-06-10T21:48:56Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I think there are actually two questions here:\n>\n>   1. Will it be easier for people to understand \"git diff\" if we use\n>      tokens to describe non-treeish sources and destinations?\n>\n>   2. Are there better tokens to use to break down parts of the index?\n>\n> I don't have a big problem with (1). Allowing things like:\n>\n>   git diff INDEX WTREE\n>\n> allows one to explain what is going on with the diff syntax in a very\n> clear and verbose manner. I wouldn't want to type that every day, but\n> that's OK; \"git diff\" will always mean the same thing as it always has,\n> but can now be explained to people who have trouble seeing it in terms\n> of \"git diff INDEX WTREE\".\n>\n> There's still a bit of magic in that INDEX is _not_ a tree, but I think\n> that's a good thing. When there are no merge conflicts, it will behave\n> identically to the proposed NEXT tree. And when there are conflicts, it\n> will show you something even more useful.\n\nThanks. This is exactly why I love to have people like you on the list,\nwho can say what I wanted to say in a matter that is a lot easier to\nunderstand.\n\nIn short, the proposed \"NEXT\" does not help in a situation with conflicts,\nand makes the user experience worse. In order to get the current power of\n\"git diff\" with various options that are specifically designed to help\nusers to make progress (either working on their own changes, rebasing them\non top of others, or merging other's work in), people _COULD_ introduce\nBASE/OURS/THEIRS in addition to \"NEXT\", throw the existing HEAD and\nMERGE_HEAD to the mix, derive the same information by spending mental\neffort to choose between which pairs of two entities among these six\npossibilities and take pairwise diffs among those pairs, and combine the\nresults of these diffs (the message I responded to with \"is that a useful\nquestion\" was an example of that---\"Could we pile more kludge on top of\nNEXT to have expressiveness equivalent to what the current index-based\nsystem offers?\"). Yes, that may be possible, but is there a point in\nmaking users go through that kind of mental contortion by introducing\nthese new tokens? I find it highly doubtful that it would help new people\nunderstand the situation during conflicted merges.\n\n>   git show INDEX:OURS:Makefile\n>\n> which is identical to what I wrote above, but is perhaps easier to\n> explain.\n\nWhy does anybody even want to say :2:Makefile to begin with?\n\nPresumably, you are dealing with a merge conflict at that path and trying\nto see how pre-merge version of Makefile looked like, and then the next\nthing you may want to do is how pre-merge version of their Makefile looked\nlike.\n\nWouldn't it be far more natural to ask for these instead?\n\n    git show HEAD:Makefile\n    git show MERGE_HEAD:Makefile\n\nI do not think whoever brought that \"you can look at individual stages\nwith :$n:$path\" to this discussion was thinking straight. Yes, it is\nsomething you _could_ do, I've never found that particularly _useful_\nunless I was debugging git itself.\n"},{"id":"169865","messageId":"7vzklpuyp3.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"7v4o3xwe5z.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-10T22:08:24Z","receivedAt":"2011-06-10T22:08:24Z","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> Thanks. This is exactly why I love to have people like you on the list,\n> who can say what I wanted to say in a matter that is a lot easier to\n> understand.\n\ns/matter/manner/; of course.  Sorry for a silly typo and noise.\n"},{"id":"169867","messageId":"4DF29EA5.60502@ira.uka.de","threadId":"27548","inReplyTo":"201106102035.42525.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Holger Hellmuth","fromEmail":"hellmuth@ira.uka.de","sentAt":"2011-06-10T22:45:57Z","receivedAt":"2011-06-10T22:45:57Z","isPatch":false,"sender":{"key":"hellmuth@ira.uka.de","avatar":null},"body":"Am 10.06.2011 20:35, schrieb Jakub Narebski:\n> Dnia piątek 10. czerwca 2011 20:07, Holger Hellmuth napisał:\n>> On 10.06.2011 18:44, Jakub Narebski wrote:\n>>> On Thu, 9 Jun 2011, Holger Hellmuth wrote:\n>>>> Also there are no good words for what someone wants to see in this case.\n>>>> At least I would assume the git project would have found them if they\n>>>> existed. '--cached' is definitely not one of them. But we have fitting\n>>>> and widely known names for the targets, i.e 'working tree', 'index' and\n>>>> 'head'.\n>>>\n>>> \"I want to see if there are any remiaining changes\", \"I want to see what\n>>> 'git commit' would bring\", \"I want to see what 'git commit -a' would bring\".\n>>> Neither of those is about targets for diff.\n>>\n>> Are you proposing a command \"git \n>> --I-want-to-see-if-there-are-any-remaining-changes\" ? ;-). I was looking \n>> for short command or parameter names that are easy to remember, not for \n>> definitions of the output of cryptic commands.\n>>\n>> But lets see. If I didn't know much git, where would I look for the \n>> right command for your three needs? Where would I expect the solution? \n>> (note I'm not proposing any of these commands)\n>>\n>> \"I want to see if there are any remaining changes\"?\n>> git status\n>> git status --full\n>> git status --detailed\n> \n> \"Any differences\"?\n> \n> git diff\n\nBut difference to what --> User checks man page, again.\n\n> \n> \n> \"I want to see what I staged\"\n> \n> git diff --staged\n> \n\nUser never heard of 'staged'. He asks instead \"I want to see what I\nadded\" --> git diff --added --> Error Message --> User checks man page,\nagain\n\n> \n> Isn't it simpler than \"I want to see the changes between what I already\n> staged, which is put in place called index, but must refer to it by NEXT,\n> and the changes I didn't staged, in my working area, which I refer to by\n> WORK... no, it is TREE... oh, wait, it is WTREE\" :-)  I am exaggerating\n> much here, but I think you can see what I want to point out.\n\nSure. I'm not a fan of 'NEXT' either. I would use INDEX. Or even index\nif that doesn't clash with anything. WTREE as well is not optimal but it\nis something you can get at as soon as you remember the term 'working\ntree'. And you know what you will get without consulting the manuals if\nyou are unsure.\n\n>> Now I'll add a question I would want to ask:\n>> \"I want to see the changes between what I have in my working tree and \n>> what I already added to the index\"\n> \n> That's not a beginner question.\n\nOk, I had a different definition of beginner, especially since I and all\nthe git-user I know at my work place used the index from the beginning.\nThe index is a wonderful idea but it isn't that hard to understand. If\nyou look at the gittutorial man page (and any of the other 3 top\ntutorials in google) 3 of those 4 tutorials talk about the index and git\nadd, only one uses 'git commit -a' instead.\n\nOnly one mentions 'git diff --cached' by the way, seems to be an\nadvanced topic ;-)\n\n\n>> git diff WTREE INDEX\n>            ^^^^^^^^^^^ --- reverse to \"git diff\"\n> \n> In this direction it is surely suprising... you see, how again and again\n> having to explicitely state what to compare with which leads to mistakes\n> such like this one, and the one in few mails earlier.\n\nI'm a sloopy person as you have noticed. Also very forgetful. I usually\ndon't bother with the order of 'diff' parameters when I can get the\ndirection from the diff output.\n\n>>\n>> Btw. even the 'git diff' man page emphasizes that diff is about a \n>> comparision between two things. Citation: \"Show changes *between* two \n>> trees, a tree and the working tree, a tree and the index file,...\".\n>  \n> That's more about explaining result of command.  Besides manpages are\n> reference documentation; new users should start with user's manual, or\n> tutorial (or \"Pro Git\"), not manpages.\n\nOk, so lets look at 'Pro Git'. Besides using your description it is also\ntalking about comparision between working area and staging area and\ncomparing staged changes to last commit.\n\n> Well, that depends by what you mean by beginner.  Beginner to git, but\n> not beginner to version control knows about \"<scm> diff\" form to check\n> for one's changes, for example.\n> \n> But I don't think that beginner knows that there is such thing like the\n> index, and know that he/she has to compare the index to the working area.\n> When he/she starts to use the index, probably he/she isn't a beginner\n> anymore.\n\nLearning git is not a role playing game where you have to master level 1\nbefore you can use all the tricks of level 2 ;-). But any which way we\ncall them there are a lot of users using git with index and all, but who\nhave to search in the docs whenever they want to do something like\nunadding something from the index.\n\nSmall things like 'git unadd', Jeff Kings 'git put' and git diff with\ntargets probably would help this casual/intermediate/advanced user (take\nyour pick).\n\nHolger.\n"},{"id":"169869","messageId":"201106110105.08715.jnareb@gmail.com","threadId":"27548","inReplyTo":"7v4o3xwe5z.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-10T23:05:07Z","receivedAt":"2011-06-10T23:05:07Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Fri, 10 Jun 2011, Junio C Hamano wrote:\n\nI'll be there advocatus diaboli for some things.\n\n> Jeff King <peff@peff.net> writes:\n> \n> > I think there are actually two questions here:\n> >\n> >   1. Will it be easier for people to understand \"git diff\" if we use\n> >      tokens to describe non-treeish sources and destinations?\n> >\n> >   2. Are there better tokens to use to break down parts of the index?\n> >\n> > I don't have a big problem with (1). Allowing things like:\n> >\n> >   git diff INDEX WTREE\n> >\n> > allows one to explain what is going on with the diff syntax in a very\n> > clear and verbose manner. I wouldn't want to type that every day, but\n> > that's OK; \"git diff\" will always mean the same thing as it always has,\n> > but can now be explained to people who have trouble seeing it in terms\n> > of \"git diff INDEX WTREE\".\n> >\n> > There's still a bit of magic in that INDEX is _not_ a tree, but I think\n> > that's a good thing. When there are no merge conflicts, it will behave\n> > identically to the proposed NEXT tree. And when there are conflicts, it\n> > will show you something even more useful.\n> \n> Thanks. This is exactly why I love to have people like you on the list,\n> who can say what I wanted to say in a manner that is a lot easier to\n> understand.\n> \n> In short, the proposed \"NEXT\" does not help in a situation with conflicts,\n> and makes the user experience worse.\n\nWhich proposed NEXT?  I'm asking because there were many proposals from\nmany people, some contradictory.\n\nOne proposal was, if I understand it correctly, to have NEXT actually be\nSTAGE, i.e. be multi-tree like current index is in the case of merge\nconflicts.  This means that NEXT = \\Sum stage_0 + (stage_ours + stage_theirs\n+ stage_base). \n\n> In order to get the current power of \n> \"git diff\" with various options that are specifically designed to help\n> users to make progress (either working on their own changes, rebasing them\n> on top of others, or merging other's work in), people _COULD_ introduce\n> BASE/OURS/THEIRS in addition to \"NEXT\", throw the existing HEAD and\n> MERGE_HEAD to the mix, derive the same information by spending mental\n> effort to choose between which pairs of two entities among these six\n> possibilities and take pairwise diffs among those pairs,\n\nAnd find which direction makes more sense \"diff A B\" or \"diff B A\".\n\"git diff\" / \"git diff --staged\" / \"git diff HEAD\" use direction that\nmakes most sense.\n\n> and combine the \n> results of these diffs (the message I responded to with \"is that a useful\n> question\" was an example of that---\"Could we pile more kludge on top of\n> NEXT to have expressiveness equivalent to what the current index-based\n> system offers?\"). Yes, that may be possible, but is there a point in\n> making users go through that kind of mental contortion by introducing\n> these new tokens? I find it highly doubtful that it would help new people\n> understand the situation during conflicted merges.\n> \n> >   git show INDEX:OURS:Makefile\n> >\n> > which is identical to what I wrote above, but is perhaps easier to\n> > explain.\n> \n> Why does anybody even want to say :2:Makefile to begin with?\n> \n> Presumably, you are dealing with a merge conflict at that path and trying\n> to see how pre-merge version of Makefile looked like, and then the next\n> thing you may want to do is how pre-merge version of their Makefile looked\n> like.\n> \n> Wouldn't it be far more natural to ask for these instead?\n> \n>     git show HEAD:Makefile\n>     git show MERGE_HEAD:Makefile\n> \n> I do not think whoever brought that \"you can look at individual stages\n> with :$n:$path\" to this discussion was thinking straight. Yes, it is\n> something you _could_ do, I've never found that particularly _useful_\n> unless I was debugging git itself.\n\nActually there are cases when you don't have MERGE_HEAD, namely:\n\n * \"git merge --squash\"\n * \"git rebase\" and \"git rebase --interactive\", and \"git cherry-pick\"\n * \"git am --3way\"\n\nNote that OURS/THEIRS/BASE/WTREE has more power: currently there is no way\nas far as I know to compare stages 2 and 3 directly (\"git diff :2: :3:\"\ndidn't work, though this might be fiexed in newer git), or stage and base.\n\nThough I am not sure if anybody would want this.\n-- \nJakub Narebski\nPoland\n"},{"id":"169886","messageId":"4DF45769.4020403@alum.mit.edu","threadId":"27548","inReplyTo":"7v4o3xwe5z.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-06-12T06:06:33Z","receivedAt":"2011-06-12T06:06:33Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 06/10/2011 11:48 PM, Junio C Hamano wrote:\n> In short, the proposed \"NEXT\" does not help in a situation with conflicts,\n> and makes the user experience worse.\n\nThe idea of \"NEXT\" and its friends would indeed be marginal if it only\napplied to \"git diff\".  The real gain in learnability comes from using\nthe same idioms in other commands where they make sense; for example,\n\n    # More consistent alternative to the special \"--ours\" option:\n    git checkout OURS -- Makefile\n\n    # This would add more completeness to the\n    # \"git checkout <tree-ish> -- PATH\" command, and would remain the\n    # default if no <tree-ish> is specified:\n    git checkout NEXT -- Makefile\n\n    # I had to look up the current way to spell this\n    # (\"git show :Makefile\"), but this variant would be obvious\n    # by analogy with the other uses of NEXT:\n    git show NEXT:Makefile\n\nand of course also in the proposed \"git put\" command.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"169895","messageId":"BANLkTin_NYZ39s7gXbVrbAZU=+fzRCHdcA@mail.gmail.com","threadId":"27548","inReplyTo":"7v4o3xwe5z.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-12T13:30:13Z","receivedAt":"2011-06-12T13:30:13Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"I'm going to accept Junio's reply at a sign to withdraw.\n\nIt is clear that implementing NEXT/WTREE will worsen the performance\nof some commands (\"git diff\" under merge conflict).  I can accept that\nthe community does not want to give up performance to include an\nincomplete idea that offers no quantifiable improvement.\n\n\nI agree with Haggerty that the value of NEXT and WTREE to the user\nwill be seen when they are used in multiple commands.  That is, when\nthey are part of a collection of porcelain-level concepts that the\nuser can work with.\n\nI'm going to start a discussion on those porcelain-level concepts.  I\ndon't think this mailing list is the right forum for it.  If you wish\nto be a part of the discussion, please email me.\n\nIf the discussion produces something of value, I look forward to\nreturning and presenting it to the mailing list.\n\nMike\n\n\nOn Fri, Jun 10, 2011 at 5:48 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jeff King <peff@peff.net> writes:\n>\n>> I think there are actually two questions here:\n>>\n>>   1. Will it be easier for people to understand \"git diff\" if we use\n>>      tokens to describe non-treeish sources and destinations?\n>>\n>>   2. Are there better tokens to use to break down parts of the index?\n>>\n>> I don't have a big problem with (1). Allowing things like:\n>>\n>>   git diff INDEX WTREE\n>>\n>> allows one to explain what is going on with the diff syntax in a very\n>> clear and verbose manner. I wouldn't want to type that every day, but\n>> that's OK; \"git diff\" will always mean the same thing as it always has,\n>> but can now be explained to people who have trouble seeing it in terms\n>> of \"git diff INDEX WTREE\".\n>>\n>> There's still a bit of magic in that INDEX is _not_ a tree, but I think\n>> that's a good thing. When there are no merge conflicts, it will behave\n>> identically to the proposed NEXT tree. And when there are conflicts, it\n>> will show you something even more useful.\n>\n> Thanks. This is exactly why I love to have people like you on the list,\n> who can say what I wanted to say in a matter that is a lot easier to\n> understand.\n>\n> In short, the proposed \"NEXT\" does not help in a situation with conflicts,\n> and makes the user experience worse. In order to get the current power of\n> \"git diff\" with various options that are specifically designed to help\n> users to make progress (either working on their own changes, rebasing them\n> on top of others, or merging other's work in), people _COULD_ introduce\n> BASE/OURS/THEIRS in addition to \"NEXT\", throw the existing HEAD and\n> MERGE_HEAD to the mix, derive the same information by spending mental\n> effort to choose between which pairs of two entities among these six\n> possibilities and take pairwise diffs among those pairs, and combine the\n> results of these diffs (the message I responded to with \"is that a useful\n> question\" was an example of that---\"Could we pile more kludge on top of\n> NEXT to have expressiveness equivalent to what the current index-based\n> system offers?\"). Yes, that may be possible, but is there a point in\n> making users go through that kind of mental contortion by introducing\n> these new tokens? I find it highly doubtful that it would help new people\n> understand the situation during conflicted merges.\n>\n>>   git show INDEX:OURS:Makefile\n>>\n>> which is identical to what I wrote above, but is perhaps easier to\n>> explain.\n>\n> Why does anybody even want to say :2:Makefile to begin with?\n>\n> Presumably, you are dealing with a merge conflict at that path and trying\n> to see how pre-merge version of Makefile looked like, and then the next\n> thing you may want to do is how pre-merge version of their Makefile looked\n> like.\n>\n> Wouldn't it be far more natural to ask for these instead?\n>\n>    git show HEAD:Makefile\n>    git show MERGE_HEAD:Makefile\n>\n> I do not think whoever brought that \"you can look at individual stages\n> with :$n:$path\" to this discussion was thinking straight. Yes, it is\n> something you _could_ do, I've never found that particularly _useful_\n> unless I was debugging git itself.\n>\n"},{"id":"169901","messageId":"7vei2ysqi7.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"4DF45769.4020403@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-12T21:12:48Z","receivedAt":"2011-06-12T21:12:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> On 06/10/2011 11:48 PM, Junio C Hamano wrote:\n>> In short, the proposed \"NEXT\" does not help in a situation with conflicts,\n>> and makes the user experience worse.\n>\n> The idea of \"NEXT\" and its friends would indeed be marginal if it only\n> applied to \"git diff\".  The real gain in learnability comes from using\n> the same idioms in other commands where they make sense; for example,\n>\n>     # More consistent alternative to the special \"--ours\" option:\n>     git checkout OURS -- Makefile\n\nI do not see much improvement over --ours here.\n\n>     # This would add more completeness to the\n>     # \"git checkout <tree-ish> -- PATH\" command, and would remain the\n>     # default if no <tree-ish> is specified:\n>     git checkout NEXT -- Makefile\n>     git show NEXT:Makefile\n\nNow, during conflict, you admitted that NEXT would not be helpful for\n\"diff\", but these are even more dubious during conflict.\n\nThe point of index that can keep conflicted state (in fact, contrary to\nsome misperception, index is where the real merge happens, and updating\nthe working tree is merely to _help_ users to help the index resolve the\nconflicts, not the other way around) is that until you resolve conflicts,\n\"the state for the NEXT commit\" is not defined.\n\nHow would it improve the support we give to users when you give NEXT to\nthem, compared with the current system, if you have to say \"NEXT\" works\nmost of the time to represent what you would commit next?  You have to\nalso tell them that in some circumstances there cannot be \"NEXT\" until\nthey resolve conflicts, and then they need to learn how to do so with the\nindex. They need to learn the real thing at that point, unlearning fuzzily\ndefined \"NEXT\" illusion.\n\nI certainly do not have any objection against making system easier to\nunderstand, and I do not think implementation complexity nor performance\nshould trump the usability (I also do not think various conflicting\nsemantics of proposed \"NEXT\" are hard to implement efficiently).\n\nI however doubt \"NEXT\" would help to give users any better understanding,\nand that is the biggest problem I have with this topic.\n"},{"id":"169902","messageId":"7v8vt6spr0.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"BANLkTin_NYZ39s7gXbVrbAZU=+fzRCHdcA@mail.gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-12T21:29:07Z","receivedAt":"2011-06-12T21:29:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Nahas <mike.nahas@gmail.com> writes:\n\n> It is clear that implementing NEXT/WTREE will worsen the performance\n> of some commands (\"git diff\" under merge conflict).\n\nIt is not clear to me at all. I generally do not to base my first\nobjection on performance. When I have problems with proposals at the\ndesign and concept level, I do not have a chance to even bother about\nperformance aspect, before questioning the proposal.\n"},{"id":"169909","messageId":"BANLkTikNwk0HpJ-G+fc7NwRdY_=Hy930iQ@mail.gmail.com","threadId":"27548","inReplyTo":"7v8vt6spr0.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-13T02:14:34Z","receivedAt":"2011-06-13T02:14:34Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"On Sun, Jun 12, 2011 at 5:29 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Michael Nahas <mike.nahas@gmail.com> writes:\n>\n>> It is clear that implementing NEXT/WTREE will worsen the performance\n>> of some commands (\"git diff\" under merge conflict).\n>\n> It is not clear to me at all. I generally do not to base my first\n> objection on performance. When I have problems with proposals at the\n> design and concept level, I do not have a chance to even bother about\n> performance aspect, before questioning the proposal.\n\nMy apologies.  \"Performance\" was an ambiguous word.\n\nI meant that \"git diff\" under a merge conflict would be less\ninformative if forced it to be equivalent to some notation with\nNEXT/WTREE.  Even if we allowed diff3 and defined BASE, OURS, THEIRS.\n"},{"id":"169913","messageId":"20110613034347.GA4222@elie","threadId":"27548","inReplyTo":"4DF29EA5.60502@ira.uka.de","subject":"git diff --added (Re: Command-line interface thoughts)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-06-13T03:43:47Z","receivedAt":"2011-06-13T03:43:47Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Holger Hellmuth wrote:\n\n> User never heard of 'staged'. He asks instead \"I want to see what I\n> added\" --> git diff --added --> Error Message --> User checks man page,\n> again\n\nDo you think it would be valuable to introduce --added as a synonym\nfor --cached and slowly steer documentation to encourage the latter\nin place of the former?\n\nExamples, to see how it could work in practice:\n\n\t# Instead of searching tracked files in the working tree,\n\t# search blobs registered in the index file (i.e., accepted\n\t# with \"git add\" instead of the iffy hacks that are up in\n\t# the air).  The main advantage of this over plain \"git grep\"\n\t# is speed.\n\tgit grep --added -e foo\n\n\t# Remove foo.c from the next commit, without touching the\n\t# worktree.\n\tgit rm --added foo.c\n\n\t# Apply patch to the index, leaving the worktree alone.\n\tgit apply --added some-change.patch\n\n\t# List changes that I marked with \"git add\" for inclusion in\n\t# the next commit.\n\tgit diff --added\n\nI like it a lot more than \"staged\". ;-)  Though --index-only still\nseems a little clearer to me.\n"},{"id":"169915","messageId":"buotybu2wx7.fsf@dhlpc061.dev.necel.com","threadId":"27548","inReplyTo":"20110613034347.GA4222@elie","subject":"Re: git diff --added (Re: Command-line interface thoughts)","fromName":"Miles Bader","fromEmail":"miles@gnu.org","sentAt":"2011-06-13T04:11:00Z","receivedAt":"2011-06-13T04:11:00Z","isPatch":false,"sender":{"key":"miles@gnu.org","avatar":"https://gravatar.com/avatar/01069b69593af7bff28e2f97afeb3644ae6fe2f5f56cb3a8cf34c5fb8c36efe5?d=mp&s=160"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n> Do you think it would be valuable to introduce --added as a synonym\n> for --cached and slowly steer documentation to encourage the latter\n> in place of the former?\n\n\"--added\" sounds very awkward though; \"--staged\" is much more natural.\n\n-miles\n\n-- \nIdiot, n. A member of a large and powerful tribe whose influence in human\naffairs has always been dominant and controlling.\n"},{"id":"169916","messageId":"BANLkTikUOXwN9YrC25_mo2z5EWcsjrkg7A@mail.gmail.com","threadId":"27548","inReplyTo":"buotybu2wx7.fsf@dhlpc061.dev.necel.com","subject":"Re: git diff --added (Re: Command-line interface thoughts)","fromName":"Miles Bader","fromEmail":"miles@gnu.org","sentAt":"2011-06-13T04:46:34Z","receivedAt":"2011-06-13T04:46:34Z","isPatch":false,"sender":{"key":"miles@gnu.org","avatar":"https://gravatar.com/avatar/01069b69593af7bff28e2f97afeb3644ae6fe2f5f56cb3a8cf34c5fb8c36efe5?d=mp&s=160"},"body":"On Mon, Jun 13, 2011 at 4:11 AM, Miles Bader <miles@gnu.org> wrote:\n>> Do you think it would be valuable to introduce --added as a synonym\n>> for --cached and slowly steer documentation to encourage the latter\n>> in place of the former?\n>\n> \"--added\" sounds very awkward though; \"--staged\" is much more natural.\n\nI should note _why_ this is so:\n\nThe main problem is well-known -- that \"git add\" is a bit overloaded\nand slightly awkward in some case (e.g., to remove a file, you need to\nadd it...).  But whatever, it works well enough, because people are\nused to it.\n\nHowever in the case of git diff, if one sees \"git diff --added\", it\nsounds like it means \"show me a diff of added files\" -- but the term\n\"added files\" is ambiguous; and the fact that \"git add\" is in fact,\noverloaded with multiple meanings doesn't really help, the basic\nambiguity makes \"git diff --added\" awkward and unclear.\n\nA far better way would be to (1) make \"git diff --staged\" an alias for\n\"git-diff --cached\" (2) start promoting \"git stage\" in documentation,\ninstead of \"git add\".\n\n-Miles\n\n-- \nCat is power.  Cat is peace.\n"},{"id":"169925","messageId":"20110613080617.GC4570@elie","threadId":"27548","inReplyTo":"buotybu2wx7.fsf@dhlpc061.dev.necel.com","subject":"Re: git diff --added (Re: Command-line interface thoughts)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-06-13T08:06:18Z","receivedAt":"2011-06-13T08:06:18Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Miles Bader wrote:\n\n> \"--added\" sounds very awkward though; \"--staged\" is much more natural.\n\nYou make a strong case.  How about something like this?\n\n-- >8 --\nSubject: Documentation: explain diff --cached in terms of non --cached form\n\n\"git diff\" is a somewhat odd command, since it has two fairly\ndifferent roles:\n\n - on one hand, it is the command to explain the worktree or index in\n   terms of something else;\n - on the other hand, it is the command to compare two blobs, trees,\n   or on-disk files.\n\nTo a new user, that second role might seem to be the most basic and\nmost natural, since it is most closely analagous to the ordinary\nnon-git \"diff\" command, but in practice the first one is the one that\ngets used most often and it is somewhat different.  Avoid surprises\nby treating this first role separately in the introductory paragraph\nand calling it \"primary\".\n\nThe motivation is that it is hard enough to remember the various 0-\nand 1-tree forms of \"git diff\"; hopefully fending off the distraction\nof a false analogy with 2-tree \"git diff\" will help with that.  This\npatch also tries to clarify those mnemonics (especially: \"--cached\"\nmean to use the index in place of the worktree) by rearranging the\nmaterial slightly.  The most obvious mechanical changes involved are\nlisting 0- and 1-tree \"git diff\" separately in the synopsis and\nreordering the text to put \"git diff HEAD\" before \"git diff --cached\nHEAD\".\n\nSome small wording improvements snuck in while at it, including\nmentioning the --staged synonym for --cached a little more often.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/git-diff.txt |   61 +++++++++++++++++++++++--------------------\n 1 files changed, 33 insertions(+), 28 deletions(-)\n\ndiff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt\nindex f8d0819..7a66017 100644\n--- a/Documentation/git-diff.txt\n+++ b/Documentation/git-diff.txt\n@@ -9,59 +9,64 @@ git-diff - Show changes between commits, commit and working tree, etc\n SYNOPSIS\n --------\n [verse]\n-'git diff' [options] [<commit>] [--] [<path>...]\n+'git diff' [options] [--] [<path>...]\n+'git diff' [options] <commit> [--] [<path>...]\n 'git diff' [options] --cached [<commit>] [--] [<path>...]\n 'git diff' [options] <commit> <commit> [--] [<path>...]\n 'git diff' [options] [--no-index] [--] <path> <path>\n \n DESCRIPTION\n -----------\n-Show changes between the working tree and the index or a tree, changes\n-between the index and a tree, changes between two trees, or changes\n-between two files on disk.\n+The primary purpose of 'git diff' is to compare files in the working\n+tree to stored versions in the repository.  It can also be used to\n+show changes between the index and a tree, changes between two trees,\n+or changes between two files on disk.\n \n-'git diff' [--options] [--] [<path>...]::\n+'git diff' [options] [--] [<path>...]::\n \n \tThis form is to view the changes you made relative to\n-\tthe index (staging area for the next commit).  In other\n-\twords, the differences are what you _could_ tell git to\n-\tfurther add to the index but you still haven't.  You can\n-\tstage these changes by using linkgit:git-add[1].\n+\tthe index (staging area for the next commit).  It is\n+\tthe most common use of 'git diff'; the differences are\n+\twhat you _could_ tell git to further add to the index\n+\tbut you still haven't.  You can stage these changes by\n+\tusing linkgit:git-add[1] (aka linkgit:git-stage[1]).\n +\n-If exactly two paths are given and at least one points outside\n-the current repository, 'git diff' will compare the two files /\n-directories. This behavior can be forced by --no-index.\n+If exactly two paths are given and one points outside the current\n+repository, 'git diff' will compare the two files or directories.\n+This behavior can be forced with the `--no-index` option.\n \n-'git diff' [--options] --cached [<commit>] [--] [<path>...]::\n-\n-\tThis form is to view the changes you staged for the next\n-\tcommit relative to the named <commit>.  Typically you\n-\twould want comparison with the latest commit, so if you\n-\tdo not give <commit>, it defaults to HEAD.\n-\tIf HEAD does not exist (e.g. unborned branches) and\n-\t<commit> is not given, it shows all staged changes.\n-\t--staged is a synonym of --cached.\n-\n-'git diff' [--options] <commit> [--] [<path>...]::\n+'git diff' [options] <commit> [--] [<path>...]::\n \n \tThis form is to view the changes you have in your\n \tworking tree relative to the named <commit>.  You can\n-\tuse HEAD to compare it with the latest commit, or a\n+\tuse HEAD to compare with the latest commit, or a\n \tbranch name to compare with the tip of a different\n \tbranch.\n \n-'git diff' [--options] <commit> <commit> [--] [<path>...]::\n+'git diff' [options] --cached [<commit>] [--] [<path>...]::\n+'git diff' [options] --staged [<commit>] [--] [<path>...]::\n+\n+\tIf passed --cached or its synonym --staged,\n+\t'git diff' will view the changes you have staged for\n+\tthe next commit instead of examining the working tree.\n+\tTypically you would want a comparison with the latest\n+\tcommit, so if you do not give <commit>, it defaults\n+\tto HEAD.\n+\tIf HEAD does not exist (e.g. unborn branches) and\n+\t<commit> is not given, it shows all staged changes.\n+\n+'git diff' [options] <commit> <commit> [--] [<path>...]::\n \n \tThis is to view the changes between two arbitrary\n-\t<commit>.\n+\tcommits.\n \n-'git diff' [--options] <commit>..<commit> [--] [<path>...]::\n+'git diff' [options] <commit>..<commit> [--] [<path>...]::\n \n \tThis is synonymous to the previous form.  If <commit> on\n \tone side is omitted, it will have the same effect as\n \tusing HEAD instead.\n \n-'git diff' [--options] <commit>\\...<commit> [--] [<path>...]::\n+'git diff' [options] <commit>\\...<commit> [--] [<path>...]::\n \n \tThis form is to view the changes on the branch containing\n \tand up to the second <commit>, starting at a common ancestor\n-- \n1.7.6.rc1\n"},{"id":"169930","messageId":"201106131215.24343.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DF29EA5.60502@ira.uka.de","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-13T10:15:22Z","receivedAt":"2011-06-13T10:15:22Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sat, 11 June 2011, Holger Hellmuth wrote:\n> Am 10.06.2011 20:35, schrieb Jakub Narebski:\n>> Dnia piątek 10. czerwca 2011 20:07, Holger Hellmuth napisał:\n>>> On 10.06.2011 18:44, Jakub Narebski wrote:\n>>>> On Thu, 9 Jun 2011, Holger Hellmuth wrote:\n\n>>>>> Also there are no good words for what someone wants to see in this case.\n>>>>> At least I would assume the git project would have found them if they\n>>>>> existed. '--cached' is definitely not one of them. But we have fitting\n>>>>> and widely known names for the targets, i.e 'working tree', 'index' and\n>>>>> 'head'.\n>>>>\n>>>> \"I want to see if there are any remaining changes\", \"I want to see what\n>>>> 'git commit' would bring\", \"I want to see what 'git commit -a' would bring\".\n>>>> Neither of those is about targets for diff.\n>>>\n>>> Are you proposing a command \"git \n>>> --I-want-to-see-if-there-are-any-remaining-changes\" ? ;-). I was looking \n>>> for short command or parameter names that are easy to remember, not for \n>>> definitions of the output of cryptic commands.\n>>>\n>>> But lets see. If I didn't know much git, where would I look for the \n>>> right command for your three needs? Where would I expect the solution? \n>>> (note I'm not proposing any of these commands)\n>>>\n>>> \"I want to see if there are any remaining changes\"?\n>>> git status\n>>> git status --full\n>>> git status --detailed\n>> \n>> \"Any differences\"?\n>> \n>> git diff\n> \n> But difference to what --> User checks man page, again.\n\nUser's changes.  User doesn't need to know what are those two places\ncalled.\n \n>> \n>> \n>> \"I want to see what I staged\"\n>> \n>> git diff --staged\n>> \n> \n> User never heard of 'staged'. He asks instead \"I want to see what I\n> added\" --> git diff --added --> Error Message --> User checks man page,\n> again\n\nUser uses \"git stage <file>\", so he/she uses \"git diff --staged\".\n \n[...]\n>>> git diff WTREE INDEX\n>>           ^^^^^^^^^^^ --- reverse to \"git diff\"\n>> \n>> In this direction it is surely suprising... you see, how again and again\n>> having to explicitely state what to compare with which leads to mistakes\n>> such like this one, and the one in few mails earlier.\n> \n> I'm a sloopy person as you have noticed. Also very forgetful. I usually\n> don't bother with the order of 'diff' parameters when I can get the\n> direction from the diff output.\n\nFor other people getting the reverse of changes can be certainly\nsuprising (I though I added this, not deleted...).  When you specify\nendpoints manually, there is a chance to get them in wrong direction.\nEspecially that there is NEXT WTREE but HEAD NEXT.\n\n> Small things like 'git unadd', Jeff Kings 'git put' and git diff with\n> targets probably would help this casual/intermediate/advanced user (take\n> your pick).\n\nI agree with 'git unadd'.  Jeff Kings 'git put' and git diff targets have\nthe problems that need to be fully solved before considering for inclusion.\n\nBTW. there is code for 'git put'.  Where is code for git diff targets?\n\n-- \nJakub Narebski\nPoland\n"},{"id":"169934","messageId":"7vmxhlrk3m.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"buotybu2wx7.fsf@dhlpc061.dev.necel.com","subject":"Re: git diff --added (Re: Command-line interface thoughts)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-13T12:28:45Z","receivedAt":"2011-06-13T12:28:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Miles Bader <miles@gnu.org> writes:\n\n> Jonathan Nieder <jrnieder@gmail.com> writes:\n>> Do you think it would be valuable to introduce --added as a synonym\n>> for --cached and slowly steer documentation to encourage the latter\n>> in place of the former?\n>\n> \"--added\" sounds very awkward though; \"--staged\" is much more natural.\n\nActually I think _both_ are equally wrong.\n\nI have to thank you and Jonathan for making me realize the real reason why\n\"staged\" didn't sit well in my ears. The word used as adjective nauseated\nme forever but I couldn't clearly explain why even to myself, but now I\nhave the explanation.\n\nThe index has data registered for paths. \"add\" (and \"stage\") are verbs\nused to describe the act of taking data different from what is currently\nregistered in the index and replacing it. The phrase \"added contents\" thus\ncan be (mis)interpreted to refer to only the subset of the data that is\ndifferent from what you used to have in the index, typically meaning the\nones that are different from HEAD, i.e. you would see the change in the\noutput of \"git diff HEAD\". This is especially true because many people\nthink in terms of \"recording difference from the previous version\" when\nthey think about SCMs, and \"--added\" or \"--staged\" rhyme well with that\nmindset.\n\nThis potential misinterpretation does not cause problems in some contenxt,\nand one such context is the hidden synonym \"git diff --staged\", which _is_\nall about the subset of the paths that are different from HEAD.\n\nBut as Jonathan in his message and you in your response brilliantly\nillustrated, misinterpreted \"added\" and \"staged\" break down badly in other\ncontexts. When running \"git grep\" and \"git rm\" against the data sitting in\nthe index, you do _not_ want to limit your request to the subset of paths\nin the index that are different from HEAD. \"git rm --added\" is not a\ncommand that chooses paths that are added to the index, and remove these\npaths from both the index and the working tree, but \"added\" would invite\nsuch a misinterpretation from new people.\n\nThe adjective \"cached\" refers to the _state_ of the data for various paths\nin the index as they exist, regardless of when or how these contents were\nplaced there. For the majority of the paths the \"cached\" data may have\ncome from the HEAD, and for other paths, \"cached\" data may be something\nyou have \"added\", but because \"cached\" is a state as it exists in the\nindex, there is no distinction between the two.\n\nBecause \"cache\" nor \"index\" are never used as verbs that mean the _act_ of\nputting updated things in the index, we do not risk --cached nor --index\nto get misinterpreted as limiting to the subset of the paths that are\ndifferent from HEAD. At least that is how these four words (added, staged,\ncached and index) sound to my ears, and that is why I said the first two\nare equally wrong in the beginning of this message.\n\nIt is an entirely different issue that \"cached\" is _not_ the best way to\nspell \"index-only\", though.\n"},{"id":"169936","messageId":"7vhb7triu8.fsf@alter.siamese.dyndns.org","threadId":"27548","inReplyTo":"20110613080617.GC4570@elie","subject":"Re: git diff --added (Re: Command-line interface thoughts)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-13T12:55:59Z","receivedAt":"2011-06-13T12:55:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> -Show changes between the working tree and the index or a tree, changes\n> -between the index and a tree, changes between two trees, or changes\n> -between two files on disk.\n> +The primary purpose of 'git diff' is to compare files in the working\n> +tree to stored versions in the repository.  It can also be used to\n> +show changes between the index and a tree, changes between two trees,\n> +or changes between two files on disk.\n\nI agree that it is a good idea to clarify whatever likely misunderstanding\nnew people might have, and I further agree that to some people the command\nline syntax of diff to compare a tree with the index or with the working\ntree may look like a different \"modes\" from the syntax to compare two\ntree-ish.\n\nI however am not sure it is a good idea to declare \"comparing the index\nwith the working tree\" is the \"primary\". People who are just starting out,\njust downloading and sightseeing, are likely to use \"git clone\" followed\nby \"git diff v2.6.39 v3.0\", I suspect, and to them, the primary use would\nbe to compare two revisions, no?\n\nInstead of making them sound as if they are different \"modes\", I think it\nmay make more sense to teach them upfront that in addition to the two\n\"modes\" they may be familiar with from their past experiences with other\nSCMs, namely, comparing two revisions and comparing a revision with the\nworking tree, there are two extra pairs they could be comparing in git,\nnamely, comparing the index (the data you prepared for your next commit)\nwith the working tree, and comparing the index with a revision.\n\n\tSide note: note that even in the context of other SCMs, the choice\n\tthe user makes when using \"diff\" is not about what two things to\n\tcompare, i.e. \"scm diff REV1 WTREE\" vs \"scm diff REV1 REV2\". They\n\tchoose two \"modes\" and then fill in the parameter(s) the chosen\n\tmode requires. When comparing two revs, you need two revs; when\n\tcomparing a rev with the working tree, you need one rev, and\n\tworktree does not have to be specified. That way, you do not\n\texplicitly specify which \"mode\" you are using, as that can be\n\tinferred from the command line.\n\n\tBut if we do not call these two \"modes\", I do not see a reason for\n\tus to call two extra pairs git gives them \"modes\" either.\n\nThen if you feel \"comparing the index with the working tree\" the most\nimportant combination, start your description from that \"mode\".\n\nFor the reason I stated in the other message, I think it was a wise\ndecision not to advertise \"diff --staged\" synonym when we introduced it at\n2baf185 (git-diff: Add --staged as a synonym for --cached., 2008-10-29),\nby the way.\n"},{"id":"169960","messageId":"20110613185052.GD17845@sigill.intra.peff.net","threadId":"27548","inReplyTo":"7v4o3xwe5z.fsf@alter.siamese.dyndns.org","subject":"Re: Command-line interface thoughts","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-13T18:50:52Z","receivedAt":"2011-06-13T18:50:52Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jun 10, 2011 at 02:48:56PM -0700, Junio C Hamano wrote:\n\n> >   git show INDEX:OURS:Makefile\n> >\n> > which is identical to what I wrote above, but is perhaps easier to\n> > explain.\n> \n> Why does anybody even want to say :2:Makefile to begin with?\n> [...]\n> I do not think whoever brought that \"you can look at individual stages\n> with :$n:$path\" to this discussion was thinking straight. Yes, it is\n> something you _could_ do, I've never found that particularly _useful_\n> unless I was debugging git itself.\n\nI think it may have been me, and I was bringing it up for completeness\nin discussion of the new tokens. I don't actually use that concept very\noften at all, so it can just be dropped from this discussion.\n\n-Peff\n"},{"id":"169963","messageId":"4DF66946.8000101@ira.uka.de","threadId":"27548","inReplyTo":"7vmxhlrk3m.fsf@alter.siamese.dyndns.org","subject":"Re: git diff --added (Re: Command-line interface thoughts)","fromName":"Holger Hellmuth","fromEmail":"hellmuth@ira.uka.de","sentAt":"2011-06-13T19:47:18Z","receivedAt":"2011-06-13T19:47:18Z","isPatch":false,"sender":{"key":"hellmuth@ira.uka.de","avatar":null},"body":"Am 13.06.2011 14:28, schrieb Junio C Hamano:\n>> Jonathan Nieder <jrnieder@gmail.com> writes:\n>>> Do you think it would be valuable to introduce --added as a synonym\n>>> for --cached and slowly steer documentation to encourage the latter\n>>> in place of the former?\n\nNo. Apart from Junios reason more options won't help that much because\ngit is already loaded with options (git diff for example has 49). Don't\nmisinterpret this as a suggestion to remove options, just that an option\nin this sea of options must be very obvious to help the casual user.\nAnd \"git diff --added\" is not telling with what it compares the \"added\"\nfiles, which means you either know the concept or you have to read the\nman page whenever you need to use it. Until you fix it in your memory,\nwhich may be never because you don't use it often enough.\n\n> It is an entirely different issue that \"cached\" is _not_ the best way to\n> spell \"index-only\", though.\n\nYes, and the one and only word that would be right here (apart from\nspelling it out with index-only) is \"index\", while \"index\" as used in\ngit stash and git apply should have been something like 'with-index'. At\nleast to me '--something' suggests 'something-only' much more than\n'something-too'\n\nSince this is not possible anymore, we are stuck with 'cache' and\nessentially a diff-command that will never be user-friendly. That is why\nI still think that an alternate usage with 'git diff wtree index' would\nbe beneficial, especially with a corresponding 'git put'.\n\nHolger.\n"},{"id":"169965","messageId":"BANLkTinqRZyMVwMqZTA8Ei1Tg0nc0Od==A@mail.gmail.com","threadId":"27548","inReplyTo":"4DF66946.8000101@ira.uka.de","subject":"Re: git diff --added (Re: Command-line interface thoughts)","fromName":"Michael Nahas","fromEmail":"mike.nahas@gmail.com","sentAt":"2011-06-13T20:31:09Z","receivedAt":"2011-06-13T20:31:09Z","isPatch":false,"sender":{"key":"mike.nahas@gmail.com","avatar":null},"body":"index is a file with multiple uses.\nE.g., during a conflict it may have 4 \"stages\".\n\nI prefer either index0 or NEXT.\n\nOn Mon, Jun 13, 2011 at 3:47 PM, Holger Hellmuth <hellmuth@ira.uka.de> wrote:\n> Am 13.06.2011 14:28, schrieb Junio C Hamano:\n>>> Jonathan Nieder <jrnieder@gmail.com> writes:\n>>>> Do you think it would be valuable to introduce --added as a synonym\n>>>> for --cached and slowly steer documentation to encourage the latter\n>>>> in place of the former?\n>\n> No. Apart from Junios reason more options won't help that much because\n> git is already loaded with options (git diff for example has 49). Don't\n> misinterpret this as a suggestion to remove options, just that an option\n> in this sea of options must be very obvious to help the casual user.\n> And \"git diff --added\" is not telling with what it compares the \"added\"\n> files, which means you either know the concept or you have to read the\n> man page whenever you need to use it. Until you fix it in your memory,\n> which may be never because you don't use it often enough.\n>\n>> It is an entirely different issue that \"cached\" is _not_ the best way to\n>> spell \"index-only\", though.\n>\n> Yes, and the one and only word that would be right here (apart from\n> spelling it out with index-only) is \"index\", while \"index\" as used in\n> git stash and git apply should have been something like 'with-index'. At\n> least to me '--something' suggests 'something-only' much more than\n> 'something-too'\n>\n> Since this is not possible anymore, we are stuck with 'cache' and\n> essentially a diff-command that will never be user-friendly. That is why\n> I still think that an alternate usage with 'git diff wtree index' would\n> be beneficial, especially with a corresponding 'git put'.\n>\n> Holger.\n>\n"},{"id":"169970","messageId":"4DF69041.9060100@gspranz.de","threadId":"27548","inReplyTo":"201106131215.24343.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Holger Hellmuth","fromEmail":"holger@gspranz.de","sentAt":"2011-06-13T22:33:37Z","receivedAt":"2011-06-13T22:33:37Z","isPatch":false,"sender":{"key":"holger@gspranz.de","avatar":null},"body":"Am 13.06.2011 12:15, schrieb Jakub Narebski:\n> For other people getting the reverse of changes can be certainly\n> suprising (I though I added this, not deleted...).  When you specify\n> endpoints manually, there is a chance to get them in wrong direction.\n> Especially that there is NEXT WTREE but HEAD NEXT.\n\nOther people have that problem anyway when they use 'git diff <commit>\n<othercommit>'. Or when they use linux diff, where the man page doesn't\neven specify which direction it compares. Obviously someone thought that\n\"--- a.txt,  +++ b.txt\" or the direction of '>' and '<' give enough hints.\n\n[...]\n> BTW. there is code for 'git put'.  Where is code for git diff targets?\n\nDo you accept perl code? ;-) I've never seriously coded in C\n\nHolger.\n"},{"id":"169975","messageId":"4DF6E1C0.5000503@alum.mit.edu","threadId":"27548","inReplyTo":"201106131215.24343.jnareb@gmail.com","subject":"Re: Command-line interface thoughts","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-06-14T04:21:20Z","receivedAt":"2011-06-14T04:21:20Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 06/13/2011 12:15 PM, Jakub Narebski wrote:\n> BTW. there is code for 'git put'.  Where is code for git diff targets?\n\nIs this just a rhetorical question, or would code be useful?  From the\ntone of the conversation, I got the impression that the change has no\nchance of being accepted.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"169984","messageId":"201106140951.19227.jnareb@gmail.com","threadId":"27548","inReplyTo":"4DF6E1C0.5000503@alum.mit.edu","subject":"Re: Command-line interface thoughts","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-06-14T07:51:18Z","receivedAt":"2011-06-14T07:51:18Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 14 Jun 2011, Michael Haggerty wrote:\n> On 06/13/2011 12:15 PM, Jakub Narebski wrote:\n\n> > BTW. there is code for 'git put'.  Where is code for git diff targets?\n> \n> Is this just a rhetorical question, or would code be useful?  From the\n> tone of the conversation, I got the impression that the change has no\n> chance of being accepted.\n\nIt was not entirely rhetorical question.\n\nFirst, code speak louder than words. A feature for which there exist\nimplementation (and documentation, and tests) has much more chance being\naccepted / merged in, than purely theoretical discussion on user\ninterface. Though the latter is needed too, of course.\n\nSecond, writing proof of concept implementation, or at least trying\nto write documentation and/or test for new feature or new behavior\nhelp to flesh out ideas, to give them definite shape.\n\n\nBut I know that not everybody is a programmer, and from those not all\nare proficient in C (at least for this case), Perl, Python or shell\nscripting, and with Git API to implement new feature.\n\n-- \nJakub Narebski\nPoland\n"}]}