placeholderUnderstanding Git Reset and Revert

Understanding Git Reset and Revert

Learn how git reset and git revert undo commits, move HEAD, affect the staging area and working tree, and preserve or rewrite history.

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:

git reset [option] <commit>

Git Reset has three main options:

  • 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.
  • 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.
  • 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.
  • 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.