Track Changes with git add and commit

Learn to track changes in Git using git add and commit. This lesson covers the core concepts, step-by-step walkthrough, and troubleshooting for effectively staging and saving your work.

Focus: track changes with git add and commit

Sponsored

You've just written a brilliant piece of code, saved the file, and closed your editor with a satisfied sigh. But somewhere in the back of your mind, a nagging question haunts you: "What changed?" If that code breaks an hour later, can you look back and see exactly what you did? Without a system to track changes, you're flying blind — every edit becomes a gamble. Git's add and commit commands are your safety net, the first two steps toward a complete, auditable history of your project. In this lesson, you'll stop hoping you remember and start knowing what changed, when, and why.

The problem this lesson solves

You've probably been in this situation: you tweak a config file, adjust a function, delete a debug line — and the next day, the app is broken. You have no idea which of those tiny edits caused the disaster. You're left grepping through files, tearing your hair out, and wishing you had a time machine.

Git is that time machine, but only if you use it correctly. The raw power of Git lies in its commit history — a permanent record of every meaningful change you've made. However, Git doesn't automatically snapshot your work like a security camera. You have to tell it what to capture and when to capture it. That's exactly what git add and git commit do.

Without these commands, you're working without a net. You lose the ability to: - Revert a single feature that turned out to be a mistake. - Compare your current code to a working version from last week. - Collaborate with teammates without clobbering each other's work. - Understand the evolution of a file to spot when a bug was introduced.

By the end of this lesson, you'll have the mental model and hands-on skills to capture your work with precision. You'll never have to say "I should have committed that" again.

Core concept / mental model

Think of Git as a photographer for your project. The files in your working directory are the live scene — constantly changing, chaotic, and ephemeral. To capture a moment, you need two things: a composition and a shutter click.

  • git add is the staging area — it's like arranging your subjects and setting the focus. You choose exactly which files (or even lines within files) will appear in the next snapshot. This is called staging.
  • git commit is the shutter click — it permanently saves the staged snapshot to your project's history database. Each commit gets a unique ID (like a photo number) and a timestamp.

Diagram: Working Directory -> git add -> Staging Area -> git commit -> Repository

The key insight: a commit is not a copy of your entire project. It's a set of changes (a diff) from the previous commit. This makes Git incredibly efficient — you can view the history as a series of snapshots, but internally it stores the differences between them.

Let's clarify the three main areas you'll work with:

Area What it is Your command
Working Directory Your current files on disk (just edit files)
Staging Area (Index) Snapshot of what you've chosen to commit next git add
Repository (.git) The full, permanent history git commit

Think of it like this: git add is the shopping cart, git commit is the checkout. You don't take the whole store home — you only take what you put in your cart.

How it works step by step

Here's the logical flow that turns chaos into history:

  1. Modify your files — Edit content in your working directory. Git notices these changes, but does nothing with them until you tell it to.
  2. Stage the changes — Run git add <file> or git add . to move the current state of those files into the staging area. You can stage all files, specific files, or even parts of a file (using git add -p).
  3. Check what's staged — Use git status and git diff --cached to review exactly what you're about to commit. This is your last chance to make sure everything is correct.
  4. Commit the snapshot — Run git commit -m "Your commit message" to save the staged changes to the repository. A new commit object is created with a unique SHA-1 hash, your name, your email, and a timestamp.
  5. Repeat — Continue this cycle for every logical unit of work.

This two-step process (add, then commit) is what gives you granular control. You might have made changes to five files, but only one of those changes is related to a bug you're fixing. You can stage just that file and commit it with a clear message, keeping your history clean and easy to follow.

Pro tip: Commit early and often. Each commit should represent one logical change — like "fix typo in README" or "add login form validation". This makes it trivially easy to pinpoint and revert a specific change later.

Hands-on walkthrough

Let's put this into practice with a real (if small) example. We'll create a simple Python script, modify it, and watch Git track every step.

First, initialize a new Git repository and create a file:

mkdir git-practice && cd git-practice
git init
printf 'print("Hello, world!")\n' > hello.py
git status

You should see something like:

On branch master

No commits yet

Untracked files:
  (use "git add <file>" to include in what will be committed)
    hello.py

nothing added to commit but untracked files present (use "git add" to track)

Now, stage and commit your first version:

# Stage the file
git add hello.py

# See what you're about to commit (still uncommitted)
git status

# Commit it with a message
git commit -m "Initial commit: hello.py prints greeting"

The git status output now shows Changes to be committed with hello.py listed. After the commit, you'll see:

[master (root-commit) 1a2b3c4] Initial commit: hello.py prints greeting
 1 file changed, 1 insertion(+)

Now let's modify the file and see the full cycle:

# Edit hello.py
printf 'print("Hello, Git!")\n' > hello.py

# Check status
git status

# Notice: hello.py is modified, but NOT staged
# Stage it
git add hello.py

# Review the difference between staging area and last commit
git diff --cached

# Commit the change
git commit -m "Update greeting to be more Git-friendly"

# View the full history
git log --oneline

Your git log should look like this:

2b5f8d1 Update greeting to be more Git-friendly
1a2b3c4 Initial commit: hello.py prints greeting

