﻿---
title: Understanding Git Reset and Revert
date: 2024-05-05
excerpt: Learn how git reset and git revert undo commits, move HEAD, affect the staging area and working tree, and preserve or rewrite history.
tags:
  - Git
cover: https://assets.vluv.space/cover/ToolChain/GitRevert.webp
updated: 2026-07-08 08:30:25
lang: en
i18n:
  cn: /reset-and-revert
  translation: 2
---

## Introduction

What should you do when you accidentally commit something, or when a bad change needs to be undone during project development? Git Reset can help us move back in Git history, remove mistaken commits or changes, and clear the way for the project to continue.

## Git Core Concepts: Working Directory, Staging Area, and Repository 📦

Before understanding Git Reset, we first need to understand Git's three core areas:

```
┌─────────────────────────────────────────────────────────────┐
│                        Git 仓库                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                    版本库 (.git)                    │    │
│  │  ┌─────────────┐    ┌─────────────────────────┐     │    │
│  │  │   HEAD      │    │       对象区            │     │    │
│  │  │  指向当前   │    │  ┌─────────────────┐    │     │    │
│  │  │   分支      │    │  │   暂存区        │    │     │    │
│  │  └─────────────┘    │  │  (Index/Stage)  │    │     │    │
│  │                     │  └─────────────────┘    │     │    │
│  │                     │  ┌─────────────────┐    │     │    │
│  │                     │  │   对象数据库    │    │     │    │
│  │                     │  │  (Commit历史)   │    │     │    │
│  │                     │  └─────────────────┘    │     │    │
│  │                     └─────────────────────────┘     │    │
│  └─────────────────────────────────────────────────────┘    │
│                           │                                 │
│                           ▼                                 │
│              ┌─────────────────────────┐                    │
│              │      工作目录           │                    │
│              │   (Working Directory)   │                    │
│              └─────────────────────────┘                    │
└─────────────────────────────────────────────────────────────┘
```

- **Working Directory**: the actual files you are editing, representing the current state of the project.
- **Staging Area/Index**: an area between the working directory and the repository, used to selectively prepare changes for commit.
- **Repository**: where all commit history and the object database are stored.

**Git file flow**:
1. `git add` → add working directory changes to the staging area.
2. `git commit` → save staged changes to the repository.

Understanding these three areas is essential for understanding the three modes of `git reset`.

## reset Command Format and Options 🛠️

Before introducing use cases for Git Reset, let's look at the command format and options. The general format is:

```shell
git reset [option] <commit>
```

Git Reset has three main options:

- `{shell} git reset --soft <commit>`: moves HEAD to the specified commit, but leaves the staging area and working directory unchanged. This means all changes remain staged and can be committed again. It is a good way to undo a commit while keeping changes ready for recommit.
  Only changes the position of HEAD; it does not change the staging area or working directory.
- `{shell} git reset --mixed <commit>`: the default mode of `git reset`. This moves HEAD to the specified commit and also updates the staging area to match that commit. However, files in the working directory do not change. Your changes still exist, but they are no longer staged, so you can stage and commit them again.
  Changes HEAD and the staging area, but not the working directory.
- `{shell} git reset --hard <commit>`: moves HEAD to the specified commit and updates both the staging area and working directory to match it. This permanently deletes all changes since the specified commit. It is dangerous, because it permanently removes changes, so make sure you do not need them before using it.
  Changes HEAD, the staging area, and the working directory.
- `{shell} git reset --merge/keep` is less commonly used and will not be covered here.

> `git reset` can also operate on files. Use `git reset <file_name>` to unstage the corresponding file from the staging area.

### Use Cases

**Fixing a bad commit** 🐞

Sometimes we may accidentally commit bad code or files, or even sensitive information. You can use `git reset` to return to an earlier commit, undo the mistaken commit, then modify the files again and make sure passwords or other sensitive data are no longer committed to the repository.

**Rolling back to a stable version** ⏪

Another common use case for Git Reset is rolling a project back to a stable version. Sometimes, while developing a new feature or making experimental changes, we may discover hard-to-fix problems that prevent the project from working normally. By returning to an earlier stable version, you can quickly undo the problematic changes and restore the project to a usable state.

For example, suppose you add new features to a website and discover that they cause serious performance problems. You want to discard these changes and return to a known stable version. With Git Reset, you can easily go back to an earlier commit, undo those changes, and make the project work normally again.

## Git Revert

`git reset` can undo commits, but it removes commit history. If you want to preserve commit history, use `git revert`.

`git revert <commit>`, where `<commit>` is the hash or reference of the commit you want to undo. Git automatically creates a new commit that reverses the specified changes while preserving the history of the undo operation. At that point, your code returns to the state before the reverted commit.
