Undoing Changes and Resetting

INPUT · Slides

Undoing changes (restore / reset / revert)

01 / 11

The primary benefit of Git: safely going back

Up to this point, you have focused on recording commits. However, the greatest value of a version control system is the ability to reliably rewind to any previous state.

Knowing you can always revert changes gives you the confidence to refactor boldly and experiment freely.

In this chapter, you will master four essential undo commands. The crucial concept is that which command you use depends strictly on which area you want to restore.

02 / 11

Identify which area needs to be restored first

Git has dedicated undo commands for each of its three areas (working tree, staging area, repository):

  • Discard uncommitted changes in the working tree → git restore <file>
  • Unstage changes from the staging area (index) → git restore --staged <file>
  • Rewind local commit history in the repository → git reset
  • Safely negate commits that have already been pushed to remote → git revert

While we say "undo", the exact operation depends entirely on the target area. Identifying the area makes choosing the command straightforward.

03 / 11

git restore — Discarding working tree changes

If you edited a file and decide you do not want those changes, run git restore <filename>.

Your working tree file is instantly restored to the state of the latest commit.

Be aware: discarded uncommitted changes cannot be recovered. Because they were never committed, Git has no snapshot of them in its database.

$ git restore prices.txt$ git statusOn branch mainnothing to commit, working tree clean

04 / 11

git restore --staged — Unstaging files

If you ran git add and then realized you do not want to include a certain file in the upcoming commit, pass --staged.

The file is removed from the staging area, but your edits in the working tree are completely preserved.

Forgetting --staged discards the working tree edits entirely, so always verify whether you need --staged before executing.

$ git add .$ git restore --staged secret.txt$ git statusChanges to be committed:	new file:   recipe.txtUntracked files:	secret.txt

05 / 11

git commit --amend — Modifying the latest commit

If you made a typo in your commit message or forgot to include a file, run git commit --amend.

Rather than creating an extra commit, it overwrites and replaces the most recent commit with the current staged contents and message. If you forgot a file, git add it first, then run --amend.

Because this generates a new commit hash, the commit ID will change.

$ git commit -m "added th"$ git commit --amend -m "added the notes"[main 7c1e4a9] added the notes

06 / 11

Never amend commits that have already been pushed

A changed commit ID means rewriting history.

If you amend a commit that teammates have already pulled from the remote repository, your local branch will diverge with an incompatible commit ID. This causes conflicts across the team.

The golden rule: only use git commit --amend on local commits that have not yet been pushed to remote.

07 / 11

git reset — Moving the branch HEAD pointer back

To undo commits and roll back your branch pointer to an earlier state, use git reset.

It moves the branch HEAD pointer to a previous commit (e.g., HEAD~1 for one commit back, HEAD~2 for two).

git reset provides three main modes that determine how much of your working state is preserved.

$ git log --oneline9f2a1c4 unwanted commit3b7e5d1 valid commit$ git reset --soft HEAD~1$ git log --oneline3b7e5d1 valid commit

08 / 11

The three reset modes (--soft / --mixed / --hard)

The difference lies in what remains in your staging area and working tree after the reset:

  • --soft … Undoes the commit only. Both the staging area and working tree edits are preserved
  • --mixed (default if omitted) … Undoes the commit and unsets the staging area. Working tree edits are preserved
  • --hard … Undoes everything: commit, staging area, and working tree. All uncommitted work is deleted

If you simply want to redo a commit, use --soft or --mixed.

--hard permanently deletes uncommitted edits with no way to recover them. Always check your status before using --hard.

09 / 11

git revert — Creating an inverse commit

Because git reset rewrites history, you cannot use it on commits already shared on a remote repository.

To undo a pushed commit, use git revert <commit-id>.

Instead of deleting past commits, git revert appends a new commit that applies the exact inverse changes of the target commit. Because history is preserved, teammates can pull the fix cleanly without conflicts.

$ git revert HEAD[main 4d8b2f1] Revert "deleted it by mistake"$ git log --oneline4d8b2f1 Revert "deleted it by mistake"9f2a1c4 deleted it by mistake3b7e5d1 made the price list

10 / 11

When to reset vs when to revert

The decision rule is simple and absolute:

  • Unpushed local commits → use git reset (keeps history clean)
  • Pushed shared commits → use git revert (safely appends an inverse commit)

Freely reshape your own local history with reset; use revert once changes have been published to collaborators.

11 / 11

How to approach the exercises

The exercises in this chapter begin with deliberate mistakes in the workspace.

Before typing, run git status and git log --oneline to inspect the state of your working tree, staging area, and commit history.