{"thread":{"id":"50","subject":"Proposal for simplification and impovement of the git model","startedAt":"2005-04-16T13:35:24Z","lastAt":"2005-04-16T13:35:24Z","messageCount":1,"participants":["Luca Barbieri"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"303","messageId":"4261149C.7030704@gmail.com","threadId":"50","inReplyTo":null,"subject":"Proposal for simplification and impovement of the git model","fromName":"Luca Barbieri","fromEmail":"luca.barbieri@gmail.com","sentAt":"2005-04-16T13:35:24Z","receivedAt":"2005-04-16T13:35:24Z","isPatch":false,"sender":{"key":"luca.barbieri@gmail.com","avatar":null},"body":"In this message, a method to simplify and at the same time make more\npowerful the git abstraction is presented.\n\nI believe that the enhancements I propose make git adhere even more to\nits \"spirit\" and make it more intuitive.\n\nThe proposal makes it much easier to build an SCM over git, obtaining in\nparticular the following advantages:\n\n- Blob and tree objects become symmetric\n\n- Commit objects are removed (their data is put inside tree objects)\n\n- Commit comments are per-file\n\n- A tree in a repository looks like a repository itself, with full\nversion information (now only the one mentioned in the commit object has\nversion information)\n\n- File and directory renames are tracked\n\n- Renames are tracked regardless of the way they are made (even with cp\nand rm)\n\n- Commit comments can be updated at any time by whoever made the change\n\n- Doing the \"blame\" operation is trivial\n\n- Minimizing disk space usage (at the expense of speed) by storing diffs\nis easily doable\n\n\n\nThe basic idea is that rather than having single blob or tree revisions\nas the base concept, the abstract base unit is the whole set of\nmodifications, with comments, leading to that state.\n\nOf course, tracking that would be extremely space-inefficient, so we\ninstead track the current file contents, plus the public key of the\nauthor and the hashes of all parents.\n\n\nThis is implemented with the following changes to git:\n\n\n- The commit object is removed\n\n\n- Each tree must have a \".git-commit\" file that contains the information\npreviously in the commit object (only for immediate children, thus\nhaving a \".git-commit\" file in each directory), but with the author\npublic key instead of the comments\n\n\n- Each blob will be hashed as the blob contents plus an header in a\ncanonical format that contains data similar to the data in the\n\".git-commit\" file\n\n\n- When checked out, the blob header is put in a C/C++ comment, a #\ncomment, or if the file format is unknown, in an extended attribute or a\nseparate file\n\nAn example of a C/C++ file with metadata is the following:\n\n// @parent<SHA1_OF_PARENT1> @parent<SHA1_OF_PARENT2>\n// @author<FINGERPRINT_OF_AUTHOR_PUBLIC_KEY>\n#include <stdlib.h>\n\nint main(int argc, char** argv)\n{\n\tprintf(\"Hello, world!\\n\");\n\treturn 0;\n}\n\nNote that @parent<> and @author<> in checked out files are NOT the same\nof the ones in the repository but are crafted so that there is a single\n@parent pointing to the repository file and @author is taken from\n$HOME/.gitrc\n\n\n- When the file is checked in, the header is parsed and removed.\n\n*  If there is a single parent, its header is added and the resulting\nbuffer is hashed and compared with the parent's hash. If equal, the file\nis unchanged and not committed.\n\n* Otherwise, the header data is added in a canonical format and the\nbuffer is hashed and committed\n\n\n- A new class of objects is added, that is not named by their hash, but\nrather by a public key (or fingerprint of it), a timestamp and a name.\n\nThe object is correct if and only if the contents plus name and\ntimestamp are signed with the private key corresponding to public key in\nthe name.\n\nObject names are formatted as \"<id>/<name>/<args>\" where <url> is an\nuuid or url that makes the <id>/<name> unique, <name> is the name, and\n<args> is additional data.\n\nFile names formatted like \"git/c/<sha1>\" are interpreted as commit\ncomments for object <sha1>.\n\n\n- For storage or network transmission purposes, a binary diff against\nthe parents can be stored instead of the contents af an object. This\nwill of course require to walk the whole history to rebuild it, but\nsmarter schemes are possible (e.g. \"keyframes\", \"jump diffs\", etc.).\n\n"}]}