Home DevOps Git Add, Commit and Status: Master the Core Workflow Without Losing Work
Beginner 4 min · July 07, 2026

Git Add, Commit and Status: Master the Core Workflow Without Losing Work

Master Git add, commit, and status commands.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Production
production tested
July 07, 2026
last updated
214
articles · all by Naren
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer

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.

✦ Definition~90s read
What is Git Add, Commit and Status?

Git add, commit, and status are the three commands that form the core workflow for tracking changes in a Git repository. git status shows the current state of your working directory and staging area. git add moves changes from your working directory to the staging area. git commit saves the staged changes as a permanent snapshot in the repository's history.

Think of Git like a photographer at a wedding.
Plain-English First

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.

staging-area-demo.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
# io.thecodeforge — DevOps tutorial

# Initialize a test repo
git init staging-demo
cd staging-demo

# Create two files
echo "Hello" > file1.txt
echo "World" > file2.txt

# Check status — both files are untracked
git status

# Stage only file1.txt
git add file1.txt

# Status now shows file1 staged, file2 untracked
git status

# Commit only the staged file
git commit -m "Add file1.txt"

# Status now shows clean working directory except file2
git status
Output
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
file1.txt
file2.txt
nothing added to commit but untracked files present (use "git add" to track)
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: file1.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
file2.txt
[master (root-commit) abc1234] Add file1.txt
1 file changed, 1 insertion(+)
create mode 100644 file1.txt
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
file2.txt
nothing added to commit but untracked files present (use "git add" to track)
Senior Shortcut:
Use 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.

status-examples.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
# io.thecodeforge — DevOps tutorial

git init status-demo
cd status-demo

# Create a file and stage it
echo "content" > tracked.txt
git add tracked.txt
git commit -m "Initial commit"

# Modify the file
echo "more content" >> tracked.txt

# Create a new untracked file
echo "secret" > secret.txt

# Run status
git status

# Output shows modified tracked file and untracked file
Output
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: tracked.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
secret.txt
no changes added to commit (use "git add" and/or "git commit -a")
Production Trap:
Never run 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.

add-precision.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
# io.thecodeforge — DevOps tutorial

# Create a repo with a file
git init add-demo
cd add-demo
echo -e "line1\nline2\nline3" > file.txt
git add file.txt
git commit -m "Initial"

# Make two changes: fix a bug and add a comment
echo -e "line1\nline2_fixed\nline3\n# TODO: optimize" > file.txt

# Interactive staging — press 'y' for first hunk, 'n' for second
git add -p file.txt

# Check what's staged
git diff --cached

# Commit only the bug fix
git commit -m "Fix typo in line2"

# Now stage and commit the comment
git add -p file.txt
git commit -m "Add TODO comment"
Output
diff --git a/file.txt b/file.txt
index 1234567..abcdefg 100644
--- a/file.txt
+++ b/file.txt
@@ -1,3 +1,4 @@
line1
-line2
+line2_fixed
line3
+# TODO: optimize
Stage this hunk [y,n,q,a,d,e,?]? y
@@ -1,3 +1,4 @@
line1
line2_fixed
line3
+# TODO: optimize
Stage this hunk [y,n,q,a,d,e,?]? n
[master abc1234] Fix typo in line2
1 file changed, 1 insertion(+), 1 deletion(-)
[master def5678] Add TODO comment
1 file changed, 1 insertion(+)
The Classic Bug:
Using 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.

commit-messages.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
# io.thecodeforge — DevOps tutorial

git init commit-demo
cd commit-demo

# Create and stage a file
echo "initial" > app.py
git add app.py

# Bad commit message
git commit -m "update"

# Good commit message — use conventional format
git commit --allow-empty -m "feat: add user authentication

Implement JWT-based authentication for the login endpoint.
Includes token generation and validation middleware.
Closes #42"

# View the log
git log --oneline
Output
[master (root-commit) abc1234] update
1 file changed, 1 insertion(+)
create mode 100644 app.py
[master def5678] feat: add user authentication
1 file changed, 0 insertions(+), 0 deletions(-)
def5678 feat: add user authentication
abc1234 update
Senior Shortcut:
Use 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.

undo-mistakes.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash
# io.thecodeforge — DevOps tutorial

git init undo-demo
cd undo-demo

# Setup: create a commit
echo "important" > file.txt
git add file.txt
git commit -m "Initial commit"

# Accidentally stage a file you don't want
echo "secret" > secret.txt
git add secret.txt

# Unstage it
git reset HEAD secret.txt

# Now modify file.txt and stage it
echo "more" >> file.txt
git add file.txt

# Commit but realize you forgot something
git commit -m "Update file.txt"

# Undo the commit but keep changes staged
git reset --soft HEAD~1

# Now you can add the forgotten change and recommit
echo "even more" >> file.txt
git add file.txt
git commit -m "Update file.txt with all changes"

# Check log
git log --oneline
Output
[master (root-commit) abc1234] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 file.txt
Unstaged changes after reset:
M file.txt
[master def5678] Update file.txt with all changes
1 file changed, 2 insertions(+)
def5678 Update file.txt with all changes
abc1234 Initial commit
Never Do This:
Don't use 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.

production-workflow.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
# io.thecodeforge — DevOps tutorial

