You edit a file, pass tests and commit, yet a teammate receives an incomplete change. Git may not have lost anything: staged content can differ from the working file. Understanding staging gives you control over the next commit.
This guide assumes a repository with an initial commit and no active merge conflict. Replace example paths with real ones. Add and restore --staged change the index; scope them to files you have identified.
1. Separate three states
| Component | Meaning in an ordinary workflow |
|---|---|
| HEAD | The current commit used as a comparison baseline |
| Index or staging area | Content prepared for the next commit |
| Working tree | The files you read and edit |
The git-add documentation explains that add records content at the time it runs. Subsequent edits are not staged automatically, so one file can contain both staged and unstaged changes.
Suppose you stage a calculation fix, then add input validation without staging again. An ordinary commit includes the indexed change, not automatically every new line visible in your editor.
2. Choose the right comparison
Git diff offers different comparisons. For tracked files in an ordinary state:
git status --short
git diff -- src/Example.php
git diff --cached -- src/Example.php
git diff HEAD -- src/Example.php
git diffcompares working tree with index: unstaged changes.git diff --cachedcompares index with HEAD: staged changes.git diff HEADshows net working-tree changes against HEAD without separating those layers.
Untracked files do not automatically appear as ordinary diffs. Check status for new files. An empty git diff does not prove there is nothing to commit: all changes may already be staged.
3. Stage narrowly and review
git add -- src/Example.php
git diff --cached --stat
git diff --cached
Statistics can reveal unexpected files but cannot replace reading content. Inspect configuration, fixtures, generated files and sensitive values. Avoid habitual stage-everything commands when unrelated work shares a directory.
git add -p -- src/Example.php lets you select hunks. Mechanical separation does not guarantee a complete change: a staged hunk may rely on an unstaged function or import.
4. Unstage without discarding working edits
The git-restore manual distinguishes index and working-tree targets. Under this guide's assumptions, this restores the index entry from HEAD without changing the working file:
git restore --staged -- src/Example.php
git status --short
git diff -- src/Example.php
Do not omit --staged or add --worktree when your aim is only to unstage. Other forms can overwrite working edits. Unstaging also does not preserve an intermediate version existing only in the index; save that version first if needed.
5. Test what you intend to deliver
Check whether tests depend on unstaged working-tree content. Tests run in the current directory normally use working files, not a separate application assembled from the index.
When splitting changes into commits, verify each deliverable snapshot through the project's test workflow, potentially in an isolated environment. Do not destroy uncommitted work merely to obtain a clean test directory.
6. Pre-commit checklist
git diff --cached --check
git diff --cached --name-status
git diff --cached
git status --short
--check detects some whitespace errors and conflict markers, not logical or security correctness. Commit only after the selected content meets the team's process.
- Staged changes have one clear purpose.
- No required new files or dependencies are missing.
- No credentials, sensitive logs or personal data are included.
- Tests reflect the intended snapshot.
- Remaining unstaged work is preserved intentionally.
Staging is where you select the deliverable, not merely another button before commit. Reviewing the staged diff helps produce clearer history and fewer incomplete handoffs.




No comments yet. Be the first to share your thoughts.