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 choosey/n. The best way to split unrelated changes into separate commits.git commit -m "message": commit with a one-line message; without-mGit 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 totalsRemember
- 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.