Git Objects: commits within trees.
- Dominant language
- No language data
- Stars
- 328
- Forks
- 12
- PR merge metrics
- No merged PRs in 30d
Description
(This is a realization i made while designing IPFS. Explaining it here because I'll need to refer to it. Excuse the meandering between too little and too much exposition. Not clear to me what I should and shouldn't assume the readers know).
Traditionally, Git commits point to trees (and other commits). Trees don't point to commits. This is a useful design as it keeps the commit tree somewhat separate from the file objects. Walking/manipulating the commit dag is simple.
This design choice becomes problematic when handling submodules, or the repositories themselves. Using submodules is notoriously annoying, because the model makes assumptions on the workflow (submodules are _other things_ from some _other space_). Repos themselves aren't tracked within git. ("what!?" _you say_. "What does that even mean!?")
### Repository objects
Imagine the Repository as a first-class git object, something like this:
```
head a906cb2a4a904a152e80877d4088654daad0c859 master
head 8f94139338f9404f26296befa88755fc2598c289 dev
tag 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 v1.2.0
tag 495d50ddb02dfb149c808cf5491f9ba696285a92 v1.1.0
tag 31ee3269618939b37049251d79e9edd52c67d051 v1.0.0
```
Mapping ref names to commit hashes. A collection of entries, with an entry format like:
```
```
This is really just a more complicated `tree` object. Example tree:
```
100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
```
The tree is a collection of entries, with an entry format like:
```
```
(From now on, ignore the unix perms.) These are the same! So a `repo` object is really just a privileged `tree` object that gets to point to commits. That seems to me like a bad lack of generality. What if all trees could point to commits?
You'd unlock a host of new workflow patterns within the object commit graph, and make submodules first-class things.
- submodules are just repos + a pointer[1] to its origin, for updates.
- version each file independently (not heresy, there are use cases for this).
- repos themselves can be tracked. When you manipulate a repo (update the index, etc), those changes can be versioned too (reflog).
- reflog becomes just a meta commit graph.
It's ~~turtles~~ commits all the way down.
Takeaway: let trees point to commits.
---
[1] saying pointer here, and not url, because this can be a hash. Why is it a url? Because git is built to operate within a single machine, with a completely separate blobstore from all other git blobstores. If you change that -- if you make _one blobstore to store them all_ -- then the url can be a _hash_ to another object in the blobstore. (italics on hash because it's not a hash of the value of the object (not content-addressed). It has to be a symlink (mutable object).
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.