Git File and Commit Operations: Managing Changes Between States
Introduction¶
Ever stared at your repo, wondering why a “small” change just won’t commit or push?
GUI tools like GitHub Desktop or VSCode extensions are convenient—but they hide the magic. When things go sideways, or when you need to carefully craft commits, stage parts of files, or undo a “tiny mistake” that isn’t obvious, the GUI often leaves you helpless.
Full CLI Git is where you gain real control. It’s the difference between:
- Clicking buttons blindly and hoping everything works
- Understanding exactly where each change lives (Working Directory, Index, HEAD, Remote) and moving it precisely
Even minor mistakes—like accidentally staging a debug log or overwriting a feature—can snowball into hours of frustration. By mastering the CLI, you can fix problems before they become disasters, cherry-pick changes, or sculpt your commit history like a pro.
Think of this guide as your toolkit: practical commands, clear flows between Git states, and actionable tips to tame your repo—even when the “small” fixes aren’t so small after all.
Git File and Commit Operations Between States¶
Git can be a maze if you don’t know where your changes live and how commands affect them. Everything exists in one of four places:
- Remote → the branch on a remote repo, e.g.,
origin/main - HEAD → the last commit on your current branch
- Index → staging area, where changes wait for your next commit
- Working Directory (WD) → the files you actually edit
Understanding which command touches which area is key. Mistakes here aren’t just annoying—they can break your workflow.
Ready to see how to move safely between states and take control? Let’s go.
Git File and Commit Operations Between States¶
Git can feel like a maze if you don’t know where your changes live and how commands affect them. Every file and commit exists in one of four zones:
- Remote → your branch on a remote repo, e.g.,
origin/main - HEAD → the last commit on your current branch
- Index (staging area) → where changes are prepared for your next commit
- Working Directory (WD) → the files you’re editing locally
Understanding which command touches which area is crucial. Small mistakes here can ripple into messy histories or lost work. Think of this as territory control: knowing where your “soldiers” are ensures you can move them safely.
Quick Glossary¶
- Stage → move a file from WD → Index (
git add) - Unstage → move a file from Index → WD (
git restore --staged <file>) - Commit → move staged changes Index → HEAD (
git commit) - Amend → tweak the last commit without creating a new one (
git commit --amend) - Reset → move HEAD or Index, optionally discarding WD changes (
git reset) - Discard/Restore → revert a file in WD or Index to a previous state (
git restore)
Mastering these simple moves is like learning the basic steps before leading a full-scale campaign.
Moving Changes Between States: Practical Guide¶
Let’s break it down, battlefield-style. Each section shows exactly how to control your files and commits safely.
1. Working Directory → Index (Staging)¶
When you edit a file, it lives in your Working Directory. To prepare it for a commit:
- Moves changes WD → Index
- Marks files for the next commit
Undo staging if you changed your mind:
Pro tip: Stage only what you’re sure about. Partial staging is safer than committing everything blindly.
2. Index → HEAD (Committing)¶
Staged changes become permanent when you commit:
- Moves Index → HEAD
- Freezes the staged snapshot in branch history
Need to tweak the last commit?
Commits are your milestones. Make them clear—your future self (and your teammates) will thank you.
3. HEAD → Working Directory (Undo & Reset)¶
Sometimes you need a tactical retreat:
- Restore a file to its last commit:
- Reset staging back to HEAD:
- Hard reset your branch (dangerous—destroys uncommitted work!):
Think of these commands as emergency extractions. Use wisely.
4. HEAD → Remote (Push)¶
When your branch is ready for the world:
- Moves HEAD → Remote
- Shares your work with teammates
Conflicts? Git stops you. That’s good—it prevents sending broken code into battle.
5. Remote → HEAD / Working Directory (Fetch & Pull)¶
To bring your repo up to date:
or in one command:
fetch→ grabs remote changes without touching your branch (Remote → Local)merge→ integrates fetched changes into your branch (HEAD ← fetched changes)pull= fetch + merge
Keep your local repo in sync before making big moves. Avoid surprise conflicts.
6. Visual Flow Diagram¶
Here’s a conceptual diagram of Git areas and commands:
- Shows Working Directory ↔ Index ↔ HEAD ↔ Remote
- Highlights which commands update WD, Index, or HEAD, and which leave history intact

