Staging and committing

Git · Essentials · 10 min

Commits are the unit of history; good ones make review, debugging and reverting easy.

git add <path> stages the current content of files: new files, modifications and (with git add -A or git add .) deletions. git commit then records the staged snapshot with a message.

Useful forms:

  • git add file.py dir/: stage specific paths.
  • git add -p: walk through each change hunk and choose y/n. The best way to split unrelated changes into separate commits.
  • git commit -m "message": commit with a one-line message; without -m Git opens your editor.
  • git commit -a: stage all modifications to tracked files and commit in one go. It skips new files.
  • git commit --amend: replace the last commit with a new one that includes what is staged now, or just fix its message. Only do this before pushing.

A good commit is one logical change that leaves the project working. Write the message for a future reader: a short summary line (about 50 characters, imperative mood: "Fix rounding in invoice totals"), a blank line, then a body explaining why if it isn't obvious.

Each commit gets an ID, a hash such as 3f9a2c1..., derived from its content and its parent. You can refer to it by the first 7 or so characters. Change anything about a commit, even its message, and you get a new ID; this is why amending pushed commits causes trouble for others.

Commit early and often locally. Small commits are cheap and easier to review, revert and bisect than one giant "WIP" commit.

Example

git add src/invoice.py              # stage one file
git add -p                          # pick hunks interactively
git commit -m "Fix rounding in invoice totals"

# Longer message: summary, blank line, body
git commit -m "Cache exchange rates" -m "Rates were fetched per line item, making large invoices slow."

# Forgot a file? Add it to the last (unpushed) commit
git add tests/test_invoice.py
git commit --amend --no-edit

git log --oneline -3
# 9c1e2ab Cache exchange rates
# 3f9a2c1 Fix rounding in invoice totals

Remember

  • git add stages; git commit records the staged snapshot
  • git add -p lets you split unrelated edits into separate commits
  • One logical change per commit, imperative summary line
  • --amend rewrites the last commit; don't amend what you've pushed

Watch out for

  • Expecting git commit -a to include brand-new files — it only stages files Git already tracks.

Check yourself

  1. You created new.py and modified old.py. What does git commit -a -m 'x' commit?
  2. Why does git commit --amend change the commit's ID?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository