Search Knowledge

© 2026 LIBREUNI PROJECT

Undoing Changes

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
Code
rectangle "Commit History" {
rectangle C1
rectangle C2
rectangle C3
C1 <- C2
C2 <- C3
}

rectangle "HEAD -> C3" as head

rectangle "Reset Modes" {
rectangle "--soft" as soft
rectangle "--mixed" as mixed
rectangle "--hard" as hard
}

soft --> C1 : Moves HEAD only
mixed --> C1 : Moves HEAD + Index
hard --> C1 : Moves HEAD + Index + WorkDir
Commit HistoryReset ModesC1C2C3--soft--mixed--hardHEAD -> C3Moves HEAD onlyMoves HEAD + IndexMoves HEAD + Index + WorkDir

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 A creates 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
  • -f means force.
  • -d means remove directories too.

Warning: This deletes files permanently.

git
1# Setup
2git init
3echo "V1" > file.txt
4git add file.txt
5git commit -m "Version 1"
6 
7echo "V2" > file.txt
8git commit -am "Version 2"
9 
10# Soft reset to V1
11git reset --soft HEAD~1
12git status
13# file.txt shows as modified/staged

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
Previous Module Inspecting History