Every object id you compute matches real Git byte for byte, so you can cross-check with git hash-object and git cat-file at every step. Each lesson is one concrete spec with exact hex ids and byte layouts: the empty blob e69de29, hello.txt hashing to ce013625, a tree that sorts directories as if they end in a slash, a commit that reproduces its exact 40-hex id under a fixed author and timestamp, a symbolic HEAD resolving through a branch ref, and a two-commit log walking child to parent.
Over 41 lessons you build the core of Git from first principles: a content-addressable object database in which every object is stored under the SHA-1 hash of its own contents. The remarkable payoff is that the ids you compute match real Git exactly, so at every step you can cross-check your work with git hash-object and git cat-file, and the objects your library writes can be read back by real git.
You start with the loose object format and blobs, hashing file contents to the exact 40-hex ids Git produces. Then you build tree objects that encode directories (with the subtle rule that a directory sorts as if its name ended in a slash), a staging index and a write-tree that turns it into nested tree objects, commit objects that reproduce their exact id under a fixed author and timestamp, refs and a symbolic HEAD with a log that walks the parent chain, and a simplified status that classifies files as added, modified, or unchanged. The capstone runs a full session: initialise a repository, stage and commit a few files including one in a subdirectory, make a second commit, and assert every exact blob, tree, and commit id along with the branch ref and the log walk.
This is a teaching-grade Git built around the object model, the Merkle DAG, and the index: a real library with a mini-git command line that stores into its own object directory. It deliberately stops short of the machinery real Git layers on top - it uses stdlib SHA-1 and zlib as plumbing rather than reimplementing them, has no packfiles or delta compression, no diff, merge, or network transport, a simplified index serialization, and a checkout that retargets HEAD rather than materialising the working tree. What it does build is the honest heart of Git: the object store, trees, the index, commits, refs, and the commit graph.
Git is really a little database that stores every version of everything under the hash of its contents. That database lives in a directory, so before we can store a single object we need to create that directory. Today you initialise a repository.
Create a repository rooted at a directory, with an object database directory inside it.
Real Git keeps everything under a hidden .git directory, and the heart of it is
.git/objects - a plain directory of files where every version of every file,
every directory listing, and every commit is stored. There are no fancy formats
at the top level: it is a filesystem folder full of content-addressed blobs. We
will use .mygit instead of .git so our tool never touches a real repository’s
data by mistake.
Today is deliberately tiny: create the repository directory and the objects
directory inside it. That folder is where every object we build for the rest of
the project will be written. Keeping our data under our own .mygit directory,
never the real .git, is a safety rule we hold to the whole way through.
// the object database is just a directory of filesfunc Init(root string) error {objects := filepath.Join(root, ".mygit", "objects")return os.MkdirAll(objects, 0o755)}
A genuinely working, teaching-grade Git core whose blob, tree, and commit ids match real Git byte for byte - so git cat-file can read the very objects it writes - with a content-addressable object store, nested trees, a staging index and write-tree, commits with parents, refs and a symbolic HEAD, log, branching, and a simplified status, all driven by a small reproducible mygit command line and demo; it stops at the plumbing layer, with no working-tree checkout, no diff or merge, no packfiles or delta compression, and no network transport.
The canonical explanation of Git as a content-addressable filesystem: loose objects, blobs, trees, commits, refs, and HEAD, worked through with the plumbing commands (hash-object, cat-file, write-tree, commit-tree) this project rebuilds.
A full book that reimplements Git from scratch in Ruby, object by object. The definitive long-form companion to this project, covering the exact loose-object, tree, and commit encodings, then going on to diffs, merges, and packs.
A compact hands-on tutorial building a working git clone (wyag) in Python. Excellent, concise coverage of the object format, the fan-out storage layout, trees, refs, and the commit graph.
The official reference for the on-disk formats: the index (staging area) binary layout and the .git directory layout (objects, refs, HEAD). Read it to see how far real Git goes beyond the simplified index this project uses.
A classic essay that explains Git by starting at the object store and building up to branches and the reflog. The clearest short account of why blobs, trees, and commits are all just content-addressed objects.