3 ms·
A commit is not deltas. It contains a hash of a tree object, which in turn contains a list of hashes of blob and tree objects. The tree hashes are of course o
by godd2 10y ago
A commit is not deltas. It contains a hash of a tree object, which in turn contains a list of hashes of blob and tree objects. The tree hashes are of course of tree objects which are your subdirectories, and the blob hashes are the hashes of your full files. When you make a change to a file, and then add it, git saves the new file as a full copy, and gives it its own sha1 hash.
If you go into `.git/objects` and find the file whose name is the hash of your most recent commit, you can decompress it (zlib inflate) and the first few characters of the file will be something like "commit 485\0tree 6f3eeb2952a...". This tell us that this object is a commit object of size 485 bytes, and then after the null character is the commit itself. If you then take that tree hash and do the same thing, you'll see a list of blob hashes next to filenames, and tree hashes next to directory names (in a tree object, git stores the hashes as the raw bits, instead of ascii encoded, so if you want to follow the hash list, you'll have to convert the hashes to their ascii equivalent to find the appropriate object in the object store).
You are correct that git uses deltas, but it doesn't use them for commits, it uses them when it recompresses your objects into a packfile (which happens when there are too many loose objects or when you pull and push).
Every commit can reconstruct the state of your project at the time the commit was made. Each commit can do this without the help of any other commit.
- antocv 10y agoWow, that is informative, did not know. Thanks to you, and others!
- godd2 10y agoNo problem! :) Once I understood this, things like merging and shallow clones made a lot more sense. Although it makes rebasing more confusing. What's happening there is that git is creating patches on the fly, and then applying them to the new base, and creating new commits. But the resulting commits are snapshots of what the files would have been had you applied the patches yourself. Of course, there can still be "merge conflicts" since both branches might make changes to the same place in the same file. But since everything is a snapshot, if you have no pending changes in your working directory, hopping around the commit history is a safe action, so long as you have a branch pointing to where you left off.
- adrianN 10y agoConsider reading the article.
- godd2 10y agoI don't think it's fair to assume they didn't read the article. It's difficult to know when an explanation is succinct vs analogous, especially if you have a working model of knowledge. "A is just B" can mean more than one thing.