Pro tip: Memorize this flow. Once you can picture it, every command makes sense instantly.
7. Command Cheat Sheet¶
| Action | From → To | Command |
|---|---|---|
| Stage changes | WD → Index | git add <file> |
| Undo changes | Index → WD | git restore <file> |
| Commit | Index → HEAD | git commit -m "msg" |
| Amend last commit | HEAD → HEAD | git commit --amend |
| Unstage | HEAD → Index | git restore --staged <file> |
| Reset staging | HEAD → Index | git reset <file> |
| Push | HEAD → Remote | git push origin <branch> |
| Fetch | Remote → Local | git fetch origin |
| Pull | Remote → HEAD | git pull origin <branch> |
Print it. Stick it by your terminal. Use it daily.
Git Command Flow Cheat Sheet¶
| Task (source → target) | Description | Command |
|---|---|---|
| Remote → HEAD | Update local branch | git fetch + git merge / git pull |
| Remote → Index | Stage files from remote | git restore --source=origin/main --staged <file> |
| Remote → WD | Restore working dir from remote | git restore --source=origin/main <file> |
| HEAD → Index | Stage/unstage from last commit | git restore --staged <file> / git reset HEAD <file> |
| Index → WD | Restore staged version | git restore <file> |
| HEAD → WD | Discard changes | git restore --source=HEAD <file> / git reset --hard HEAD |
Key Notes & Best Practices¶
-
git restoreis your go-to tool. -
Restoring from HEAD or a commit does not touch HEAD—it updates WD or Index only.
-
You can choose
--stagedto update the Index, or omit it to update only the Working Directory. -
git resetis powerful for staging + HEAD moves. -
git reset <file>→ unstage without touching WD -
git reset --hard HEAD→ resets Index + WD to last commit -
git checkoutis legacy. -
Can still restore files or switch branches, but may create detached HEAD situations.
-
Prefer
restoreandswitchinstead ofcheckout. -
git revert <commit> -
Safely undo commits in shared history by creating a new commit that inverses changes.
- Unlike
reset, it does not rewrite history, making it safe for remote branches.
Memorize: restore = safe, targeted updates; reset = staging + HEAD moves; revert = safe undo commits. Legacy
checkoutonly when needed.
Rules of Thumb¶
- Use
git restorefor files — it safely updates WD or index without affecting commits. - Use
git resetfor commits — moves HEAD and optionally unstages or discards changes. - Use
git revertto undo commits in a shared history — creates a new commit. - Use
git checkoutprimarily to switch branches or view old commits (legacy usage). - Always be cautious with
reset --hardandpush --force— they can permanently discard work.
Handling Local branches
Merging and rebasing are your primary tools for integrating work from other branches. Read this Git Branch Operations docu to understand how they work
Syncing with Remote¶
Git provides commands to keep local and remote branches in sync:
| Task | Command(s) |
|---|---|
| Update current branch from remote | git pull (merge or rebase depending on configuration) |
| Pull with rebase | git pull --rebase |
| Pull only if fast-forward | git pull --ff-only |
| Push local changes to remote | git push |
| Force push (overwrite remote) | git push --force (use with caution) |
Read this docu about how to manage Local Modifications and Remote Changes in Git for a deeper understanding of how these commands operate
Notes:
git pullfetches remote commits and merges or rebases them into your current branch.- Pulling updates HEAD and may update Index/WD if there are conflicts.
- Pushing sends HEAD commits to the remote branch.
Mastering these areas and commands will make Git a lot less confusing, and help you confidently manage your changes without accidental loss.