Part III · Shell and commands
30.1 How git stores your work
alsogitcommitcommitsbranchbranchesheaddetached headgit objectsstaging areagit indexgit addgit statussha
TL;DR
- A commit is a snapshot of the whole project, plus its author, message and parent commit(s). It's named by a hash of all that.
- A branch is just a name pointing at one commit; committing moves it
forward.
HEADsays which branch you're on. - Changes go through three places: your files, the staging area
(
git add), then the repository (git commit).
git status # what changed, what's staged
git log --oneline --graph --all
git diff --staged # what the next commit will contain
Pitfalls
- "detached HEAD": you checked out a commit, not a branch. New commits
there belong to no branch:
git switch -c new-namekeeps them. git addstages a file as it is now; editing it again needs anothergit addbefore committing.- Untracked files aren't protected by git at all: commit or stash before any command that cleans the folder.
- Big binary files bloat every clone forever, even after deletion: keep them out, or use Git LFS.
Deep dive 2 questions
What's inside .git?
An object store: each file version is a blob, each folder a tree listing
blobs and trees, each commit points to one tree and its parents. All are
named by the hash of their content, so identical files are stored once
and any change gives a new name. Branches are small files under
.git/refs/heads/ holding a commit hash; .git/HEAD names the branch.
Why are branches cheap?
Creating one writes a 41-byte file; switching rewrites only the files that differ. Nothing is copied. That's why git encourages a branch per feature or fix: it costs nothing, and merging is what git is built for.