Git
Git isn't a pile of commands, it's four object types and a graph. Learn the model with plumbing and the porcelain (merge, rebase, reset) stops being frightening.
Git stores content as blobs, named by the SHA of the content itself. Same bytes → same hash, always.
Hash a string two different ways and compare.
$ echo hi | git hash-object --stdinWrite the same content to a file and git hash-object it — identical hash. Content-addressing, first-hand.
Reveal solution
$ git init demo && cd demo $ echo hi | git hash-object --stdin $ printf hi | git hash-object --stdin - # note: differs, trailing newline matters
Staging builds a tree (a directory snapshot); a commit is a tiny object pointing at one tree plus parent + author.
Stage a file, write the tree, and read it back.
$ git cat-file -p $(git write-tree)The tree lists your file as a blob. A commit is just this tree, wrapped with metadata.
Reveal solution
$ echo hello > f $ git add f $ git write-tree $ git cat-file -p $(git write-tree)
A branch is a 41-byte file holding one commit SHA. "Switching branches" moves a pointer — nothing is copied.
Commit, branch, and prove both refs point at the same commit.
$ cat .git/refs/heads/main .git/refs/heads/featureBoth files contain the same SHA. That's all a branch is.
Reveal solution
$ git commit -m first $ git branch feature $ cat .git/refs/heads/main $ cat .git/refs/heads/feature
Reach engineers who read the man page
Native, contextual, no tracking — this is how the curriculum stays free.
A hard reset seems to destroy work. It doesn't — the commit is still in the object store, and the reflog remembers where HEAD has been.
Make a commit, hard-reset past it, then bring it back.
$ git log --oneline -1After reset --hard to the reflog SHA, your "lost" commit is back at the tip. The reflog is your safety net.
Reveal solution
$ echo more >> f && git commit -am second $ git reset --hard HEAD~1 # "lose" it $ git reflog # find the second commit's SHA $ git reset --hard <sha-of-second>
Blobs, trees, commits, refs — plus the reflog. Once you see Git as objects in a graph, rebases and merges are just re-pointing the graph, and you can always recover. This model is the foundation for GitHub Actions and GitOps.