The Time Machine
One of the main reasons we use version control is the ability to undo mistakes. Git provides several tools for this, ranging from safe reversals to destructive history rewriting.
Discarding Local Changes
If you have modified a file but haven’t staged it yet, and you want to throw away your changes (revert the file to how it looks in the last commit):
git restore file.txt
(In older Git versions, this was done with git checkout -- file.txt)
If you have staged a file and want to unstage it (but keep the changes in your file):
git restore --staged file.txt
(Previously git reset HEAD file.txt)
The git reset Command
git reset is a powerful tool that moves the HEAD pointer (and the branch pointer) to a specific commit. It has three main modes that determine what happens to your Index (staging area) and Working Directory.
1. Soft Reset (--soft)
Moves HEAD to the target commit. Does not touch the Index or Working Directory. Result: Your changes since that commit are now “staged” and ready to be committed again. Useful for squashing the last few commits.
2. Mixed Reset (--mixed) - Default
Moves HEAD to the target commit. Resets the Index to match the target commit. Does not touch the Working Directory. Result: Your changes are preserved but are “unstaged”.
3. Hard Reset (--hard)
Moves HEAD, resets Index, and overwrites the Working Directory. Result: All changes since the target commit are lost permanently.
# Go back 3 commits, throw away everything
git reset --hard HEAD~3
Reverting Public Commits
If you have already pushed your changes to a shared repository, using reset is dangerous because it rewrites history that others might have based their work on.
Instead, use git revert.
git revert <commit-hash>
This creates a new commit that applies the exact opposite of the changes introduced by the target commit. It is a “forward-moving” undo.
Example:
- Commit A adds line “Hello”.
git revert Acreates Commit B which removes line “Hello”.
Amending the Last Commit
If you just committed but forgot to add a file, or made a typo in the message, you don’t need to reset.
git add forgotten_file.js
git commit --amend
This replaces the last commit with a new one containing the combined changes. Do not use this if you have already pushed the commit.
Cleaning Untracked Files
If your directory is cluttered with untracked files (build artifacts, temporary files) that you want to delete:
git clean -fd
-fmeans force.-dmeans remove directories too.
Warning: This deletes files permanently.
Which command should you use to undo a commit that has already been pushed to a shared team branch?
Unstaging a File
# You accidentally staged 'secret.key'. Unstage it without deleting the file. git --staged secret.key