How to Reset Changes in Git

Updated on 20 May, 2025
Learn how to safely use git reset to undo commits, unstage files, and discard changes.
How to Reset Changes in Git header image

The git reset command lets you undo commits, unstage files, or discard changes from your working directory. It works by modifying Git's three main states, HEAD, Index, and Working Directory, depending on the option used. While powerful, git reset can be destructive if used carelessly, especially with --hard. This article explains how it works and when to use each option.

Git Reset Common Options

Git offers three main options for the reset command. Each affects the repository’s HEAD, staging area (Index), and working directory differently. The table below summarizes their behavior:

Flag HEAD Staging Area Working Dir Summary
--soft Yes No No Keeps changes staged
--mixed Yes Yes No Unstages but keeps file changes
--hard Yes Yes Yes Discards all committed changes

Let’s explore how each option works in practice with syntax, behavior, and typical use cases.

git reset --soft

Command Syntax and Breakdown

git reset --soft <commit>
  • git reset: Base command that modifies Git history.
  • --soft: Moves the HEAD pointer but leaves the staging area and working directory unchanged.
  • <commit>: The target commit to reset to (e.g., HEAD~1, a specific commit hash).

What the Flag Does

  • Moves HEAD to the specified commit.
  • Leaves all changes from the reset commit staged (in the index).
  • Does not touch your working directory or file contents.

Use this when you want to amend or rework the previous commit without redoing the changes manually.

Command Demonstration

  1. Assume you made a second commit but realized you want to reword it or combine it with the first.

    console
    $ git log --oneline
    

    Output:

    abc1234 Second commit
    def5678 Initial commit
  2. Reset the last commit but keep its changes staged.

    console
    $ git reset --soft HEAD~1
    

    This command removes abc1234 from history, but the changes remain staged.

  3. Check the current Git state.

    console
    $ git status
    

    Output:

    On branch main
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
        modified: file.txt
  4. Recreate or amend the commit.

    console
    $ git commit -m "Amended commit"
    

    This creates a new commit with the same changes, allowing you to update the message or combine changes.

git reset --mixed (default)

Command Syntax

git reset --mixed <commit>
  • git reset: Base command that modifies Git history.
  • --mixed: Resets the HEAD and updates the staging area to match the target commit. It leaves your working directory unchanged.
  • <commit>: The commit hash or reference to reset to (e.g., HEAD~1).

If no flag is provided, Git defaults to --mixed.

What the Flag Does

  • Moves HEAD to the specified commit.
  • Clears the staging area (Index) to match the target commit.
  • Keeps all changes in your working directory.

Use this when you want to undo a commit and unstage its changes, but continue editing your files.

Command Demonstration

  1. View your recent commits.

    console
    $ git log --oneline
    

    Output:

    abc1234 Second commit  
    def5678 Initial commit
  2. Reset the last commit and unstage the changes.

    console
    $ git reset --mixed HEAD~1
    

    This removes the most recent commit (abc1234) from history and clears the staging area, while keeping the changes in your working directory.

  3. Check the current Git state.

    console
    $ git status
    

    Output:

    On branch main  
    Changes not staged for commit:  
      (use "git add <file>..." to update what will be committed)  
        modified: file.txt
  4. Restage and recommit if needed.

    console
    $ git add file.txt
    
    console
    $ git commit -m "Revised commit"
    

    This approach is helpful when you want to revise or split changes without losing your progress.

git reset --hard

Command Syntax

git reset --hard <commit>
  • git reset: Base command that modifies Git history.
  • --hard: Resets HEAD, the staging area, and the working directory to match the target commit.
  • <commit>: The commit hash or reference to reset to (e.g., HEAD~1).

Use --hard with caution, as it permanently deletes committed changes unless recoverable via git reflog.

What the Flag Does

  • Moves HEAD to the specified commit.
  • Clears the staging area to match that commit.
  • Replaces the contents of your working directory with the version from that commit.

Use this when you want to completely discard changes and revert your repository to a clean state.

Command Demonstration

  1. View your commit history.

    console
    $ git log --oneline
    

    Output:

    abc1234 Buggy commit  
    def5678 Stable baseline
  2. Perform a hard reset to discard recent changes.

    console
    $ git reset --hard HEAD~1
    

    This resets HEAD, clears the staging area, and restores all files to the state of the previous commit (def5678).

  3. Confirm the reset state.

    console
    $ git status
    

    Output:

    On branch main  
    nothing to commit, working tree clean

    All file modifications from the discarded commit are gone. If you need to recover them, use git reflog.

Reset Changes in Git

You can use git reset to move your project back to a specific commit in history. This section explains the syntax, flag behavior, and demonstrates how to reset changes safely and intentionally. These commands are ideal for safely navigating through commit history during iterative development.

Command Syntax

git reset [--soft|--mixed|--hard] <commit>
  • --soft: Moves HEAD to the target commit and keeps changes staged.
  • --mixed: Moves HEAD and unstages changes while preserving working directory content.
  • --hard: Resets HEAD, Index, and working directory — discards all changes.
  • <commit>: Target commit hash or relative reference (e.g., HEAD~2, a1b2c3d).

If no flag is provided, Git defaults to --mixed.

Reset to a Specific Commit

  1. List your commit history to find the target hash.

    console
    $ git log --oneline
    

    Output:

    a1b2c3d Fix typo  
    9f8e7d6 Add login feature  
    8e7f6a5 Initial commit
  2. Reset to a specific commit using --soft, --mixed, or --hard.

    • Soft Reset (keep changes staged)

      console
      $ git reset --soft a1b2c3d
      

      Use this to reword or group commits without modifying your working directory.

    • Mixed Reset (default, keep file changes but unstage them).

      console
      $ git reset --mixed a1b2c3d
      

      Use this when you want to review or edit file changes after rollback.

    • Hard Reset (discard all changes).

      console
      $ git reset --hard a1b2c3d
      

      This removes all local changes and resets your project to the specified commit.

    Use git reflog if you need to recover after an accidental reset.

Undo Reset Changes in Git

You can undo a git reset by using the reflog, which tracks the movement of HEAD and other references.

Command Syntax and Breakdown

git reflog
  • Shows recent changes to HEAD, including resets and commits.
console
$ git reset --hard HEAD@{n}
  • Resets to a previous state from the reflog.
  • HEAD@{n} refers to how many actions ago that state was (e.g., HEAD@{1} is one step back).

Command Demonstration

  1. Perform a reset.

    console
    $ git reset --hard HEAD~1
    
  2. View the reflog.

    console
    $ git reflog
    

    Output:

    abc1234 HEAD@{0}: reset: moving to HEAD~1  
    def5678 HEAD@{1}: commit: Add login feature
  3. Undo the reset.

    console
    $ git reset --hard HEAD@{1}
    

    This restores the previous commit and discards the effects of the reset.

git reflog works with all reset types (--soft, --mixed, --hard). However, it’s most critical for --hard, which removes changes from the working directory and index. Make sure you act before git gc prunes unreachable commits.

Conclusion

By learning how to use git reset, you now understand how to undo commits, unstage changes, and discard unwanted modifications from your Git history. This command gives you precise control over the HEAD, staging area, and working directory, making it a crucial tool in any developer’s workflow.

Use the appropriate reset type based on what you want to preserve:

  • Use --soft to undo commits while keeping changes staged.
  • Use --mixed to unstage changes without touching your working directory.
  • Use --hard to completely discard changes and reset everything, only when you're sure no committed changes need to be kept.
Tags: