Ad – 728×90
🚀 Getting Started

git add & git commit – Staging and Committing Changes

Git's staging area is what makes it unique among version control systems. Instead of committing every changed file at once, you first stage exactly what you want to include in the next snapshot. This gives you fine-grained control over your history. This lesson teaches you how to stage with git add, commit with git commit, and write commit messages that your future self will thank you for.

⏱️ 20 min read 🎯 Beginner 📅 Updated 2026

The Staging Area – Why It Exists

Git tracks your files across three distinct zones:

ZoneAlso calledWhat lives here
Working directory Working tree Your actual files on disk — edited freely
Staging area Index, cache Changes you've explicitly selected for the next commit
Repository .git database Permanent commit history, stored in .git/objects/

The staging area lets you craft precise commits. Imagine you fixed a bug and reformatted some unrelated code. Without staging, you'd have to commit everything together. With staging, you can add only the bug-fix files and commit them separately from the reformatting — resulting in a cleaner, more reviewable history.

ℹ️
What is a commit ID (SHA)?

Every commit in Git gets a unique 40-character hexadecimal fingerprint called a SHA-1 hash (or commit ID), e.g. a3f8c2d1.... It is calculated from the commit's contents, author, timestamp, and parent commit — so it is effectively unique. You only need to type the first 7 characters when referencing a commit in commands.

git add – Staging Changes

The git add command moves changes from the working directory into the staging area. You can be as specific or as broad as you like.

Stage a specific file

Bash
# Stage a single file
git add README.md

# Stage a file in a subdirectory
git add src/main.py

# Stage multiple specific files
git add index.html style.css

Stage everything in the current directory

Bash
# Stage ALL changes (new files, modifications, deletions) recursively
git add .

# Alternative: stage everything from the repo root, regardless of where you are
git add -A
⚠️
Use git add . with care

Running git add . stages everything — including temporary files, build artifacts, and secrets you may not want in version control. Always check git status before committing and keep a good .gitignore file to exclude files you never want tracked.

Stage changes interactively (patch mode)

git add -p is one of the most powerful staging tools. It walks through every changed hunk (a continuous block of changes) in your files and asks whether you want to stage it. This lets you split a single file's changes across multiple commits.

Bash
# Launch interactive patch mode
git add -p

# Or for a specific file
git add -p src/main.py
Interactive prompt
@@ -10,7 +10,9 @@ def calculate():
     result = a + b
+    # New: validate inputs
+    if a < 0 or b < 0:
+        raise ValueError("Inputs must be positive")
     return result

Stage this hunk [y,n,q,a,d,s,?]? 

Key responses: y stage this hunk, n skip it, s split into smaller hunks, q quit, ? show help.

Ad – 336×280

git commit – Saving the Snapshot

Once your changes are staged, git commit saves them as a permanent snapshot in the repository's history. Every commit records: what changed, who made the change, when, and a message explaining why.

Commit with an inline message

Bash
# Commit staged changes with a short message
git commit -m "Add input validation to calculate function"
Output
[main a3f8c2d] Add input validation to calculate function
 1 file changed, 3 insertions(+)

Git shows the branch name, the first 7 characters of the new commit's SHA, the message, and a summary of what changed.

Commit with a multi-line message (opens your editor)

Bash
# Opens your configured editor (usually vim, nano, or VS Code)
git commit

# Configure VS Code as your commit editor
git config --global core.editor "code --wait"

Writing Good Commit Messages

A good commit message is a gift to your teammates — and to your future self six months from now. The widely-adopted convention:

Commit message format
Short summary in imperative mood (50 chars max)

Optional longer body explaining WHY this change was made,
what problem it solves, and any context reviewers need.
Wrap lines at ~72 characters.

Optionally reference issue numbers:
Closes #123
Bad messageGood message
fixFix null pointer crash when user has no profile photo
wipAdd skeleton for user authentication module
updated stuffUpdate API base URL to use environment variable
fixing the thingCorrect off-by-one error in pagination calculation
Use imperative mood: "Add", not "Added" or "Adding"

Think of the subject line as completing the sentence: "If applied, this commit will...". So: "If applied, this commit will Add input validation" — not "Added input validation".

git commit --amend – Editing the Last Commit

Made a typo in your last commit message? Forgot to stage one file? --amend lets you rewrite the most recent commit.

Bash
# Fix the last commit message only
git commit --amend -m "Add input validation with proper error messages"

# Add a forgotten file to the last commit
git add forgotten-file.py
git commit --amend --no-edit   # --no-edit keeps the original message
⚠️
Only amend commits that haven't been pushed

--amend rewrites the commit — it creates a brand-new commit with a different SHA and discards the old one. If you've already pushed to a shared branch and then amend, your local history diverges from the remote. Other team members who pulled the original commit will get conflicts. Rule of thumb: amend only your local, unpushed commits.

Checking What You've Committed

After committing, confirm everything looks right:

Bash
# See recent commits
git log --oneline -5

# Check current staging status
git status
Output
a3f8c2d (HEAD -> main) Add input validation to calculate function
7b9e1a3 Initial project setup
On branch main
nothing to commit, working tree clean

"Nothing to commit, working tree clean" is the green light — all changes are committed and the staging area is empty.

📋 Summary

  • Git has three zones: working directory (edited files), staging area (selected for next commit), and the repository (permanent history).
  • git add <file> — stage a specific file; git add . stages everything (use carefully).
  • git add -p — interactive patch mode; stage individual hunks within a file for precise commits.
  • git commit -m "message" — create a commit with an inline message.
  • Good commit messages: imperative mood, 50-char subject, explain the why in the body.
  • git commit --amend — rewrite the last commit (message or content); only safe before pushing.
  • Every commit gets a unique SHA hash — the first 7 characters are enough for most commands.

FAQ

What happens if I commit without staging anything? +

Git will show the message nothing to commit, working tree clean (if no changes exist) or nothing added to commit but untracked files present (if you have new files but haven't staged them). No commit is created. You must run git add first to stage changes before git commit will do anything.

Can I stage and commit in a single command? +

Yes — for already-tracked files only: git commit -a -m "message" (or git commit -am "message") stages all modifications to tracked files and commits them in one step. It does not stage new (untracked) files. While convenient, skipping the explicit git add step means you lose the ability to selectively stage changes, so use it only when you're sure you want to commit everything.

How do I unstage a file I accidentally added? +

Use git restore --staged <file> (Git 2.23+) to unstage a file without discarding your changes — the file goes back to "modified but not staged". The older equivalent is git reset HEAD <file>. Your actual file content is untouched either way; only the staging area entry is removed.

How long should a commit message be? +

The subject line should be 50 characters or fewer (GitHub truncates at 72). For simple changes, a one-liner is fine. For anything non-obvious — a complex bug fix, an architectural decision, a workaround — add a body after a blank line. The body should explain why the change was made, not just what changed (the diff already shows the what). There is no strict maximum for the body length.