Git

Undoing Changes

Git · 10 entries

Discard Working Directory Changes

syntax
git restore <file>
git restore .
example
# Discard changes to one file:
git restore src/app.js

# Discard all unstaged changes:
git restore .

Note WARNING: This permanently discards your uncommitted changes — there is no undo. The file reverts to whatever is in the staging area (or HEAD if nothing is staged). Double-check with git diff first.

Unstage a File

syntax
git restore --staged <file>
example
git restore --staged secrets.env
git restore --staged .

Note This moves the file from staged back to unstaged. Your actual changes in the working directory are preserved — nothing is lost. This is the modern replacement for git reset HEAD <file>.

Undo Commit, Keep Changes Staged

syntax
git reset --soft HEAD~<n>
example
# Undo the last commit, keep everything staged:
git reset --soft HEAD~1

Note Moves HEAD back but leaves your changes in the staging area, ready to be committed again. Perfect for rewriting a commit message or combining the last few commits into one.

Undo Commit, Keep Changes Unstaged

syntax
git reset HEAD~<n>
git reset --mixed HEAD~<n>
example
# Undo last commit, unstage changes but keep them:
git reset HEAD~1
output
Unstaged changes after reset:
M  src/auth.js
M  src/routes.js

Note --mixed is the default mode. Changes end up in your working directory as unstaged modifications. You can re-add specific files and commit differently.

Undo Commit and Discard All Changes

syntax
git reset --hard HEAD~<n>
git reset --hard <commit>
example
# Throw away the last commit entirely:
git reset --hard HEAD~1

# Reset to a specific commit:
git reset --hard a1b2c3d
output
HEAD is now at f4e5d6c Update API response format

Note DANGER: This permanently destroys uncommitted changes AND the commits you reset past. There is no undo for uncommitted work. Commits can be recovered via git reflog within ~30 days, but unstaged/uncommitted edits are gone forever.

Revert a Commit (Safe Undo)

syntax
git revert <commit>
example
git revert a1b2c3d
git revert HEAD
output
[main g7h8i9j] Revert "Add user authentication endpoint"
 2 files changed, 3 deletions(-), 45 insertions(-)

Note Revert creates a NEW commit that undoes the changes from the specified commit. Unlike reset, it doesn't rewrite history, making it safe for shared/public branches. Always prefer revert over reset for pushed commits.

Amend the Last Commit

syntax
git commit --amend [-m "new message"]
example
# Fix the commit message:
git commit --amend -m "Add user auth endpoint with JWT support"

# Add forgotten files to the last commit:
git add forgotten-file.js
git commit --amend --no-edit
output
[main b2c3d4e] Add user auth endpoint with JWT support

Note WARNING: Amending rewrites the commit hash. Never amend a commit that has already been pushed to a shared branch — other developers who pulled the original commit will have conflicts. Use git revert instead for pushed commits.

Restore a File from a Specific Commit

syntax
git restore --source=<commit> <file>
git checkout <commit> -- <file>
example
# Restore app.js to how it was 3 commits ago:
git restore --source=HEAD~3 src/app.js

# Classic syntax:
git checkout a1b2c3d -- src/app.js

Note This replaces the file in your working directory with the version from that commit. The change is staged automatically. Useful for recovering a deleted or broken file without resetting the whole branch.

Remove Untracked Files

syntax
git clean -f [-d] [-n]
example
# Preview what would be deleted:
git clean -n -d

# Actually delete untracked files and directories:
git clean -f -d
output
Would remove build/
Would remove temp.log

Removing build/
Removing temp.log

Note DANGER: This permanently deletes files that are not tracked by Git. Always run with -n (dry run) first to preview what will be removed. Use -x to also remove files that match .gitignore patterns (like node_modules).

Reset a Single File to HEAD

syntax
git checkout HEAD -- <file>
git restore --source=HEAD --staged --worktree <file>
example
# Fully reset one file (both staging and working directory):
git restore --source=HEAD --staged --worktree src/config.js

Note This restores the file to exactly how it is in the last commit, discarding both staged and unstaged changes to that specific file only.