Git from First PrinciplesPost 15 of 16 · 16 of 16 written

15. Practice path, fluency checklist and glossary

Git · 15 of 164 min readOct 2026

Reading builds the model; drills make it fluent. Work through these exercises in order in ~/git-lab, and tick them off as you go.

Practice path

  • Objects. Make five commits with good messages. Run git cat-file -p on a commit, its tree and a blob. Count objects with find .git/objects -type f after each commit.
  • Deduplication. Commit two files with identical content under different names. Confirm with git ls-tree HEAD that both point to one blob.
  • The index. Stage a file, edit it again, commit, and check which version landed. Then use git add -p to split one messy change into two clean commits.
  • Branching. Create two branches that diverge. Fast-forward one into main and three-way merge the other. Then cause a conflict on purpose, read it with zdiff3, and resolve it.
  • Rebase. Rebase a branch and note the new hashes. Use git rebase -i to squash three commits into one, then try --fixup with --autosquash.
  • Disaster drills. Reset three commits away with --hard and recover them from the reflog. Delete a branch and restore it. Rescue commits made in detached HEAD. Drop a stash and recover it with git fsck.
  • A fake server. Run git init --bare ~/git-lab/server.git, then clone it twice as alice and bob. Make them push conflicting work, hit a rejected push, fix it with fetch and rebase, and practise --force-with-lease on a feature branch.
  • Plumbing. Do the build-a-commit-by-hand exercise in Part 13 without looking.
  • An ML repository. Add the Part 5 .gitignore, pre-commit with ruff, gitleaks and nbstripout, and DVC tracking a small dataset to a local remote (dvc remote add -d local /tmp/dvcstore). Make a training script log its commit hash and dirty flag.
  • Bisect. Write a script that creates 30 commits, one of which breaks a test. Find it with git bisect run.
  • Worktrees. Create two worktrees on two branches, make a change in each, and merge both into main.

You are fluent when you can…

  • Draw the object graph for any repository from git lg, and explain blob, tree, commit and tag.
  • Say which areas (working tree, index, refs, objects, remote) any command reads and writes.
  • Predict the graph after a merge and after a rebase, before running either.
  • Recover from reset --hard, a deleted branch or detached HEAD without searching.
  • Resolve a conflict by reasoning from the base, not by picking a side at random.
  • Explain fetch, pull and push in terms of refs, and why a push gets rejected.
  • Choose between revert and reset by asking whether the commits are shared.
  • Set up an ML repository with ignores, hooks, data pointers and commit-hash logging.
  • Review an agent’s diff for scope, weakened tests, dependencies and secrets.
  • Find a regression with git bisect run.

Glossary

Term Meaning
Blob Object holding one file’s raw content, with no name
Tree Object listing names, modes and hashes of blobs and subtrees: one directory
Commit Object holding a tree hash, parent hashes, author, committer and message
Annotated tag Object naming another object, with tagger, message and optional signature
Hash The content-derived name of an object (SHA-1 today, SHA-256 planned as default)
Ref A human-readable name mapped to a hash
Branch A ref under refs/heads/ that moves forward as you commit
HEAD The ref for your current position, usually naming a branch
Detached HEAD HEAD holding a commit hash directly, not a branch name
Working tree The files on disk you edit
Index / staging area The draft snapshot of your next commit
Reachable Findable by following parent pointers from some ref
Dangling An object nothing points to; eventually garbage-collected
Reflog Local log of where each ref has pointed
Merge base The best common ancestor of two commits
Fast-forward Moving a ref ahead along existing history, with no new commit
Three-way merge Combining two tips by comparing each with their merge base
Rebase Replaying commits onto a new base, creating new commits
Cherry-pick Applying one commit’s change onto HEAD as a new commit
Remote A named URL of another copy of the repository
Remote-tracking branch Your local bookmark of a remote branch, such as origin/main, updated by fetch
Upstream The remote-tracking branch a local branch is linked to
Refspec A rule mapping remote refs to local refs, used by fetch and push
Packfile Compressed bundle of objects stored as deltas
Porcelain / plumbing User-facing commands / the low-level commands they are built on
Worktree An extra working directory attached to the same repository
Submodule A pinned commit of another repository inside this one
Hook A script Git runs at a fixed moment, such as before a commit
Git LFS Extension that stores large files outside Git behind pointer files