How Git Thinks
The object model, what git actually stores
Commits & the Object Model
Open a real `.git/objects/` store, tell a blob, tree, and commit apart by what each holds, and predict why two identical files collapse to one hash.
Refs & HEAD
Read the one line inside a branch file and the ref: line inside `.git/HEAD`, then predict which single file a commit changes versus a switch, and why detached HEAD is a shape rather than a break.
The Commit Graph (DAG)
Follow the hash each commit stores for the one before it to trace the whole graph, then slide a ref off a commit and watch the object survive on disk, reachable through the reflog until garbage collection's grace period lapses.
Everyday Git
Staging, tracking, history, and setting aside work
The Staging Area
Track one file across the working tree, `.git/index`, and your last commit, decode the two columns of `git status`, stage a single hunk with `git add -p`, and know what `.gitignore` can and cannot untrack.
Reading History
Reconstruct every `git log`, `git diff`, `git blame`, and `git grep` result by hand as a walk over the commit snapshots, and see why re-reading history never adds a byte to `.git/`.
Tags & Releases
Pin a release to one commit with a tag that never moves, choose lightweight or annotated by the metadata it stores, read what each writes to `.git/refs/tags/` and `.git/objects/`, decode the `git describe` string, and number releases with semantic versioning.
Stash & Worktrees
Stash edits into the two-parent commit git writes under `.git/refs/stash`, restore them with apply (keeps the entry) or pop (erases it), and open a second `git worktree` that shares one object store while keeping its own HEAD and index.
Branching & Merging
Parallel work and bringing it together
Branching
Write one 41-byte file to branch with nothing copied, watch a switch rewrite every working file to another snapshot while your commits hold still, drive two branches into divergence, and see why `-d` refuses before it strands a commit.
Merging
Drive two branches to divergence and watch one reachability check pick the write: a reachable tip fast-forwards a 41-byte ref with no new commit, a diverged tip builds a merge commit with two `parent` lines, and standing on the other branch swaps which is first parent.
Merge Conflicts
Halt a merge on one overlapping line, read the disagreement as marker blocks, three index stages, and a MERGE_HEAD flag, flip between merge, diff3, and zdiff3 rendering, then stage the fix into a two-parent commit or abort clean.
Rewriting & Undoing
Amend, rebase, reset, bisect, and recovery
Amend & Fixup
Correct the tip of your branch with `git commit --amend`, which writes a new commit and moves the ref while the original waits in the reflog, then queue a fix for a buried commit by writing a `fixup!` marker to fold in later.
Rebase
Rebuild your branch's commits onto a new base, watching each become a new object with the same diff but a fresh parent and hash, fold a queued `fixup!` marker into its target with `--autosquash`, and see why `ours` and `theirs` swap when a replay hits a conflict.
Reset, Revert & Clean
Rewind a branch with `git reset` and pick with `--soft`, `--mixed`, or `--hard` how far the staging area and working tree follow; append a push-safe inverse commit with `git revert` (choosing a mainline with `-m` on a merge); and wipe untracked files with `git clean -fd`, the only one of the three the reflog cannot undo.
Cherry-pick
Copy the change from any commit onto your current branch as a new object with its own hash while the original stays put, select a merge's mainline with `-m`, and run a range through the sequencer that halts on a conflict with four ways out.
Bisect
Pinpoint the commit that broke a test by halving a 1024-commit range in about ten classifications, read the `.git/BISECT_*` state the search parks on disk without moving your branch, and automate the whole loop with `git bisect run` (exit 0 good, 125 skip, non-zero bad).
Collaboration
Remotes, pull requests, hooks, and team workflows
Remotes
Watch `git remote add` write two lines to `.git/config` with no network call, see `git fetch` fill `.git/objects/` and `refs/remotes/origin/` while your branches stay put, and read a `non-fast-forward` push rejection as the remote refusing to drop a teammate's commit.
Pull Requests
Search the server's `.git/` after opening a PR and find no new object, push more commits to see the diff re-resolve off the live tip with no update step, then run merge, squash, and rebase to land `refs/heads/main` at three different hashes.
Git Hooks
Place a file named `pre-commit` in `.git/hooks/`, `chmod +x` it, and watch git fork it on the next commit and abort on a non-zero exit, then clone the repo to find the hook gone and see why `--no-verify` skips your copy but never the server's `pre-receive`.
Workflows
Read a team's model off its `git branch -a`, route one feature through trunk-based, GitFlow, and forking so identical code lands on `main` three ways, then pick the shape by release cadence and contributor trust.