{"thread":{"id":"43185","subject":"Re: [RFC] git-add update with all-0 object","startedAt":"2006-11-30T22:08:23Z","lastAt":"2006-12-02T08:55:16Z","messageCount":15,"participants":["Andy Parkins","Jakub Narebski","Daniel Barkalow","Linus Torvalds","Junio C Hamano","Theodore Tso","Johannes Schindelin","Nicolas Pitre"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"295135","messageId":"Pine.LNX.4.64.0611301634080.20138@iabervon.org","threadId":"43185","inReplyTo":null,"subject":"[RFC] git-add update with all-0 object","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2006-11-30T22:08:23Z","receivedAt":"2006-11-30T22:08:23Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"One thing that I think is non-intuitive to a lot of users (either novice \nor who just don't do it much) is that it matters where in the process you \ndo \"git add <path>\" if you're also changing the file. Even if you \nunderstand the index, you may not realize (or may not have internalized \nthe fact) that what git-add does is update the index with what's there \nnow.\n\nI think the more obvious behavior is to have it record the fact that you \nwant to have the path tracked, but require one of the usual updating \nmechanisms to get a particular content into the index.\n\nThis should be pretty simple to implement: use --cacheinfo 0 0 $path \ninstead of --add -- $path, and teach programs that look at the objects \nrecorded in the index (rather than just hashes or other info) about all-0 \nhashes meaning \"but no content there\". write-tree would probably just \nskip the entry (and then you could add a file, but still produce commits \nwithout it until you actually do either an update-index explicitly or one \nof the commit option sets that updates it); diff would treat it as empty; \ncheckout would ignore it.\n\n\t-Daniel\n"},{"id":"296454","messageId":"Pine.LNX.4.63.0611302328570.30004@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"43185","inReplyTo":"Pine.LNX.4.64.0611301634080.20138@iabervon.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-11-30T22:32:01Z","receivedAt":"2006-11-30T22:32:01Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 30 Nov 2006, Daniel Barkalow wrote:\n\n> I think the more obvious behavior is to have it record the fact that you \n> want to have the path tracked, but require one of the usual updating \n> mechanisms to get a particular content into the index.\n\nI fear that this is just your being used to the CVS mindset. Please see \nhttp://article.gmane.org/gmane.comp.version-control.git/32792 for details.\n\nHth,\nDscho\n"},{"id":"297169","messageId":"Pine.LNX.4.64.0611301733460.9647@xanadu.home","threadId":"43185","inReplyTo":"Pine.LNX.4.64.0611301634080.20138@iabervon.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-11-30T22:34:58Z","receivedAt":"2006-11-30T22:34:58Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 30 Nov 2006, Daniel Barkalow wrote:\n\n> One thing that I think is non-intuitive to a lot of users (either novice \n> or who just don't do it much) is that it matters where in the process you \n> do \"git add <path>\" if you're also changing the file. Even if you \n> understand the index, you may not realize (or may not have internalized \n> the fact) that what git-add does is update the index with what's there \n> now.\n\nAnd actually I think this is a good thing.  This is what makes the index \nworth it.  Better find a way to make it obvious to people what's \nhappening.\n\n\n"},{"id":"295644","messageId":"eknmju$9ok$1@sea.gmane.org","threadId":"43185","inReplyTo":"Pine.LNX.4.64.0611301733460.9647@xanadu.home","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-30T22:41:53Z","receivedAt":"2006-11-30T22:41:53Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Nicolas Pitre wrote:\n\n> On Thu, 30 Nov 2006, Daniel Barkalow wrote:\n> \n>> One thing that I think is non-intuitive to a lot of users (either novice \n>> or who just don't do it much) is that it matters where in the process you \n>> do \"git add <path>\" if you're also changing the file. Even if you \n>> understand the index, you may not realize (or may not have internalized \n>> the fact) that what git-add does is update the index with what's there \n>> now.\n> \n> And actually I think this is a good thing.  This is what makes the index \n> worth it.  Better find a way to make it obvious to people what's \n> happening.\n\nStill, perhaps (perhaps!) it would be useful to have \"intent to add\"\ngit-add.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"295277","messageId":"Pine.LNX.4.64.0611301431420.3513@woody.osdl.org","threadId":"43185","inReplyTo":"Pine.LNX.4.64.0611301634080.20138@iabervon.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-11-30T22:46:23Z","receivedAt":"2006-11-30T22:46:23Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 30 Nov 2006, Daniel Barkalow wrote:\n> \n> I think the more obvious behavior is to have it record the fact that you \n> want to have the path tracked, but require one of the usual updating \n> mechanisms to get a particular content into the index.\n\nWhile this certainly matches the git model better than just automatically \ntaking whatever state exist at commit time (you instead introduce it as a \nspecial \"empty state\" case), I don't think you really want it.\n\nWhy? \n\nTwo reasons:\n\n - you're still left with all the same issues (ie you do need to use \"git \n   commit -a\" because that is simply fundamental, and if you don't, \"git \n   commit\" now causes an ERROR, which is just illogical - you just added \n   the data!)\n\n   So it's simply better to just tell people \"git add\" adds the whole \n   state. Explain to them that git doesn't track \"filenames\", it tracks \n   state, and when you do a \"git add\", it really adds the _data_ and the \n   permissions too.\n\n   Really, if you didn't come from years of broken SCM's, you'd think that \n   it's _natural_ that when you add a file for tracking, you add its \n   contents too. It's not that git is surprising or unnatural, it's that \n   CVS is.\n\n - you generally really don't want to see \"git diff\" show you the big diff \n   for a new creation. You only think you do, but trust me, you generally \n   don't. It's the same thing as with doing merges - keeping the \n   automerged state in the index is actually nice, because it means that \n   the default \"git diff\" can just shut the heck up about the things that \n   may be the _bulk_ of the change, but it's not the interesting part.\n\nSo I would suggest that if people are irritated with \"git diff\" for \nexample not showing newly added files AT ALL, then the solution to that \nisn't that they should be added as \"empty\" or \"all zeroes\". We do have \nother state bits in the index already (we need them for marking things as \nbeing unmerged etc), and if the problem is that you want to see that you \nhave a pending add, it's easy enough to have \"git add\" always set a bit \nsaying \"this file is new\".\n\nA normal \"read tree object\" would populate index entries with that bit \ncleared, and so it would be possible to have\n\n\tgit add file.c\n\tgit diff\n\nshow something like\n\n\tdiff --git a/file.c b/file.c\n\tadded file <mode> <sha1>\n\nrather than show the whole big diff (which I _really_ don't think you want \nto see, and which is actually against the whole point, which is that you \nadd _content_ to the index, and \"git diff\" will always show you the stuff \nthat is _not_ added to the index yet).\n\n(Of course, if you _also_ had changed it between the \"git add\" and the \n\"git diff\", you'd get both the \"added file <mode> <sha1>\" _and_ the diff \nthat is the diff between the thing you added, and the status it has now).\n\nSo showing a real diff after \"git add\" would really be wrong. The index \nreally is important. But if it's _only_ an issue of worrying about seeing \nadded files at all, we can add a \"people comfort\" bit to do that.\n\n(Quite frankly, I don't think it's worthwhile. I really think this is a \ndocumentation issue. Make people understand that \"git add\" adds the \ncontents too, and that git never tracks filenames on their own at all).\n\nSo it is always going to be true that\n\n\tgit add file\n\techo New line >> file\n\tgit commit\n\nmust commit the old contents of the file. That really _does_ follow from \nthe whole \"track contents\" model. Anything that doesn't do this is \nfundamnetally broken, and has broken the notion of what \"git add\" means.\n\n"},{"id":"297060","messageId":"Pine.LNX.4.64.0611301747330.9647@xanadu.home","threadId":"43185","inReplyTo":"eknmju$9ok$1@sea.gmane.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-11-30T22:49:27Z","receivedAt":"2006-11-30T22:49:27Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 30 Nov 2006, Jakub Narebski wrote:\n\n> Nicolas Pitre wrote:\n> \n> > On Thu, 30 Nov 2006, Daniel Barkalow wrote:\n> > \n> >> One thing that I think is non-intuitive to a lot of users (either novice \n> >> or who just don't do it much) is that it matters where in the process you \n> >> do \"git add <path>\" if you're also changing the file. Even if you \n> >> understand the index, you may not realize (or may not have internalized \n> >> the fact) that what git-add does is update the index with what's there \n> >> now.\n> > \n> > And actually I think this is a good thing.  This is what makes the index \n> > worth it.  Better find a way to make it obvious to people what's \n> > happening.\n> \n> Still, perhaps (perhaps!) it would be useful to have \"intent to add\"\n> git-add.\n\nWell, sure.  It could be an argument to git-add.  But surely not the \ndefault?\n\ngit-add --latest maybe?\n\n\n"},{"id":"298301","messageId":"Pine.LNX.4.64.0611301749450.20138@iabervon.org","threadId":"43185","inReplyTo":"Pine.LNX.4.64.0611301431420.3513@woody.osdl.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2006-12-01T00:12:31Z","receivedAt":"2006-12-01T00:12:31Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 30 Nov 2006, Linus Torvalds wrote:\n\n> A normal \"read tree object\" would populate index entries with that bit \n> cleared, and so it would be possible to have\n> \n> \tgit add file.c\n> \tgit diff\n> \n> show something like\n> \n> \tdiff --git a/file.c b/file.c\n> \tadded file <mode> <sha1>\n> \n> rather than show the whole big diff (which I _really_ don't think you want \n> to see, and which is actually against the whole point, which is that you \n> add _content_ to the index, and \"git diff\" will always show you the stuff \n> that is _not_ added to the index yet).\n\nI'm not sure I want to see the whole added file more when diffing two \ntrees, or when I do \"git diff --cached\" after \"git update-index --add\", \nthan when I do \"git diff\" after \"git add\", but I'll concede that viewing \nthe content of a new file as a diff is no fun. (Maybe diff-against-nothing \nfor display needs work in general? It's solve the whole root commit thing, \ntoo.)\n\n> (Of course, if you _also_ had changed it between the \"git add\" and the \n> \"git diff\", you'd get both the \"added file <mode> <sha1>\" _and_ the diff \n> that is the diff between the thing you added, and the status it has now).\n> \n> So showing a real diff after \"git add\" would really be wrong. The index \n> really is important. But if it's _only_ an issue of worrying about seeing \n> added files at all, we can add a \"people comfort\" bit to do that.\n\nThis is where I think \"git add\" is really broken. For every other git \ncommand, if the command causes the index to not match HEAD, the command \ncontains \"index\" either in the name of the command or in an option.\n\nSo, if you understand the index, and you understand git's model, but you \ndon't know this one weird corner case, you will come to the conclusion \nthat \"git add <path>\" leaves <path> such that the index matches HEAD.\n\nNow *you* know that \"git add\" really is \"git update-index --add\", because \nyou were typing the latter (well, \"git update-cache --add\", anyway) before \n\"git add\" existed at all. But for new users, and anyone who wasn't adding \na lot of files back then, it's a surprising exception that has to be \nlearned and internalized.\n\n\"git checkout\" leaves the index matching HEAD or its original state.\n\"git commit\" leaves the index matching HEAD (the new HEAD) or its original \nstate.\n\"git reset\" (all options) leaves the index matching HEAD or its original \nstate.\n\"git pull/merge\" does disrupt the index, but it also starts to prepare a \ncommit based on multiple *HEAD files, and it leaves every stage of the \nindex matching some *HEAD or its original state. And new users still seem \nto wonder where the merge happens, because it doesn't say \"in the index\".\n\"git apply\" leaves the index alone.\n\n\"git update-index\" says it works on the index.\n\"git apply --index\" says it works on the index.\n\nAm I missing any violations of the rule? I guess \"git rm\", but that's just \nfor the CVS-damaged, unnecessary anyway, and it still doesn't care about \nthe state of the working directory at any particular point in time. And I \nstill prefer \"git update-index --force-remove\" as a command for that \noperation.\n\nSo it's obvious that the \"add\" functionality is properly called \"git add \n--index\", because whatever \"git add\" would, it would have to leave the \nindex matching HEAD or its original state.\n\n(Well, okay, '\"git commit -i path\" ^C', violates the rule. But I forgot \nuntil recently that -i stands for --include, not --index, which would make \na reasonable expansion, too)\n\n> (Quite frankly, I don't think it's worthwhile. I really think this is a \n> documentation issue. Make people understand that \"git add\" adds the \n> contents too, and that git never tracks filenames on their own at all).\n\nI think people's model is likely to be closer to \"touch\" for the index, \nespecially since it has no effect if the file is already in the index.\n\n> So it is always going to be true that\n> \n> \tgit add file\n> \techo New line >> file\n> \tgit commit\n> \n> must commit the old contents of the file. That really _does_ follow from \n> the whole \"track contents\" model. Anything that doesn't do this is \n> fundamnetally broken, and has broken the notion of what \"git add\" means.\n\n\"git add\" doesn't *say* it changes the index, and nothing else there \n*says* it changes the index, so \"git commit\" there should say \"nothing to \ncommit\", because you never did \"git update-index file\", either before or \nafter the change, and you didn't do \"git commit file\" or \"git commit -a\". \n\nJust tossing the words in commands around, it's obvious that what \n\"git add file\" should do is mean that you can now do\n\"git update-index file\" instead of\n\"git update-index --add file\". Saying you shouldn't need \"update-index\" \nafter adding a file is like saying you shouldn't need \"update-index\" after \nmodifying a file.\n\nBut it shouldn't change my index any more than \"git apply\" should, because \nit doesn't say it updates the index. (Of course, it would be good to have \n\"git add --index file\", matching \"git apply --index patch\", which does \nwhat \"git add\" does now.)\n\nNow, in order to interact correctly with reseting, checking out a \ndifferent branch, etc, it wants to have the information in the index \nfile, so there isn't a separate file with a list to lose stuff from. And \nit patterns naturally as an adjunct to the index for some things (like \nls-files, which doesn't care at all what the content associated with \nfilenames is). But that's fundamentally an implementation detail, not an \naspect of the model.\n\n\t-Daniel\n"},{"id":"296171","messageId":"20061201045727.GA22622@thunk.org","threadId":"43185","inReplyTo":"Pine.LNX.4.64.0611301749450.20138@iabervon.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2006-12-01T04:57:27Z","receivedAt":"2006-12-01T04:57:27Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Thu, Nov 30, 2006 at 07:12:31PM -0500, Daniel Barkalow wrote:\n> This is where I think \"git add\" is really broken. For every other git \n> command, if the command causes the index to not match HEAD, the command \n> contains \"index\" either in the name of the command or in an option.\n> \n> So, if you understand the index, and you understand git's model, but you \n> don't know this one weird corner case, you will come to the conclusion \n> that \"git add <path>\" leaves <path> such that the index matches HEAD.\n\nBut it's not just this one wierd corner case.  You yourself said that\n\"git pull/merge\" leave the index where it's != HEAD.   \n\nI have serious trouble believing that \"if the command leaves index !=\nHEAD, the command must contain 'index' in either the name of the\ncommand or the option\" is all that important of a consistent rule or\nprinciple that must be maintained at all costs.\n\n\nBy the way, after thinking about this for a while, part of the problem\nis that the name \"index\" really sucks.  Which is perhaps why Linus is\nnow trying to stop us from actually using the term \"index\" in these\ndiscussions.  :-)    If we called it a \"staging area\", as our Great\nLeader has suggested, I think it would be a lot easier for novice\nusers to understand.    Consider what is in the git man page:\n\n\tThe index is a simple binary file, which contains an efficient\n\trepresentation of a virtual directory content at some random\n\ttime.  It does so by a simple array that associates a set of\n\tnames, dates, permissions and content (aka \"blob\") objects\n\ttogether. The cache is always kept ordered by name, and names\n\tare unique (with a few very specific rules) at any point in\n\ttime, but the cache has no long-term meaning, and can be\n\tpartially updated at any time.....\n\n\tIn particular, the index file can have the representation of\n\tan intermediate tree that has not yet been instantiated. So\n\tthe index can be thought of as a write-back cache, which can\n\tcontain dirty information that has not yet been written back\n\tto the backing store.\n\nFor a kernel programmer, this might not be understandable --- but for\nyour typical application programmer, this is enough to cause him or\nher to conclude that git is simply not meant for use by mere mortals.\n\nSo as Junio and Linus have both said, it's all about your mental\nmodel, and if we think about it in terms of a staging area for a\ncommit, and we think about what commands are most natural given that\nmodel, it's far more important than whether a command has \"index\" in\nits name or specified in an option.\n\nPut another way, the reason why I think people are liking the whole\n\"git add\" and \"git rm\" suggestion is that it's a nice middle ground\nbetween the \"hide the index\" and the \"shove the index in the user's\nface\" approaches.  It's not that we are hiding the fact that there is\nthis thing with the horribly chosen name \"index\", but instead we talk\nabout this concept of a staging area and we don't dwell on things like\nthe fact that it is a binary file which stores an efficient\nrepresentation of a virtual directory.... blah blah blah.\n\nOnce this is done, the only command which is still problematic to\ndescribe is \"git diff\".  Yes, it almost always does the right thing.\nBut if you read the man page, even we are now using \"<tree-ish>\"\ninstead of \"<ent>\" to describe it, it still forces the user who is\nreading the man page to prove to him- or her-self that it really\nalways does the right thing.  The EXAMPLES section really helps, but\neven so, the man page is need in terrible of help.\n\nFor example, exactly what \"git diff\" does is described in terms of\n\"git diff-files\", \"git diff-index\". and \"git diff-tree\".  (And the\ncommand name git-diff-index, git-diff-tree and git-diff-files in the\nDESCRIPTION aren't even hotlinks, making it hard to get to the\nplumbing man pages, which is the only place where you can get\ndocumentation of the options accepted by git-diff.)    \n\nOK, so once the novice user gets past this hurdle, he/she says, OK,\nwhat does \"git diff <tree-ish>\" does?  Hmm, according to EXAMPLES,\nthis diffs the working tree with the named tree.  What options can I\ngive?  Well, with one one <tree-ish>, I have to go to read the man\npage for \"git-diff-index\", whose synposis says, \"Compares content and\nmode of blobs between the index and repository\".  But wait!  According\nto git-diff's EXAMLES section, \"git diff <tree-ish>\" doesn't involve\nthe index at all!  Why does the synposis say anything about the index?\nAnd this leaves the novice confused and bewildered.  And why not?  If\nthe user spends time puzzling through the man page, he/she will\ndiscover that:\n\n1) \"git diff-index <tree>\" compares the tree with the working\ndirectory, and doesn't involve the index at all, even though it is in\nthe command name.  WTF?!?\n\n2) If you want to really diff the index, you have to use the command\n\"git diff-index --cached <tree>\"\n\nIf you look at this from the point of the novice user, it becomes very\nclear why the index and commands that operate on the index are\nhopelessly confusing.  Yes, if you the grasshopper read and medidate\nvery deeply the low-level meaning of the plumbing, and then someone\nlike Linus slaps you upside the head with one of his e-mail messages,\nit will suddenly make sense to you.  The problem with this method is\nthat it doesn't scale terribly well.  :-)\n\nBut if you are just reading the \"git-diff\" man page for the first\ntime, and are then forced to read the \"git-diff-index\" man page to\npuzzle out what a particular \"git diff\" option does, and then have to\nconfront the notion that something as \"git diff HEAD\" involves a\ncommand \"git diff-index\", even though this confusing thing called the\nindex is never involved unless the --cache option is given --- can you\nsee how this might cause the beginning user of git to conclude that\ngit is hopelessly confusing and too hard to use?\n\nThe question then is how can we fix the \"git diff\" man page, and how\ndo we explain \"git diff\" in a tutorial so that users can understand\nwhat in the world does it do?  For a starting point, I'd recommend\nmoving the EXAMPLES to the beginning of the man page, and moving the\nany mention of git-diff-index, git-diff-files, and git-diff-tree to\nthe very end of the man page, and to put the most commonly used\noptions in the git-diff man page, so that most users don't have to\nlook at the low-level plumbing man pages to figure out how the\nhigh-level git-diff works.  \n\n"},{"id":"295846","messageId":"7vhcwgcf39.fsf@assigned-by-dhcp.cox.net","threadId":"43185","inReplyTo":"20061201045727.GA22622@thunk.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-01T06:20:10Z","receivedAt":"2006-12-01T06:20:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Theodore Tso <tytso@mit.edu> writes:\n\n> The question then is how can we fix the \"git diff\" man page, and how\n> do we explain \"git diff\" in a tutorial so that users can understand\n> what in the world does it do?  For a starting point, I'd recommend\n> moving the EXAMPLES to the beginning of the man page, and moving the\n> any mention of git-diff-index, git-diff-files, and git-diff-tree to\n> the very end of the man page, and to put the most commonly used\n> options in the git-diff man page, so that most users don't have to\n> look at the low-level plumbing man pages to figure out how the\n> high-level git-diff works.  \n\nAll good points.  The only slight worry I have is that just\nmoving EXAMPLE up deviates from the traditional UNIX manpage\norder of presenting information.\n\nI think the plumbing manuals can (and probably should) stay as\nthe technical manual for Porcelain writers.  \"git diff\", \"git\nadd\" and friends that are clearly Porcelain should talk about\nwhat it does in the terms of end user operation in the\nDESCRIPTION section and puts less stress on how things work\nbehind the scene in technical terms.  For example, from\ngit-diff(1):\n\n        DESCRIPTION\n        -----------\n        Show changes between two trees, a tree and the working tree, a\n        tree and the index file, or the index file and the working tree.\n        The combination of what is compared with what is determined by\n        the number of trees given to the command.\n\nThat may be an accurate description of what the command does in\ntechnical terms, but it does not tell why the user may want to\ncompare \"a tree and the working tree\".  The users would want to\nknow which case applies to their current situation and we should\nmake it easier for them to find that information.\n\nFor example, although --cached is technically speaking one of\nthe --diff-options, it should be separated out from other\noptions when we talk about 'git-diff'.  Also, although 'git-diff'\nis designed to work on tree-ish, Porcelain users will use with\ncommit-ish (either a commit or an annotated signed tag that\npoints at a commit) 99.9% of the time, so we should mention\n<tree-ish> at the end as a sidenote and talk about <commit>.\n\n\tDESCRIPTION\n\t-----------\n\tThis command shows changes between four combinations \n\tof states.\n\n\t* 'git-diff' [--options] [--] [<path>...]\n\n          is to see the changes you made relative to the index\n          (staging area for the next commit).  In other words, the\n          differences are what you _could_ tell git to further add\n          to the index but you still haven't.  You can stage\n          these changes by using gitlink:git-update-index[1].\n\n        * 'git-diff' [--options] --cached [<commit>] [--] [<path>...]\n\n          is to see the changes you staged for the next commit\n          relative to the named <tree-ish>.  Typically you would\n          want comparison with the latest commit, so if you do\n          not give <commit>, it defaults to HEAD.\n\n        * 'git-diff' [--options] <commit> -- [<path>...]\n\n          is to see the changes you have in your working tree,\n          regardless of you staged them or not, relative to the\n          named <commit>.\n\n\t* 'git-diff' [--options] <commit> <commit> -- [<path>...]\n\n\t  is to see the changes between two <commit>.\n\n\tJust in case if you are doing something exotic, it\n        should be noted that all of the <commit> in the above\n        descriptoin can be any <tree-ish>.\n\n"},{"id":"298432","messageId":"Pine.LNX.4.64.0611302306120.3695@woody.osdl.org","threadId":"43185","inReplyTo":"20061201045727.GA22622@thunk.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-12-01T07:10:36Z","receivedAt":"2006-12-01T07:10:36Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 30 Nov 2006, Theodore Tso wrote:\n>\n> By the way, after thinking about this for a while, part of the problem\n> is that the name \"index\" really sucks.\n\nHey, it was originally called \"cache\".\n\nI don't care _what_ it's called, I just want people knowing about it, \nbecause hiding it will just cripple git (ie at the very least, when you \nhit a merge conflict, you really do want to to understand it if you ever \nwant to go the the \"next level\").\n\nIf people are more comfortable just calling it the \"staging area\", and \ntalking about it in those terms, I'll be happy.\n\n> Put another way, the reason why I think people are liking the whole\n> \"git add\" and \"git rm\" suggestion is that it's a nice middle ground\n> between the \"hide the index\" and the \"shove the index in the user's\n> face\" approaches.  It's not that we are hiding the fact that there is\n> this thing with the horribly chosen name \"index\", but instead we talk\n> about this concept of a staging area and we don't dwell on things like\n> the fact that it is a binary file which stores an efficient\n> representation of a virtual directory.... blah blah blah.\n\nYes.\n\nAnd even \"git diff\" isn't really a problem once you understand the staging \narea. If people feel worried, let them use \"git diff HEAD\". You won't need \nto use git for _that_ long until you realize that since the staging area \nis going to match the HEAD under normal circumstances (and when it \ndoesn't, you actually tend to prefer to get the diff against the staging \narea _anyway_), you'll find people just starting to use \"git diff\" and not \nworry about it.\n\n"},{"id":"296943","messageId":"Pine.LNX.4.64.0612010223010.20138@iabervon.org","threadId":"43185","inReplyTo":"20061201045727.GA22622@thunk.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2006-12-01T08:10:48Z","receivedAt":"2006-12-01T08:10:48Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 30 Nov 2006, Theodore Tso wrote:\n\n> By the way, after thinking about this for a while, part of the problem\n> is that the name \"index\" really sucks.  Which is perhaps why Linus is\n> now trying to stop us from actually using the term \"index\" in these\n> discussions.  :-)    If we called it a \"staging area\", as our Great\n> Leader has suggested, I think it would be a lot easier for novice\n> users to understand.    Consider what is in the git man page:\n> \n> \tThe index is a simple binary file, which contains an efficient\n> \trepresentation of a virtual directory content at some random\n> \ttime.  It does so by a simple array that associates a set of\n> \tnames, dates, permissions and content (aka \"blob\") objects\n> \ttogether. The cache is always kept ordered by name, and names\n> \tare unique (with a few very specific rules) at any point in\n> \ttime, but the cache has no long-term meaning, and can be\n> \tpartially updated at any time.....\n> \n> \tIn particular, the index file can have the representation of\n> \tan intermediate tree that has not yet been instantiated. So\n> \tthe index can be thought of as a write-back cache, which can\n> \tcontain dirty information that has not yet been written back\n> \tto the backing store.\n> \n> For a kernel programmer, this might not be understandable --- but for\n> your typical application programmer, this is enough to cause him or\n> her to conclude that git is simply not meant for use by mere mortals.\n\nMy position on this subject is that \"index\" is a good name, but that \ndescription is a terrible description, and \"index\" is a word that needs a \ngood description in context. If we just said up front:\n\n Git's \"index\" is a staging area that you use to prepare commits. It maps \n filenames to content. It allows git to remember changes you want to put \n into the next commit while you do more work. For normal commits, it is \n not necessary to use the index, but it is very helpful for complicated \n commits, because it lets you focus on the part you're still working on \n while git remembers the part you're done with.\n\nI think people would get it. (If it were called the \"cache\" still, it \nwould be hopeless, because \"cache\" implies false things; \"index\" doesn't \nimply anything initially.)\n\nOf course, we'd still have to disabuse people of the notion that the index \ncan store the information \"there's nothing at this path yet, but I'm \ninterested in it\", because that's a piece of information people often know \nbefore a file is ready, and think git would be able to remember in a \nstaging area.\n\n\t-Daniel\n"},{"id":"293994","messageId":"200612010937.08468.andyparkins@gmail.com","threadId":"43185","inReplyTo":"Pine.LNX.4.64.0612010223010.20138@iabervon.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2006-12-01T09:37:07Z","receivedAt":"2006-12-01T09:37:07Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"On Friday 2006 December 01 08:10, Daniel Barkalow wrote:\n\n> My position on this subject is that \"index\" is a good name, but that\n> description is a terrible description, and \"index\" is a word that needs a\n> good description in context. If we just said up front:\n\nIf we need to explain what \"index\" means in the context of diff then it's not \na good name :-)\n\nAn index /everywhere else/ is a lookup table.  topic->page number; \nauthor->book title.  record id->byte position.  There is never any content in \nan index, indices just point at content.\n\nI imagine that's how git's index got it's name.  (I'm only guessing as I've \nnot looked at what's actually inside git's \"index\").  Here's my guess:\n\ngit update-index file1 hashes file1, stores it somewhere under that hash and \nwrites the hash->filename connection to .git/index.  That is why git's index \nis called an index.  It's a hash->filename index.\n\nUnfortunately, \"index\" in colloquial git actually means the combination \nof .git/index plus the hashed file itself.  That's no longer an index, it's \na \"book\". :-)\n\nIt's made worse, I think, by the fact that git doesn't want to do any \nindex-like things with the \"index\".  Being content-oriented rather than \nname-oriented means that an entry like \"file1->NOTHING\" is impossible in git.  \nThis leads to the sort of \"git-add means track this filename\" confusion that \nturns up a lot with new users.\n\nIt's probably all too late to change the nomenclature, but I've always been of \nthe opinion that names are important, they confer meaning.  When we use a \ncommon word, with common meaning and deviate from that common meaning we are \nbound to create confusion.  New users don't have any \"git-way-of-thinking\" \nknowledge when they begin, so when they hear \"index\" they can only fall back \non their standard understanding of that word.  We shouldn't be surprised then \nwhen new users don't get \"the index\".\n\n\n\nAndy\n-- \nDr Andy Parkins, M Eng (hons), MIEE\n"},{"id":"294337","messageId":"ekrd8b$re8$1@sea.gmane.org","threadId":"43185","inReplyTo":"Pine.LNX.4.64.0612010223010.20138@iabervon.org","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-12-02T08:26:43Z","receivedAt":"2006-12-02T08:26:43Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Daniel Barkalow wrote:\n\n> Of course, we'd still have to disabuse people of the notion that the index \n> can store the information \"there's nothing at this path yet, but I'm \n> interested in it\", because that's a piece of information people often know \n> before a file is ready, and think git would be able to remember in a \n> staging area.\n\nWell, that was what about the first message in this thread about. Marking\na file \"interesting\" (so 'git commit -a' would pick it up) using all-0\nfor object hash... which of course requires review and if necessary\nmodification of all core tools which touch the index.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"294845","messageId":"ekrdph$tg6$1@sea.gmane.org","threadId":"43185","inReplyTo":"200612010937.08468.andyparkins@gmail.com","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-12-02T08:35:52Z","receivedAt":"2006-12-02T08:35:52Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Andy Parkins wrote:\n\n> On Friday 2006 December 01 08:10, Daniel Barkalow wrote:\n> \n>> My position on this subject is that \"index\" is a good name, but that\n>> description is a terrible description, and \"index\" is a word that needs a\n>> good description in context. If we just said up front:\n> \n> If we need to explain what \"index\" means in the context of diff then it's not \n> a good name :-)\n\nBut \"staging area\" or more descriptive \"staging area for commits\" is\na bit long. But we no longer name the \"index\" \"dircache\".\n\n> An index /everywhere else/ is a lookup table.  topic->page number; \n> author->book title.  record id->byte position.  There is never any content in \n> an index, indices just point at content.\n\nJust like git index.\n\n> I imagine that's how git's index got it's name.  (I'm only guessing as I've \n> not looked at what's actually inside git's \"index\").  Here's my guess:\n> \n> git update-index file1 hashes file1, stores it somewhere under that hash and \n> writes the hash->filename connection to .git/index.  That is why git's index \n> is called an index.  It's a hash->filename index.\n\nThis \"somewhere\" is object repository. And it is reverse: it is \nfilename->(stat + hash) index; from a file in the working area to the blob\n(or tree) in the repository.\n\n> Unfortunately, \"index\" in colloquial git actually means the combination \n> of .git/index plus the hashed file itself.  That's no longer an index, it's \n> a \"book\". :-)\n\nYes, it is true that \"index\" in colloquial git means \"index version\"\n(version pointed by the \"index\").\n\n> It's made worse, I think, by the fact that git doesn't want to do any \n> index-like things with the \"index\".  Being content-oriented rather than \n> name-oriented means that an entry like \"file1->NOTHING\" is impossible in git.  \n> This leads to the sort of \"git-add means track this filename\" confusion that \n> turns up a lot with new users.\n\nIt is possible. By convention all-0 hash means 'no such object'. The very\nfirst message in this thread tried to make use of it... but \"git add\" to\nmark filename as interesting instead of \"git add\" to add _current_ contents\nof the file goes a bit against git ideas.\n\n> It's probably all too late to change the nomenclature, but I've always been of \n> the opinion that names are important, they confer meaning.  When we use a \n> common word, with common meaning and deviate from that common meaning we are \n> bound to create confusion.  New users don't have any \"git-way-of-thinking\" \n> knowledge when they begin, so when they hear \"index\" they can only fall back \n> on their standard understanding of that word.  We shouldn't be surprised then \n> when new users don't get \"the index\".\n\nWell, \"dircache\" was changed to \"index\". \"<ent>\" was axed in preference\nto \"<tree-ish>\". I think using \"staging area\" name in git man pages would\nbe a good idea (as would be making --index to be alias to --cached).\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"298382","messageId":"ekrets$v72$1@sea.gmane.org","threadId":"43185","inReplyTo":"7vhcwgcf39.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] git-add update with all-0 object","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-12-02T08:55:16Z","receivedAt":"2006-12-02T08:55:16Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n>         * 'git-diff' [--options] <commit> <commit> -- [<path>...]\n> \n>           is to see the changes between two <commit>.\n> \n>         Just in case if you are doing something exotic, it\n>         should be noted that all of the <commit> in the above\n>         descriptoin can be any <tree-ish>.\n\ns/descriptoin/description/\n          \nIt _might_ be worth mentioning that you can compare two arbitrary\nfiles using\n\n   git diff [--options] <blob1 sha> <blob2 sha>\n\nwhere <blob sha> can be entered as <tree-ish>:<filename>, usually\n<commit>:<filename> (<filename> is HEAD:<filename>) to compare blob (file)\nfrom a named tree/from a given commit, or as :<stage>:<filename> (or\njust ::<filename> if file is not in merge conflict) to compare blob (file)\nfrom an index.\n\nIf I understand correctly there is currently no way to compare files from a\nworking tree, not to mention files outside working tree\n(including /dev/null) with that syntax.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"}]}