Git has several undo commands because “undo” can mean changing the working tree, changing the staging area, moving a branch, or creating a new commit that reverses an older one.
Choose the command based on where the unwanted change exists and whether its commit has been shared.
Inspect Before Changing Anything
git status
git diff
git diff --staged
git log --oneline --decorate -10These commands distinguish unstaged content, staged content, and commit history. That distinction determines the safe recovery action.
Quick Decision Table
| Situation | Starting command | Main effect |
|---|---|---|
| Staged the wrong file | git restore --staged <path> | Remove it from the next proposed commit; keep working content |
| Want to discard an unstaged tracked edit | git restore <path> | Replace working content; destructive |
| Need to pause unfinished tracked work | git stash push | Store work temporarily and clean the working tree |
| Need to undo a published commit | git revert <commit> | Create a new inverse commit |
| Need to remove the latest unpublished local commit | git reset --mixed HEAD~1 | Move the branch back; keep changes unstaged |
| Need to edit the latest unpublished commit | git commit --amend | Replace the latest commit |
Warning: Commands that replace working-tree content or move branch history can discard work. Inspect the state and create a safety branch or commit when uncertain.
Unstage Without Losing the Edit
git restore --staged switch1.cfgThis updates the index so the path is no longer part of the proposed next commit. The working-tree edit remains.
before: change is staged + present in working tree
after: change is unstaged + still present in working treeOlder documentation may use git reset HEAD -- <path> for this operation. git restore --staged expresses the intent more directly.
Discard an Unstaged Tracked Change
git restore switch1.cfgThis replaces the working-tree version with content from the index by default. The discarded working-tree edit is normally difficult or impossible to recover through Git because it was never committed.
Always inspect first:
git diff -- switch1.cfgOlder tutorials often use git checkout -- switch1.cfg. Modern Git provides git restore for file restoration and git switch for changing branches, avoiding the overloaded checkout command.
Temporarily Store Unfinished Work
git stash push -m "WIP before urgent routing fix"By default, stash saves staged changes and modifications to tracked files, then restores a clean working state. Untracked files are not included unless requested:
git stash push -u -m "WIP including untracked files"Inspect stored entries:
git stash list
git stash show --patch stash@{0}Restore the work:
# Apply and keep the stash entry
git stash apply stash@{0}
# Apply, then drop the entry if application succeeds
git stash popApplying a stash can produce conflicts if the current files changed in overlapping areas.
Note: A stash belongs to the local repository and is not normally transferred by
git push. It is temporary working storage, not a team collaboration mechanism or backup.
Revert a Shared Commit
git log --oneline
git revert e871a41git revert creates a new commit that applies the inverse of the selected commit. The original commit remains in history:
e871a41 Configure Loopback0 on switch1
11123ce Configure Loopback0 on switch2
295922e Revert "Configure Loopback0 on switch1"This is normally safer for a published branch because it adds history instead of moving the branch backward.
A revert can conflict, and reversing an old commit may affect later changes that depend on it. Review and test the result.
For infrastructure, a Git revert changes the desired files. It does not automatically reverse a configuration already deployed to a switch. Deployment and validation are separate steps.
Reset an Unpublished Local Commit
Suppose the latest commit should not remain in local history and has not been shared:
git reset --mixed HEAD~1The default mixed reset:
- moves the current branch to the parent commit
- resets the staging area to that commit
- leaves the former commit’s file changes in the working tree
The changes can then be edited and committed again.
Reset modes
| Mode | Moves branch | Resets index | Replaces working tree |
|---|---|---|---|
--soft | Yes | No | No |
--mixed | Yes | Yes | No |
--hard | Yes | Yes | Yes |
git reset --hard can destroy uncommitted working-tree changes. It should not be used as a generic fix.
Moving a published branch backward also rewrites the history others may have based work on. Prefer git revert for a shared branch unless the team has explicitly agreed to rewrite it.
Amend the Latest Unpublished Commit
Stage the corrected content, then replace the latest commit:
git add switch1.cfg
git commit --amendTo change only its message:
git commit --amend -m "Configure Loopback0 on core switch"Amend creates a new commit with a different identifier. Avoid amending a commit that others have already fetched unless the shared workflow explicitly allows history rewriting.
Removing a File vs. Stopping Tracking
Remove the file and stage its deletion:
git rm old-switch.cfgKeep the local file but remove it from the index:
git rm --cached local-settings.cfgThe second command does not erase copies already present in earlier commits. If the file contained a secret, rotate the credential. Merely deleting, reverting, or ignoring the file does not make an exposed secret safe again.
A Safer Recovery Habit
When the correct undo command is unclear:
git status
git diff
git diff --staged
git log --oneline --decorate -10
git branch safety-before-undoThe safety branch gives the current commit a durable name. It does not save uncommitted working-tree content, so stash or commit that content separately if it matters.
Common Mistakes
- Using
git restore <path>before reviewing the unstaged difference - Assuming stash includes untracked files without
-u - Treating stash as a remote backup
- Resetting a commit already shared with other developers
- Using
git reset --hardwhen only unstaging was required - Believing revert erases the original commit
- Believing a Git revert automatically rolls back deployed infrastructure
- Deleting a committed secret without rotating it
TL;DR
- Inspect working-tree, staging, and history state before undoing.
git restore --stagedunstages while keeping the edit.git restore <path>discards an unstaged tracked edit.- Stash temporarily stores local unfinished work;
-uis needed for untracked files. - Revert adds an inverse commit and is usually appropriate for shared history.
- Reset moves a branch and is best restricted to unpublished local work.
--hardcan destroy uncommitted content.
Resources
Note: Recovery commands and safety boundaries were checked against current Git documentation in July 2026.