Git Add, Commit and Status: Master the Core Workflow Without Losing Work
Master Git add, commit, and status commands.
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
Use git status to see what's changed, git add to stage changes you want to commit, and git commit -m "message" to save those changes. Always run git status before committing to avoid missing or including unintended files.
Think of Git like a photographer at a wedding. Your working directory is the dance floor — everything happening live. git add is like telling the photographer 'hey, capture this moment' — they frame the shot. git commit is the actual click of the shutter — the photo is saved forever in the album. git status is the photographer's assistant telling you which moments are already captured and which are still waiting.
I've seen a junior dev delete three days of work because they didn't understand the difference between git add and git commit. They thought git commit -a would save everything, but it only saved tracked files — their new config file was gone forever. That's the kind of pain this article prevents.
The problem is that Git's core workflow — add, commit, status — is deceptively simple. Most tutorials show you the happy path: git add . then git commit -m "stuff". But in production, you need precision. You need to know exactly what's staged, what's not, and how to undo mistakes before they become permanent.
By the end of this, you'll be able to track changes with surgical precision, recover from accidental commits, and never again push a half-baked feature or lose work because you didn't stage the right files.
What Exactly Is the Staging Area?
Before you can commit, you need to understand the staging area. It's Git's middle ground between your working directory and the repository. Why does it exist? Because you don't always want to commit everything you've changed. Maybe you fixed a bug in one file but also made experimental changes in another. The staging area lets you pick and choose which changes go into the next commit.
Without a staging area, you'd have to commit every change as it happens — or use complex workarounds like creating temporary branches. Git's staging area gives you surgical control. It's the difference between dumping your entire toolbox on the table and carefully selecting the right screwdriver.
Here's how a typical workflow looks: you edit files, then use git add to stage specific changes. You can stage entire files or even individual lines within a file using git add -p. Then git status shows you exactly what's staged and what's not. Finally, git commit saves the staged snapshot.
git add -p to stage individual hunks of a file. This lets you commit only the bug fix parts of a file while leaving experimental changes unstaged. It's a game-changer for keeping commits clean.git status: Your Safety Net
git status is the most underrated command in Git. It tells you exactly what's going on: which files are modified, which are staged, and which are untracked. I run it before every git add and before every git commit. It's like checking your mirrors before changing lanes — you'd be stupid not to.
Why is this so important? Because git add . is a shotgun — it stages everything in the current directory, including generated files, logs, and secrets. I've seen people accidentally commit API keys because they didn't check status first. git status shows untracked files in red, so you can add them to .gitignore before they become a problem.
git status also tells you if you're on the right branch, if you're ahead/behind the remote, and if there are merge conflicts. It's your dashboard. Learn to read it.
git add . without first running git status. You might stage a .env file with production credentials. If that commit gets pushed, you have to rotate all secrets. Trust me, that's a 3am phone call you don't want.git add: Staging with Precision
git add moves changes from your working directory to the staging area. You can stage entire files (git add file.txt), multiple files (git add file1.txt file2.txt), or all changes in the current directory (git add .). But the real power is in staging parts of a file.
Use git add -p (or git add --patch) to interactively stage hunks. Git will show you each change and ask if you want to stage it. This is how you keep commits focused. For example, you might have a file with a bug fix and a formatting change. You can stage only the bug fix hunk, commit it, then stage the formatting change separately.
Another common pattern is git add -A which stages all changes including deletions. git add -u stages only modified and deleted tracked files (no new files). Know the difference — using the wrong one can leave out new files or include unwanted deletions.
git add . from the repo root stages everything, including subdirectories. If you have a node_modules folder not in .gitignore, you'll stage thousands of files. Always check .gitignore and run git status first.git commit: Saving a Snapshot
git commit takes everything in the staging area and creates a permanent snapshot in the repository's history. Each commit has a unique hash, an author, a timestamp, and a message. The message is critical — it's how you and your team understand what changed and why.
Write good commit messages. The first line should be a short summary (50 chars max), then a blank line, then a detailed description. This follows the conventional commit format and makes git log readable. Bad commit messages like "fix stuff" or "update" are useless when you're debugging a production issue six months later.
Use git commit -m "message" for short commits. For longer messages, omit -m and Git will open your default editor. Pro tip: set your editor to something you're comfortable with using git config --global core.editor "code --wait" for VS Code.
git commit -v to see the diff of staged changes in the commit message editor. This reminds you exactly what you're committing and helps catch mistakes.Undoing Mistakes: Reset and Restore
You will make mistakes. You'll stage the wrong file, commit too early, or commit to the wrong branch. Git gives you tools to undo without panic.
To unstage a file (keep changes but remove from staging): git reset HEAD <file>. To discard changes in a file entirely (irreversible!): git restore <file>. To undo the last commit but keep changes staged: git reset --soft HEAD~1. To undo the last commit and unstage changes: git reset HEAD~1. To undo the last commit and discard changes: git reset --hard HEAD~1 — but be careful, this deletes changes permanently.
I use git reset --soft all the time when I accidentally commit to the wrong branch. I undo the commit, stash the changes, switch branches, and pop the stash. It's a five-second fix that saves a lot of pain.
git reset --hard unless you're absolutely sure you want to discard all uncommitted changes. There's no undo for that. I've seen devs lose hours of work because they ran it without checking git status first.The Complete Workflow: A Production Example
Let's put it all together with a realistic scenario. You're working on a checkout service. You fix a bug in payment.js, add a new feature in discount.js, and accidentally create a log file debug.log. Here's how to handle it like a pro.
First, run git status to see the landscape. You'll see payment.js and discount.js as modified, and debug.log as untracked. Add debug.log to .gitignore so it never gets committed. Then stage only payment.js for the bug fix commit. Commit with a message like "fix: correct tax calculation for international orders". Then stage discount.js for the feature commit. Commit with "feat: add bulk discount logic".
This creates two clean, focused commits. If something goes wrong, you can revert one without affecting the other. That's the power of the staging area.
git add -p to stage hunks, write descriptive commit messages, and commit often with a single logical change per commit. Never mix bug fixes and features in the same commit.The Commit That Killed the Deploy
git add . which staged a database dump file that wasn't in .gitignore. The commit included the file, and once pushed, the repository history permanently contained the large blob.git filter-branch or BFG Repo-Cleaner to remove the file from history, then force push. Add *.sql to .gitignore and educate the team to always run git status before git add ..- Always run
git statusbefore anygit add .— it shows untracked files that might accidentally get staged.
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ {print $3, $4}' | sort -n | tail -10
2. Remove it from history: git filter-branch --tree-filter 'rm -f <file>' HEAD or use BFG Repo-Cleaner.
3. Force push: git push origin --force --all
4. Educate team to add the file type to .gitignore.git revert <commit-hash>
2. Cherry-pick the commit to the correct branch: git checkout correct-branch && git cherry-pick <commit-hash>
3. Push both branches.
4. If the commit contains sensitive data, use git filter-branch to remove it.git log origin/master..HEAD
2. If it's wrong, undo it: git reset --soft HEAD~1 to uncommit but keep changes, then fix and recommit.
3. If it's correct, push: git push origin HEAD.git reset HEAD <file>git status (to confirm it's unstaged)| File | Command / Code | Purpose |
|---|---|---|
| staging-area-demo.sh | git init staging-demo | What Exactly Is the Staging Area? |
| status-examples.sh | git init status-demo | git status |
| add-precision.sh | git init add-demo | git add |
| commit-messages.sh | git init commit-demo | git commit |
| undo-mistakes.sh | git init undo-demo | Undoing Mistakes |
| production-workflow.sh | git init checkout-service | The Complete Workflow |
Key takeaways
git status before git add and git commitgit add -p to stage individual hunksgit reset --soft is your undo button for commits without losing workInterview Questions on This Topic
What happens when you run `git commit -a` and there are untracked files?
git commit -a only stages and commits changes to tracked files. Untracked files are ignored. This is a common gotcha — developers think -a means 'all', but it means 'all tracked'. To include untracked files, you must explicitly git add them first.Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
That's Git. Mark it forged?
4 min read · try the examples if you haven't