git init checkout-service
cd checkout-service

# Simulate existing code
echo "// payment logic" > payment.js
echo "// discount logic" > discount.js
git add .
git commit -m "Initial commit"

# Make changes
echo "// fixed tax" >> payment.js
echo "// added bulk discount" >> discount.js
echo "[DEBUG] log" > debug.log

# Step 1: Check status
git status

# Step 2: Add debug.log to .gitignore
echo "debug.log" >> .gitignore

# Step 3: Stage only payment.js
git add payment.js

# Step 4: Commit bug fix
git commit -m "fix: correct tax calculation for international orders"

# Step 5: Stage discount.js
git add discount.js

# Step 6: Commit feature
git commit -m "feat: add bulk discount logic"

# Step 7: Verify history
git log --oneline
Output
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: discount.js
modified: payment.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
debug.log
[master abc1234] fix: correct tax calculation for international orders
1 file changed, 1 insertion(+)
[master def5678] feat: add bulk discount logic
1 file changed, 1 insertion(+)
def5678 feat: add bulk discount logic
abc1234 fix: correct tax calculation for international orders
1234567 Initial commit
Interview Gold:
Interviewers love asking 'How do you keep commits clean?' The answer: use 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.
● Production incidentPOST-MORTEMseverity: high

The Commit That Killed the Deploy

Symptom
Deployment pipeline failed because a commit contained a large binary file (300MB) that bloated the repository, causing clone times to spike from 10 seconds to 5 minutes.
Assumption
The team assumed the issue was a network problem or server load.
Root cause
A developer ran 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.
Fix
Use 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 ..
Key lesson
  • Always run git status before any git add . — it shows untracked files that might accidentally get staged.
Production debug guideSystematic recovery paths for the failure modes engineers actually hit.3 entries
Symptom · 01
I committed a large file and now the repo is bloated
Fix
1. Identify the large file: 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.
Symptom · 02
I committed to the wrong branch and pushed
Fix
1. Revert the commit on the wrong branch: 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.
Symptom · 03
git status shows 'Your branch is ahead of 'origin/master' by 1 commit' but I haven't pushed yet
Fix
1. Check what the commit contains: 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 Add, Commit and Status Triage Cheat SheetFirst-response commands for when things go wrong — copy-paste ready.
I staged a file I didn't mean to — `git status` shows it in green
Immediate action
Unstage the file without losing changes
Commands
git reset HEAD <file>
git status (to confirm it's unstaged)
Fix now
git reset HEAD <file>
I committed and want to undo but keep changes — `git log` shows the commit+
Immediate action
Soft reset to undo commit but keep changes staged
Commands
git reset --soft HEAD~1
git status (to see staged changes)
Fix now
git reset --soft HEAD~1
I want to discard all uncommitted changes — `git status` shows modified files+
Immediate action
Restore files to last committed state
Commands
git restore .
git status (to confirm clean)
Fix now
git restore .
I committed and want to permanently discard the changes — `git log` shows the commit+
Immediate action
Hard reset — irreversible, so double-check
Commands
git reset --hard HEAD~1
git log (to confirm removal)
Fix now
git reset --hard HEAD~1
CommandEffectWhen to Use
git add .Stages all changes (new, modified, deleted) in current directoryWhen you want to commit everything, but check status first
git add -pInteractively stage hunks of changesWhen you want to commit only part of a file
git add -uStages modified and deleted tracked files onlyWhen you want to update existing files but skip new ones
git add -AStages all changes in the entire working treeSame as git add . but from repo root
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
staging-area-demo.shgit init staging-demoWhat Exactly Is the Staging Area?
status-examples.shgit init status-demogit status
add-precision.shgit init add-demogit add
commit-messages.shgit init commit-demogit commit
undo-mistakes.shgit init undo-demoUndoing Mistakes
production-workflow.shgit init checkout-serviceThe Complete Workflow

Key takeaways

1
Always run git status before git add and git commit
it's your safety net against staging the wrong files.
2
Use git add -p to stage individual hunks
it keeps commits focused and makes code review easier.
3
Write meaningful commit messages using conventional commits
your future self and teammates will thank you.
4
git reset --soft is your undo button for commits without losing work
use it liberally.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What happens when you run `git commit -a` and there are untracked files?
Q02SENIOR
How does `git add -p` work internally, and when would you use it in a co...
Q03SENIOR
You accidentally committed a file with a hardcoded API key. What's your ...
Q04JUNIOR
What's the difference between `git reset --soft`, `git reset --mixed` (d...
Q05SENIOR
How would you design a Git workflow for a team of 20 developers to minim...
Q06SENIOR
You see 'Your branch is ahead of 'origin/master' by 3 commits' but you h...
Q01 of 06JUNIOR

What happens when you run `git commit -a` and there are untracked files?

ANSWER
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.
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
What's the difference between `git add` and `git commit`?
02
How do I undo a `git add` before commit?
03
How do I see what will be committed before I commit?
04
What does `git commit -a` do?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 07, 2026
last updated
214
articles · all by Naren
🔥

That's Git. Mark it forged?

4 min read · try the examples if you haven't

Previous
Git Init: Creating and Initializing Repositories
21 / 47 · Git
Next
Git Revert: Safe Undo for Pushed Commits