After this lesson, you will be able to: Understand what commits, trees, and blobs actually are inside .git, and why that mental model makes merges, rebases, and recovery commands stop being magic.
Most engineers use Git as a set of incantations. Engineers who understand the underlying object model (commits, trees, blobs) debug Git problems in seconds instead of asking on Slack for an hour.
This is a free introductory lesson. No purchase required.
Blob: the contents of a single file at a point in time. Identified by a SHA-256 hash of the contents. Same content = same hash = stored once. Tree: a snapshot of a directory. Contains pointers to blobs (files) and other trees (subdirectories), plus file names and modes. Commit: a tree + parent commit(s) + author + timestamp + message. Identified by a SHA of all that data. The chain of commits IS your repo history.
Open any git repo and run these. The output tells the same story this lesson does.
# Show the SHA of HEADgit rev-parse HEAD# Show what HEAD points to (a commit object)git cat-file -t HEAD # outputs 'commit'git cat-file -p HEAD # shows the commit: tree + parent + author + msg# Follow the tree pointergit cat-file -p HEAD^{tree} # lists files + blob SHAs# Read a single file blob by SHAgit cat-file -p <blob-sha> # outputs the raw file content# See ALL objects (commits + trees + blobs) packed in .gitls -lh .git/objects/pack
A merge creates a new commit with two parents (your branch + the branch you merged in). The new tree is the result of combining both. A rebase rewrites each of your commits on top of a new parent, creating NEW commits with NEW SHAs. The old ones still exist in .git until garbage collection, which is why `git reflog` can recover them. Understanding this makes 'I just lost a branch' a 30-second fix (`git reflog` + `git reset --hard <old-sha>`) instead of a panic.
Whenever HEAD points to a commit instead of a branch (e.g. `git checkout <sha>`), you're in detached HEAD. New commits made here aren't reachable from any branch and look 'lost' once you switch away. `git reflog` is your time machine: every move HEAD makes is logged for 90 days by default. If you ever think you've lost work after a `reset --hard` or a bad rebase, the answer is almost always `git reflog` + `git reset --hard HEAD@{n}`.
Practice in a throwaway repo. Knowing you can recover removes the fear of using Git boldly.
Create a new repo: mkdir gitlab && cd gitlab && git init
Add a file and commit it: echo a > a.txt && git add a.txt && git commit -m 'first'
Make a second commit: echo b >> a.txt && git commit -am 'second'
Note HEAD: git log --oneline
Simulate disaster: git reset --hard HEAD~1 (you 'lose' the second commit)
Find it: git reflog (the 'second' commit is in the log)
Recover: git reset --hard HEAD@{1}
Verify: git log --oneline shows both commits again
Treating the staging area (index) as confusing magic. It's a third tree (working dir, index, HEAD) and `git status` shows the diff between them. Once you see it as three trees, it becomes obvious. Running `git rm` or `rm` on the wrong file and panicking. Files in .git/objects survive even when removed from the working tree; recover with `git checkout HEAD -- <file>`. Force-pushing without thinking about who else is on the branch. Force-push only after you understand reflog can save the receiver. Believing 'lost' work is gone. Until git gc runs (typically 30-90 days), it isn't.
Pick the most precise answer.