{"thread":{"id":"28564","subject":"A Basic Git Question About File Tracking","startedAt":"2011-10-04T00:53:10Z","lastAt":"2011-10-09T16:57:07Z","messageCount":9,"participants":["Jon Forrest","Jonathan Nieder","Jakub Narebski","Scott Chacon"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"176797","messageId":"j6dlhf$dp3$1@dough.gmane.org","threadId":"28564","inReplyTo":null,"subject":"A Basic Git Question About File Tracking","fromName":"Jon Forrest","fromEmail":"nobozo@gmail.com","sentAt":"2011-10-04T00:53:10Z","receivedAt":"2011-10-04T00:53:10Z","isPatch":false,"sender":{"key":"nobozo@gmail.com","avatar":"https://gravatar.com/avatar/37c6a7b57f29b3f35c6a9016537907c52f15bbf98575617dc046bcec6bf06372?d=mp&s=160"},"body":"I've been reading the Pro Git book. I'm having trouble really\nunderstanding the concept of file tracking. Here's where\nmy confusion starts.\n\nThe Pro Git book says \"Untracked basically means that Git sees a\nfile you didn’t have in the previous snapshot (commit)\".\n\nIs this right? I can easily think of a counter example.\nLet's say you put a new file in the working directory of a\nGit repo. Then you \"git add\" it. At this point, the file hasn't\nbeen in any commit. Yet, 'git status' doesn't show the file\nas being untracked. Should that statement be \"Untracked basically\nmeans that Git sees a file you didn’t have in the previous\nsnapshot (commit) or a file that hasn't been staged.\"?\n\nOne additional confusing thing is that \"git add\" apparently\nboth starts tracking a file and puts it in the index the\nfirst time a file is added. Thereafter, \"git add\" only puts\nthe file in the index. One of my research projects is to understand\nwhat goes on internally when a file is tracked.\n\nJon Forrest\n"},{"id":"176798","messageId":"20111004011035.GA13836@elie","threadId":"28564","inReplyTo":"j6dlhf$dp3$1@dough.gmane.org","subject":"Re: A Basic Git Question About File Tracking","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-10-04T01:10:35Z","receivedAt":"2011-10-04T01:10:35Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi!\n\nJon Forrest wrote:\n\n> The Pro Git book says \"Untracked basically means that Git sees a\n> file you didn’t have in the previous snapshot (commit)\".\n\nYep, that's a bug in the Pro Git book.  \"Untracked\" means \"not in\nthe index\", nothing more, nothing less.\n\nI believe Scott takes patches[1]. :)\n\nHope that helps,\nJonathan\n\n[1] https://github.com/progit/progit\n"},{"id":"176799","messageId":"4E8A5DF0.6040003@gmail.com","threadId":"28564","inReplyTo":"20111004011035.GA13836@elie","subject":"Re: A Basic Git Question About File Tracking","fromName":"Jon Forrest","fromEmail":"nobozo@gmail.com","sentAt":"2011-10-04T01:14:24Z","receivedAt":"2011-10-04T01:14:24Z","isPatch":false,"sender":{"key":"nobozo@gmail.com","avatar":"https://gravatar.com/avatar/37c6a7b57f29b3f35c6a9016537907c52f15bbf98575617dc046bcec6bf06372?d=mp&s=160"},"body":"On 10/3/2011 6:10 PM, Jonathan Nieder wrote:\n> Hi!\n\nThanks for the quick reply.\n\n> Jon Forrest wrote:\n>\n>> The Pro Git book says \"Untracked basically means that Git sees a\n>> file you didn’t have in the previous snapshot (commit)\".\n>\n> Yep, that's a bug in the Pro Git book.  \"Untracked\" means \"not in\n> the index\", nothing more, nothing less.\n\nBut your definition doesn't include files that\nhave been committed. In the following trivial case\nin a new git repository\n\ncp /etc/passwd x\ngit add x\ngit commit -m\"fooling around\"\n\nis \"x\" tracked? Your definition says it isn't\nbut \"git status\" makes me think it is.\n\nSorry to be so pedantic.\n\nJon\n"},{"id":"176800","messageId":"20111004012244.GB13836@elie","threadId":"28564","inReplyTo":"4E8A5DF0.6040003@gmail.com","subject":"Re: A Basic Git Question About File Tracking","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-10-04T01:22:44Z","receivedAt":"2011-10-04T01:22:44Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jon Forrest wrote:\n> On 10/3/2011 6:10 PM, Jonathan Nieder wrote:\n\n>> \"Untracked\" means \"not in\n>> the index\", nothing more, nothing less.\n>\n> But your definition doesn't include files that\n> have been committed. In the following trivial case\n> in a new git repository\n>\n> cp /etc/passwd x\n> git add x\n> git commit -m\"fooling around\"\n>\n> is \"x\" tracked? Your definition says it isn't\n> but \"git status\" makes me think it is.\n\nYes, \"x\" is tracked.  Moreover, \"x\" is in the index.  You can\nlist files in the index with the \"git ls-files -s\" command.\n\nDoes that help?\n\n> Sorry to be so pedantic.\n\nNo problem --- it's good to clarify these things (especially if it\nresults in finding documentation that should be clarified, too).\n\nJonathan\n"},{"id":"177254","messageId":"4E90E60C.7060105@gmail.com","threadId":"28564","inReplyTo":"20111004012244.GB13836@elie","subject":"Re: A Basic Git Question About File Tracking","fromName":"Jon Forrest","fromEmail":"nobozo@gmail.com","sentAt":"2011-10-09T00:08:44Z","receivedAt":"2011-10-09T00:08:44Z","isPatch":false,"sender":{"key":"nobozo@gmail.com","avatar":"https://gravatar.com/avatar/37c6a7b57f29b3f35c6a9016537907c52f15bbf98575617dc046bcec6bf06372?d=mp&s=160"},"body":"On 10/3/2011 6:22 PM, Jonathan Nieder wrote:\n\n[I'm just getting back to this question. I had accidentally\nsent this follow up directly to Jonathan but I want to\ncontinue this on the email list.]\n\n> Yes, \"x\" is tracked.  Moreover, \"x\" is in the index.  You can\n> list files in the index with the \"git ls-files -s\" command.\n\nThis spoils my understanding of what the index\nis. I had been thinking that after you add files\nto the index, and then commit, the index is then\nempty. In other words, whatever's in the index\ngets committed, and then the index is cleaned.\n\nOn the other hand, if the definition of a tracked\nfile is a file that's in the index, then this definitely\nclears up my understanding of tracked files.\n\nIf every file that's 'git add'ed stays in the\nindex, how does git know which files to commit?\n\nI can't prove it but I suspect that many git beginners\nalso are confused by this.\n\nThanks for your replies.\n\nJon Forrest\n"},{"id":"177255","messageId":"m3ipnz0xri.fsf@localhost.localdomain","threadId":"28564","inReplyTo":"4E90E60C.7060105@gmail.com","subject":"Re: A Basic Git Question About File Tracking","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-10-09T01:17:41Z","receivedAt":"2011-10-09T01:17:41Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jon Forrest <nobozo@gmail.com> writes:\n\n> On 10/3/2011 6:22 PM, Jonathan Nieder wrote:\n> \n> [I'm just getting back to this question. I had accidentally\n> sent this follow up directly to Jonathan but I want to\n> continue this on the email list.]\n> \n> > Yes, \"x\" is tracked.  Moreover, \"x\" is in the index.  You can\n> > list files in the index with the \"git ls-files -s\" command.\n> \n> This spoils my understanding of what the index\n> is. I had been thinking that after you add files\n> to the index, and then commit, the index is then\n> empty. In other words, whatever's in the index\n> gets committed, and then the index is cleaned.\n> \n> On the other hand, if the definition of a tracked\n> file is a file that's in the index, then this definitely\n> clears up my understanding of tracked files.\n> \n> If every file that's 'git add'ed stays in the\n> index, how does git know which files to commit?\n> \n> I can't prove it but I suspect that many git beginners\n> also are confused by this.\n\nYou seem to be under [false] impression that git commit is about\n_changes_ / _changeset_.\n\nIt is not true.  What is stored in git commit object is (pointer to)\n_snapshot_ of a state of a project at given time.  This means that\n\"git commit\" creates a tree object out of state of the index, and\ncreates commit object that points to said newly created tree, and has\nversion you started work from as its parent.  It is commit remember\nthe previous version that allows to turn commit into changeset.\n\nHopefully that would clear up your confusion.\n-- \nJakub Narębski\n"},{"id":"177257","messageId":"4E910A14.7040801@gmail.com","threadId":"28564","inReplyTo":"m3ipnz0xri.fsf@localhost.localdomain","subject":"Re: A Basic Git Question About File Tracking [ANSWERED]","fromName":"Jon Forrest","fromEmail":"nobozo@gmail.com","sentAt":"2011-10-09T02:42:28Z","receivedAt":"2011-10-09T02:42:28Z","isPatch":false,"sender":{"key":"nobozo@gmail.com","avatar":"https://gravatar.com/avatar/37c6a7b57f29b3f35c6a9016537907c52f15bbf98575617dc046bcec6bf06372?d=mp&s=160"},"body":"On 10/8/2011 6:17 PM, Jakub Narebski wrote:\n\n> You seem to be under [false] impression that git commit is about\n> _changes_ / _changeset_.\n\nThis is correct. The Pro Git book says:\n\n\"You stage these modified files and then commit\nall your staged changes\"\n\nPlus, even \"git status\" tells me\n\n$ git status\n# On branch master\n# Changes to be committed:\n\nBut I see my error. Below is what I hope is a clear\nexplanation of what I didn't understand. It presumes\nthat the reader understands the git objects model.\nPlease let me know if anything is incorrect.\n----------\nWhen you \"git add\" a file two things happen:\n\n1) The file is copied to the git objects tree.\nThis location where the file is copied depends\non the hash of the file's content.\n\n2) An entry for the file is added to the git index.\nThis entry includes the same hash that was mentioned\nin #1.\n\nA tracked file has an entry in the git index file.\nA copy of the file also exists in the objects tree.\n\nWhen you run 'git status', git computes the hash of\nevery file in your working directory and looks\nup each file in the index. If the file isn't found\nthen the file is shown as untracked.\n\nWhen you do a commit, the hash values of everything\nin the index are copied into a tree object. The hash\nvalue of the tree object is then placed in a commit object.\nNo copies of tracked files in the working directory are\nmade at commit time. This is because the files were already\ncopied into the objects tree when 'git add' was run.\nThis is one reason why git commits are so fast.\n\n-----\n\nHow's that?\n\nThanks to everyone for sticking with me on this.\n\nJon\n"},{"id":"177269","messageId":"201110091137.34788.jnareb@gmail.com","threadId":"28564","inReplyTo":"4E910A14.7040801@gmail.com","subject":"Re: A Basic Git Question About File Tracking [ANSWERED]","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-10-09T09:37:33Z","receivedAt":"2011-10-09T09:37:33Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sun, 9 Oct 2011, Jon Forrest wrote:\n> On 10/8/2011 6:17 PM, Jakub Narebski wrote:\n> \n> > You seem to be under [false] impression that git commit is about\n> > _changes_ / _changeset_.\n> \n> This is correct. The Pro Git book says:\n> \n> \"You stage these modified files and then commit\n> all your staged changes\"\n> \n> Plus, even \"git status\" tells me\n> \n> $ git status\n> # On branch master\n> # Changes to be committed:\n\nWell, that is because the two representations: delta / changeset\n(\"differential\") representation and snapshot (\"integral\") representation\nare related, and [in practice] one can be transformed into the other.\n\nSometimes it is better to think about commit as representing changeset\nfrom parent commit, sometimes it is better to think of a commit as of\nsnapshot of a state of project.\n\nBut under the hood git model is snapshot-based.\n\n> But I see my error. Below is what I hope is a clear\n> explanation of what I didn't understand. It presumes\n> that the reader understands the git objects model.\n> Please let me know if anything is incorrect.\n> ----------\n> When you \"git add\" a file two things happen:\n> \n> 1) The file is copied to the git objects tree.\n\nActually it is file _contents_ that is copied to git object _store_.\n\n> This location where the file is copied depends\n> on the hash of the file's content.\n\nI'd say that this is unnecessary implementation detail of \"loose\"\nobject format.  I would say that _identifier_ of added object is\nbased on its contents.\n\n> \n> 2) An entry for the file is added to the git index.\n> This entry includes the same hash that was mentioned\n> in #1.\n\nYes.\n \n> A tracked file has an entry in the git index file.\n\nYes.\n\n> A copy of the file also exists in the objects tree.\n\nA copy of a _contents_ of a file at specific point of time\nexists in object _store_ (not necessary object tree, as it\ncan be packed).\n \n> When you run 'git status', git computes the hash of\n> every file in your working directory and looks\n> up each file in the index. If the file isn't found\n> then the file is shown as untracked.\n\nSidenote: git stores in the index also stats of a file (modification\ntime etc.) so it is possible to avoid recomputing the hash of every \nfile.\n \n> When you do a commit, the hash values of everything\n> in the index are copied into a tree object. The hash\n> value of the tree object is then placed in a commit object.\n\nTrue, though I would probably state it a bit differently.\n\n> No copies of tracked files in the working directory are\n> made at commit time. This is because the files were already\n> copied into the objects tree when 'git add' was run.\n> This is one reason why git commits are so fast.\n\nWell, there is also \"git commit -a\", but it is true that git\ncopies into object store only those tracked files that changed.\n\nAlso I think that the main reason that git commits are fast is\nthat they are local operation, and not over the network as in the\ncase of centralized version control systems.\n \n-- \nJakub Narebski\nPoland\n"},{"id":"177279","messageId":"CAP2yMaLKxtN-i6XikBTd9XeJ9_5HnAMxj=VnPMU=WsMNb6MsYw@mail.gmail.com","threadId":"28564","inReplyTo":"m3ipnz0xri.fsf@localhost.localdomain","subject":"Re: A Basic Git Question About File Tracking","fromName":"Scott Chacon","fromEmail":"schacon@gmail.com","sentAt":"2011-10-09T16:57:07Z","receivedAt":"2011-10-09T16:57:07Z","isPatch":false,"sender":{"key":"schacon@gmail.com","avatar":"https://gravatar.com/avatar/9b13a8a078e1dcf8588c4eea9554445d51ebed6c41b51f56f4d96738130b05c6?d=mp&s=160"},"body":"Jon,\n\n2011/10/8 Jakub Narebski <jnareb@gmail.com>:\n>> This spoils my understanding of what the index\n>> is. I had been thinking that after you add files\n>> to the index, and then commit, the index is then\n>> empty. In other words, whatever's in the index\n>> gets committed, and then the index is cleaned.\n>>\n>> On the other hand, if the definition of a tracked\n>> file is a file that's in the index, then this definitely\n>> clears up my understanding of tracked files.\n>>\n>> If every file that's 'git add'ed stays in the\n>> index, how does git know which files to commit?\n\nIt may help to read a blog post I put on the Pro Git blog called\n\"Reset Demystified\" that talks about a simplified model of the HEAD,\nindex and working directory.\n\nhttp://progit.org/2011/07/11/reset.html\n\nLet me know if that helps.  And you're right, the book should say \"not\nin the index\" rather than \"not be in the last commit\", that would be\nmore technically correct. I think at that point in the book I have not\ngone into any details about the index yet, so it would be confusing\nwithout more detail.\n\nthanks,\nScott\n"}]}