{"thread":{"id":"19141","subject":"Why is the name of a blob SHA1(\"$type $size\\0$data\") and not SHA1(\"$data\")?","startedAt":"2009-04-30T19:55:00Z","lastAt":"2009-04-30T22:57:33Z","messageCount":3,"participants":["David Srbecky","Shawn O. Pearce","Björn Steinbrink"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"112787","messageId":"49FA0214.70009@gmail.com","threadId":"19141","inReplyTo":null,"subject":"Why is the name of a blob SHA1(\"$type $size\\0$data\") and not SHA1(\"$data\")?","fromName":"David Srbecky","fromEmail":"dsrbecky@gmail.com","sentAt":"2009-04-30T19:55:00Z","receivedAt":"2009-04-30T19:55:00Z","isPatch":false,"sender":{"key":"dsrbecky@gmail.com","avatar":null},"body":"Hi,\n\n\nFirst of all, congratulations on makeing such a great version control \nsystem.  I love the storage model - in comparison with other systems, it \nis just birantly simple and ingenious.\n\n\nI started digging into the details and there is one thing that is really \nbugging me - why is the name of a blob SHA1(\"$type $size\\0$data\") and \nnot SHA1(\"$data\")?  I mean, wouldn't it be beautiful if the name of the \nblob would really just be the SHA1 of the uncompressed file content? :-)\n\n\nFurthermore, is the header really necessary?  Wouldn't it be \neqvivalently effective to put the blobs into own subdirectory? For \nexample:  .git\\objects\\blob\\22\\22a3d28c5b2fca0eae83be1a2ed619e357f6a1e6\nSo the blob would contatin just be the compressed content and nothing \nelse - beautiful :-)\n\n\nI would really appriciate some comments on the design decisions so that \nI can sleep well at night :-)\n\n\nDavid\n"},{"id":"112788","messageId":"20090430200217.GU23604@spearce.org","threadId":"19141","inReplyTo":"49FA0214.70009@gmail.com","subject":"Re: Why is the name of a blob SHA1(\"$type $size\\0$data\") and not SHA1(\"$data\")?","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-04-30T20:02:17Z","receivedAt":"2009-04-30T20:02:17Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"David Srbecky <dsrbecky@gmail.com> wrote:\n>\n> I started digging into the details and there is one thing that is really  \n> bugging me - why is the name of a blob SHA1(\"$type $size\\0$data\") and  \n> not SHA1(\"$data\")?  I mean, wouldn't it be beautiful if the name of the  \n> blob would really just be the SHA1 of the uncompressed file content? :-)\n\nWell, a commit is stored in the same namespace as a blob (file\ncontent).  So the type being included in the SHA1 computation helps\nto break them apart and say \"this is really a commit\" vs. \"this\nis a file that just happens to have the same content as a commit\".\nIt does help consistency checkers like `git fsck` to know that the\nobject is used in the right context.\n\nI can't guess what Linus had in mind when he wrote Git, but I would\nwager it was something along the lines that storing everything in\na single directory structure was simpler/more elegant than having\na different directory structure per object type.  Today I would\nprobably have made the same design decision, but I'm biased by\nGit already so who knows if I'm just mimicing Linus' brilliance or\nwould have arrived at the same result myself.\n\nIncluding the length is overkill, yes, but its in the header of the\ndata so that git can immediately allocate a properly sized memory\nbuffer before it inflates the rest of the object content.  Its a\nperformance improvement.  Its probably a historical accident that\nit got included in the SHA1 computation, as notice its position\nbetween the type and the data... it likely was just easier to\ninclude it in the SHA1 than to exclude it.\n\n> I would really appriciate some comments on the design decisions so that  \n> I can sleep well at night :-)\n\nThen I won't mention pack files... which aren't as simple to read\nas just inflating a file on disk.  :-)\n\n-- \nShawn.\n"},{"id":"112793","messageId":"20090430225733.GC18940@atjola.homenet","threadId":"19141","inReplyTo":"49FA0214.70009@gmail.com","subject":"Re: Why is the name of a blob SHA1(\"$type $size\\0$data\") and not SHA1(\"$data\")?","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-04-30T22:57:33Z","receivedAt":"2009-04-30T22:57:33Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.04.30 20:55:00 +0100, David Srbecky wrote:\n> Hi,\n>\n>\n> First of all, congratulations on makeing such a great version control  \n> system.  I love the storage model - in comparison with other systems, it  \n> is just birantly simple and ingenious.\n>\n>\n> I started digging into the details and there is one thing that is really  \n> bugging me - why is the name of a blob SHA1(\"$type $size\\0$data\") and  \n> not SHA1(\"$data\")?  I mean, wouldn't it be beautiful if the name of the  \n> blob would really just be the SHA1 of the uncompressed file content? :-)\n>\n>\n> Furthermore, is the header really necessary?  Wouldn't it be  \n> eqvivalently effective to put the blobs into own subdirectory? For  \n> example:  .git\\objects\\blob\\22\\22a3d28c5b2fca0eae83be1a2ed619e357f6a1e6\n> So the blob would contatin just be the compressed content and nothing  \n> else - beautiful :-)\n\nYes, at least the type is pretty important. Consider just \"git show\n$some_object_name\". If the object name was just the hash of the\ncontents, you could have a blob and a commit with the same name. Which\nis which? And which do you mean in that command? The command line\ninterface would need to accept a type in addition to the object name in\na lot of place.\n\nAnd in packs, you want the objects ordered so that you get could access\npatterns, and don't read from all over the pack file. That means that\nyou would need the type header there, regardless of whether it is in the\nloose object file.\n\nBjörn\n"}]}