{"id":19070626,"url":"https://github.com/xiaowenxia/git-first-commit","last_synced_at":"2025-04-28T14:27:35.413Z","repository":{"id":125508326,"uuid":"295896483","full_name":"xiaowenxia/git-first-commit","owner":"xiaowenxia","description":"git 第一个提交源码分析","archived":false,"fork":false,"pushed_at":"2020-10-16T05:58:40.000Z","size":24,"stargazers_count":11,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-18T17:19:20.134Z","etag":null,"topics":["c","git"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xiaowenxia.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-16T01:57:44.000Z","updated_at":"2023-11-03T09:12:01.000Z","dependencies_parsed_at":"2023-04-25T18:03:45.111Z","dependency_job_id":null,"html_url":"https://github.com/xiaowenxia/git-first-commit","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiaowenxia%2Fgit-first-commit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiaowenxia%2Fgit-first-commit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiaowenxia%2Fgit-first-commit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiaowenxia%2Fgit-first-commit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xiaowenxia","download_url":"https://codeload.github.com/xiaowenxia/git-first-commit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251328955,"owners_count":21572016,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","git"],"created_at":"2024-11-09T01:19:47.286Z","updated_at":"2025-04-28T14:27:35.392Z","avatar_url":"https://github.com/xiaowenxia.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\tGIT - the stupid content tracker\n\n\"git\" can mean anything, depending on your mood.\n\n - random three-letter combination that is pronounceable, and not\n   actually used by any common UNIX command.  The fact that it is a\n   mispronounciation of \"get\" may or may not be relevant.\n - stupid. contemptible and despicable. simple. Take your pick from the\n   dictionary of slang.\n - \"global information tracker\": you're in a good mood, and it actually\n   works for you. Angels sing, and a light suddenly fills the room. \n - \"goddamn idiotic truckload of sh*t\": when it breaks\n\nThis is a stupid (but extremely fast) directory content manager.  It\ndoesn't do a whole lot, but what it _does_ do is track directory\ncontents efficiently. \n\nThere are two object abstractions: the \"object database\", and the\n\"current directory cache\".\n\n\tThe Object Database (SHA1_FILE_DIRECTORY)\n\nThe object database is literally just a content-addressable collection\nof objects.  All objects are named by their content, which is\napproximated by the SHA1 hash of the object itself.  Objects may refer\nto other objects (by referencing their SHA1 hash), and so you can build\nup a hierarchy of objects. \n\nThere are several kinds of objects in the content-addressable collection\ndatabase.  They are all in deflated with zlib, and start off with a tag\nof their type, and size information about the data.  The SHA1 hash is\nalways the hash of the _compressed_ object, not the original one.\n\nIn particular, the consistency of an object can always be tested\nindependently of the contents or the type of the object: all objects can\nbe validated by verifying that (a) their hashes match the content of the\nfile and (b) the object successfully inflates to a stream of bytes that\nforms a sequence of \u003cascii tag without space\u003e + \u003cspace\u003e + \u003cascii decimal\nsize\u003e + \u003cbyte\\0\u003e + \u003cbinary object data\u003e. \n\nBLOB: A \"blob\" object is nothing but a binary blob of data, and doesn't\nrefer to anything else.  There is no signature or any other verification\nof the data, so while the object is consistent (it _is_ indexed by its\nsha1 hash, so the data itself is certainly correct), it has absolutely\nno other attributes.  No name associations, no permissions.  It is\npurely a blob of data (ie normally \"file contents\"). \n\nTREE: The next hierarchical object type is the \"tree\" object.  A tree\nobject is a list of permission/name/blob data, sorted by name.  In other\nwords the tree object is uniquely determined by the set contents, and so\ntwo separate but identical trees will always share the exact same\nobject. \n\nAgain, a \"tree\" object is just a pure data abstraction: it has no\nhistory, no signatures, no verification of validity, except that the\ncontents are again protected by the hash itself.  So you can trust the\ncontents of a tree, the same way you can trust the contents of a blob,\nbut you don't know where those contents _came_ from. \n\nSide note on trees: since a \"tree\" object is a sorted list of\n\"filename+content\", you can create a diff between two trees without\nactually having to unpack two trees.  Just ignore all common parts, and\nyour diff will look right.  In other words, you can effectively (and\nefficiently) tell the difference between any two random trees by O(n)\nwhere \"n\" is the size of the difference, rather than the size of the\ntree. \n\nSide note 2 on trees: since the name of a \"blob\" depends entirely and\nexclusively on its contents (ie there are no names or permissions\ninvolved), you can see trivial renames or permission changes by noticing\nthat the blob stayed the same.  However, renames with data changes need\na smarter \"diff\" implementation. \n\nCHANGESET: The \"changeset\" object is an object that introduces the\nnotion of history into the picture.  In contrast to the other objects,\nit doesn't just describe the physical state of a tree, it describes how\nwe got there, and why. \n\nA \"changeset\" is defined by the tree-object that it results in, the\nparent changesets (zero, one or more) that led up to that point, and a\ncomment on what happened. Again, a changeset is not trusted per se:\nthe contents are well-defined and \"safe\" due to the cryptographically\nstrong signatures at all levels, but there is no reason to believe that\nthe tree is \"good\" or that the merge information makes sense. The\nparents do not have to actually have any relationship with the result,\nfor example.\n\nNote on changesets: unlike real SCM's, changesets do not contain rename\ninformation or file mode chane information.  All of that is implicit in\nthe trees involved (the result tree, and the result trees of the\nparents), and describing that makes no sense in this idiotic file\nmanager.\n\nTRUST: The notion of \"trust\" is really outside the scope of \"git\", but\nit's worth noting a few things. First off, since everything is hashed\nwith SHA1, you _can_ trust that an object is intact and has not been\nmessed with by external sources. So the name of an object uniquely\nidentifies a known state - just not a state that you may want to trust.\n\nFurthermore, since the SHA1 signature of a changeset refers to the\nSHA1 signatures of the tree it is associated with and the signatures\nof the parent, a single named changeset specifies uniquely a whole\nset of history, with full contents. You can't later fake any step of\nthe way once you have the name of a changeset.\n\nSo to introduce some real trust in the system, the only thing you need\nto do is to digitally sign just _one_ special note, which includes the\nname of a top-level changeset.  Your digital signature shows others that\nyou trust that changeset, and the immutability of the history of\nchangesets tells others that they can trust the whole history.\n\nIn other words, you can easily validate a whole archive by just sending\nout a single email that tells the people the name (SHA1 hash) of the top\nchangeset, and digitally sign that email using something like GPG/PGP.\n\nIn particular, you can also have a separate archive of \"trust points\" or\ntags, which document your (and other peoples) trust.  You may, of\ncourse, archive these \"certificates of trust\" using \"git\" itself, but\nit's not something \"git\" does for you. \n\nAnother way of saying the same thing: \"git\" itself only handles content\nintegrity, the trust has to come from outside. \n\n\tCurrent Directory Cache (\".dircache/index\")\n\nThe \"current directory cache\" is a simple binary file, which contains an\nefficient representation of a virtual directory content at some random\ntime.  It does so by a simple array that associates a set of names,\ndates, permissions and content (aka \"blob\") objects together.  The cache\nis always kept ordered by name, and names are unique at any point in\ntime, but the cache has no long-term meaning, and can be partially\nupdated at any time. \n\nIn particular, the \"current directory cache\" certainly does not need to\nbe consistent with the current directory contents, but it has two very\nimportant attributes:\n\n (a) it can re-generate the full state it caches (not just the directory\n     structure: through the \"blob\" object it can regenerate the data too)\n\n     As a special case, there is a clear and unambiguous one-way mapping\n     from a current directory cache to a \"tree object\", which can be\n     efficiently created from just the current directory cache without\n     actually looking at any other data.  So a directory cache at any\n     one time uniquely specifies one and only one \"tree\" object (but\n     has additional data to make it easy to match up that tree object\n     with what has happened in the directory)\n    \n\nand\n\n (b) it has efficient methods for finding inconsistencies between that\n     cached state (\"tree object waiting to be instantiated\") and the\n     current state. \n\nThose are the two ONLY things that the directory cache does.  It's a\ncache, and the normal operation is to re-generate it completely from a\nknown tree object, or update/compare it with a live tree that is being\ndeveloped.  If you blow the directory cache away entirely, you haven't\nlost any information as long as you have the name of the tree that it\ndescribed. \n\n(But directory caches can also have real information in them: in\nparticular, they can have the representation of an intermediate tree\nthat has not yet been instantiated.  So they do have meaning and usage\noutside of caching - in one sense you can think of the current directory\ncache as being the \"work in progress\" towards a tree commit).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxiaowenxia%2Fgit-first-commit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxiaowenxia%2Fgit-first-commit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxiaowenxia%2Fgit-first-commit/lists"}