git commit
Seal the index into a permanent commit object.
git commitWhat it does
git commit reads the index, wraps it in a tree object, and creates a commit object that points to that tree and to your current HEAD. Then it moves the branch ref forward. The commit is immutable and permanent — this is history being written.
The commit object is appended and the branch pointer slides forward
Watch it — press play
A narrated, step-by-step walkthrough that shows how to do it — not just theory. It adapts to the learner mode you picked in the top bar.
Step 1
Stage first
Before a commit, files live in the index (staging). The index is a preview of what the commit will contain.
git add .Working Tree
files on disk
Index · Staging
.git/index
Repository
objects/ → commits
committed history
The index holds your next snapshot
Under the hood
Step 1 — a tree is built from the index
Every staged path is packaged into trees (directories) and blobs (files). The top-level tree object describes the entire project snapshot.
tree f2b0c9d… ├─ blob aa8f1e… README.md ├─ blob 3c2d09… src/main.ts └─ tree b7e1a2… src/
Step 2 — the commit object is written
Git builds a commit object containing the tree hash, the parent commit hash(es), the author, the committer, and your message — then hashes THAT. This hash is the commit's identity.
commit 74d3b9f (your new commit) tree f2b0c9d… parent 9a2f1c0… (previous commit) author Ada <ada@…> committer Ada <ada@…> message feat: add dark mode
Step 3 — the branch moves, HEAD follows
The branch file you're on (refs/heads/main) is rewritten to contain the new commit hash, and HEAD points at that branch. The commit is now 'on' the branch.
git rev-parse main # → 74d3b9f… cat .git/HEAD # → ref: refs/heads/main cat .git/refs/heads/main # → 74d3b9f…
Why parent pointers make history
Every commit records its parent. Following the chain of parents from any commit walks the entire history. This is exactly what git log does — it is nothing but a linked list traversal.
Aliases the pros type
Memorize the git commit concept, then let one of these shortcuts make it instant. Aliases are real git config keys — add one with:
git config --global alias.st # → git commit -mg cmgit commit -mCommit with an inline message.
g cmagit commit -amStage tracked files + commit in one.
g amendgit commit --amend --no-editFold changes into the last commit without touching the message.
g cm "$(gen)"git commit -m <generated msg>Some devs pipe a commit-message generator here.
Command anatomy
-mSet the commit message inline.
-aStage all tracked modified files before committing (never new files).
--amendReplace the last commit — new tree, new message, new hash.
--no-verifySkip pre-commit and commit-msg hooks.
When to reach for it
A logical unit of work is finished and the index looks right.
You fixed a typo in the last commit: git commit --amend --no-edit.
Combining with -a when you're committing everything and the index dance is overhead.
Pro tip
Amend is NOT editing history in place — it creates a brand-new commit object whose parent is the same as the old one. The old commit is simply dropped and garbage-collected. Never amend commits that are already shared with others.