Agentic AI with Java: Live Cohort
GitGit History and Advanced Operations

Undoing Changes in Git

Mistakes are a normal part of development. You may modify the wrong file, stage something accidentally, commit too early, or discover that a previous commit needs to be undone.

Git provides different commands for these situations. The important thing is to first identify what you want to undo and where that change currently exists.

Discarding Uncommitted Changes

Suppose you modify a file but decide that you don't want those changes.

git restore <filename>

Example:

git restore Login.java

Git restores the file to the version from the latest commit.

Be Careful

Any uncommitted changes in that file are discarded.

Before:

Working Directory
      ↓
Modified Login.java

git restore Login.java

      ↓

Last committed version

Older Syntax

You may also see:

git checkout -- Login.java

This works, but git restore is preferred because modern Git separates file restoration from branch/commit switching.


Unstaging a File

Sometimes you stage a file with git add and then realize it shouldn't be part of the next commit.

git restore --staged <filename>

Example:

git restore --staged config.txt

This does not delete your changes.

It simply moves the file out of the staging area:

Staging Area
     ↓
git restore --staged
     ↓
Working Directory

Your modifications remain available for further editing.

Older Syntax

You may encounter:

git reset HEAD config.txt

This also unstages the file.


Fixing the Most Recent Commit

Sometimes the latest commit is almost correct, but you need to make a small correction.

For example:

  • The commit message contains a typo.
  • You forgot to include a file.
  • You need to make a small adjustment to the commit.

Use:

git commit --amend

To change the commit message directly:

git commit --amend -m "Add user authentication"

Add a Forgotten File

git add UserService.java
git commit --amend --no-edit

--no-edit keeps the existing commit message.

Important

Amending creates a new version of the latest commit. Avoid amending commits that have already been pushed and shared with other developers unless you understand the consequences of rewriting history.


Reverting a Commit

What if a commit has already been shared and you want to undo its changes?

Use:

git revert <commit-id>

For example:

git revert a1b2c3d

Git creates a new commit that reverses the changes introduced by the selected commit.

Before:

A ─── B ─── C
          ↑
       unwanted


After revert:

A ─── B ─── C ─── D
                  ↑
             reverse of C

The original commit C remains in the history.

Why Is Revert Considered Safe?

Because it does not remove existing commits or rewrite the branch's history.

This makes it the usual choice for shared branches such as main.


Resetting to an Earlier Point

git reset is different from git revert.

Instead of creating a new commit, reset moves the current branch's HEAD to another commit.

Suppose you have:

A ─── B ─── C ─── D

You reset to B:

git reset <options> B

The effect depends on the option you choose.

git reset --soft

git reset --soft <commit-id>

Moves HEAD back but keeps the changes from the removed commits staged.

HEAD moves
    ↓
A ─── B

Changes from C and D
remain staged

Useful when you want to reorganize or combine recent commits.

git reset --mixed

git reset --mixed <commit-id>

Moves HEAD back and removes the changes from the staging area, but keeps them in the working directory.

HEAD → B

Changes from C and D
remain as unstaged modifications

This is the default reset mode if no option is specified:

git reset <commit-id>

git reset --hard

git reset --hard <commit-id>

Moves HEAD back and removes changes from both:

  • Staging area
  • Working directory
HEAD → B

Changes after B
      ↓
   Discarded

This can permanently discard uncommitted work.

Avoid using --hard casually, as this can permanently discard uncommitted work. Especially on branches containing work that others depend on.


Reset Comparison

ModeHEADStaging AreaWorking Directory
--softMovesChanges remain stagedChanges remain
--mixedMovesChanges become unstagedChanges remain
--hardMovesChanges removedChanges removed

Easy Way to Remember

Think of the three levels as:

HEAD
 ↓
Staging Area
 ↓
Working Directory
  • Soft → Move HEAD, keep everything else.
  • Mixed → Move HEAD and unstage.
  • Hard → Move HEAD and discard changes.

Revert vs Reset

git revertgit reset
Creates a new commitMoves the branch to another commit
Preserves existing historyCan rewrite history
Usually safer for shared branchesBetter suited to local/private work
Original commit remainsCommits may become unreachable from the branch
Preferred for undoing shared changesUseful for reorganizing local history

Git_Command_Selection


Quick Reference

CommandPurpose
git restore <file>Discard uncommitted changes in a file
git restore --staged <file>Unstage a file without losing its changes
git commit --amendModify the latest commit
git revert <commit>Create a new commit that undoes another commit
git reset --soft <commit>Move HEAD, keeping changes staged
git reset --mixed <commit>Move HEAD, keeping changes unstaged
git reset --hard <commit>Move HEAD and discard changes

Written By: Muskan Garg

How is this guide?

Last updated on