Congratulations — you've just mastered the core loop of version control! Every commit you make is now a permanent, recoverable point in time.

Compare options / when to choose what

There are several ways to use git add and git commit, and knowing when to use each can save you a lot of pain.

Staging options

Command What it does Use it when
git add <file> Stages a single file You want to commit a specific file independently
git add . Stages all changed files in the current directory (and subdirectories) You're sure every change belongs in this commit
git add -p Stages parts of a file (patch mode) You made multiple unrelated changes in one file and want to split them into separate commits
git add -A Stages all changes, including deletions, in the entire repo You want to commit everything, everywhere

Committing options

Command What it does Use it when
git commit -m "Message" Creates a commit with an inline message Most of the time — simple and fast
git commit (without -m) Opens your default text editor for a multi-line message You need a detailed explanation with a body
git commit -am "Message" Stages tracked files and commits in one go You're only modifying files that are already tracked, and you want to skip the separate add step
git commit --amend Replaces the last commit with a new one You made a typo in the commit message or forgot to stage a tiny change that belongs to that commit

git add . vs git add -A

The difference is subtle but important: - git add . stages changes in the current directory recursively, but does not stage deletions of files that were explicitly deleted (in older Git versions). - git add -A (or git add --all) stages everything in the whole repository, including deletions, renames, and new files.

For a beginner, git add -A is often safer if you're in the root directory. But be careful — it can accidentally stage large binaries or secret files if you haven't set up a .gitignore.

Troubleshooting & edge cases

"nothing added to commit but untracked files present"

This happens when you try to commit without staging. Git's commit command only saves what's in the staging area, not the working directory. Fix it with git add <file> first.

"Changes not staged for commit"

You modified a tracked file, but didn't stage it yet. git status will show this in a red "Changes not staged". Run git add to stage it, or use git commit -am to skip staging for tracked files.

You staged the wrong file

If you accidentally ran git add . and staged everything, but only want to commit one file, you can unstage with git reset <file>. This moves the file back to the working directory while keeping your changes intact.

git reset HEAD hello.py

You made a typo in the commit message

Use git commit --amend. This will open your editor with the last message so you can fix it. It's safe as long as you haven't pushed that commit to a shared repository.

"file deleted but I want to restore"

If you deleted a file and haven't committed yet, you can restore it with git checkout -- <file> (or git restore in Git 2.23+). If you already committed the deletion, you'd use git revert or git reset (discussed in a later lesson).

Large repo slowing down

If you've committed large binary files (like images or build artifacts), your repository will grow huge. Mitigate by using a .gitignore file and not committing those files in the first place. The lesson on .gitignore in this track covers this in depth.

What you learned & what's next

You've now unlocked the fundamental rhythm of Git: modify → stage → commit. You understand that git add builds a snapshot of intended changes in the staging area, while git commit permanently burns that snapshot into your project's history. You can confidently stage specific files, review what's about to be committed, write meaningful messages, and navigate the most common pitfalls.

You've met the learning objectives: - Explain the core idea — You know Git tracks changes via a two-step process of staging and committing. - Complete a practical exercise — You made multiple commits and viewed the log with git log.

Next step: You're ready to dig into git diff and git log to inspect those changes more deeply. Soon you'll be branching, merging, and collaborating like a pro. The next lesson in this track covers viewing and comparing changes. See you there!

Practice recap

Practice what you learned: Create a new directory, init a Git repo, and add a small text file. Make at least three separate edits and commit each one with a descriptive message. Use git log --oneline to see your history, and try git diff to see what changed between commits. This will cement the staging workflow into muscle memory.

Common mistakes

  • Forgetting to stage files before committing — you'll get 'nothing added to commit' error. Always run git status first.
  • Using git commit -am when you have new untracked files — it only commits tracked files, so new files will be left out silently.
  • Running git add . indiscriminately and committing secrets, large binaries, or build artifacts. Use a .gitignore or stage specific files.
  • Writing vague commit messages like 'fix stuff' — make each commit a descriptive note that explains why the change was made.

Variations

  1. Use git add -p to selectively stage hunks of a file, letting you split multiple logical changes into separate commits.
  2. Use git commit --amend to update the last commit message or add a missed change without creating a new commit (only before pushing).
  3. Use git commit -am to skip the explicit staging step when editing tracked files only — a faster workflow for solo projects.

Real-world use cases

  • Daily development workflow: you implement a new feature and commit it with a descriptive message so teammates and future-you can review changes via git log.
  • Incident rollback: when a production bug is found, you trace the history with git log -p to pinpoint the exact commit that introduced it, then revert it cleanly.
  • Code review preparation: you stage and commit changes in logical chunks (e.g., refactor vs. feature), making each commit a self-contained unit that reviewers can approve or reject separately.

Key takeaways

  • Git tracks changes via a two-step process: git add stages files, git commit saves them permanently.
  • The staging area gives you granular control over what goes into each snapshot.
  • Commit early and often, with each commit representing one logical change.
  • Use git status and git diff --cached to review before you commit.
  • You can recover from mistakes using git reset to unstage and git commit --amend to fix messages.
  • The git log command lets you view your complete history of changes.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.