Difference Between the Git Reset, Revert, and Checkout Commands

Difference Between the Git Reset, Revert, and Checkout Commands

  1. Difference Between the Git Reset, Git Revert, and Git Checkout Commands
  2. Git Reset vs. Git Revert vs. Git Checkout
  3. Commit Level Operations
  4. File Level Operations

This article discusses the difference between the git reset, git revert, and git checkout commands. These are some of the most useful Git utilities that allow us to undo some changes in our repositories.

It is easy to mix up the commands, but by the end of this article, you will have gained the confidence to use and navigate your repository with the above commands.

Difference Between the Git Reset, Git Revert, and Git Checkout Commands

It will be easier to understand these commands if we are clear on the effect of each command on the three main components of a Git repository.

  1. The working directory
  2. Staged snapshot
  3. Commit history

We can also call the above components the Three Trees.

Git Checkout

What do we mean by checking out?

This operation relocates the HEAD pointer to a specified commit.

git checkout

The image above shows a sequence of commits in a Git repository. The HEAD and main branch pointers are currently at the commit d.

We can move our HEAD ref to any commit using the git checkout command.

For example, to move our HEAD ref to the commit b, we will run:

$ git checkout -b

We can use the git checkout command at the commit and file level. Checking out at the file level will update the file’s contents with the contents of the specified commit.

Git Revert

When reverting, we take a specific commit and create a new one that reverses the specified commit’s effect. The git revert commit only takes effect at the commit level and does not have file-level functionality.

Git Reset

When resetting, we take a specific commit, reset the Three Trees, and update a repository to match the state of the repo at the specified commit. We can reset at three different modes corresponding to the three trees.

We normally use the git reset and the git checkout to undo local or private changes. They both modify the history of a repository and can lead to conflicts when pushing to the remote public or shared repositories.

Git Reset vs. Git Revert vs. Git Checkout

The table below gives some common use cases for the three commands.

Command Scope Common Use Cases
git reset Commit level Delete commits in a branch locally or discard uncommitted changes.
git reset File level Unstage a file from the index.
git checkout Commit level Inspect old commits and switch between branches.
git checkout File level Throw away changes in the working directory.
git revert Commit level Reverse the effects of a commit in public branches.
git revert File level (N/A)

Commit Level Operations

We pass parameters to the git reset and git checkout commands to invoke different levels of operation. If we fail to include a file parameter, the commands act on the commit as a whole.

Reset a Commit

Resetting on the commit level will move the HEAD ref to a specified commit. We can use this command to delete commits from a branch.

Here is an example.

$ git reset HEAD~3

The command above will move the tip of our branch backward by three commits. We can refer to them as dangling or orphaned commits.

We have discarded the three commits. It is best to use the command to do away with commits that we have not published to a remote shared repository.

We can also use the git reset command to change the staged snapshot and working directory by passing one of the following flags.

  1. --soft - Does not change the staged changes or the working directory.
  2. --mixed - Does not affect the working directory but alters the staged snapshot to match the specified commit.
  3. --hard - Alters both the working directory and staged snapshot to match the specified commit.

Checkout Old Commits

We can use the git checkout command to inspect a repository’s state at a specified commit. We can also pass branch names to switch between branches.

Here is an example.

$ git checkout feature

The command above will switch to the feature branch. It will not move branches around.

We can also inspect arbitrary commits by passing a commit hash or reference instead of a branch name. Here is an example.

$ git checkout HEAD~1

The command above will check out the parent of our current commit. Passing HEAD~2 will check out the grandparent.

The command above will switch us into the detached HEAD mode because our current HEAD does not have a branch reference.

All changes and commits done in detached HEAD mode will not be reachable once you switch to another branch. Always create a new branch when you want to commit changes while in the detached HEAD state.

Revert Shared Commits

When we revert commits, we create a new commit that reverses the effects of the specified commit. This way, we avoid re-writing the commit history of shared repositories.

For example, if we want to revert the most recent commit, we will run:

$ git revert HEAD

File Level Operations

The git checkout and the git reset commands accept a file path as an optional parameter. The effects of the commands are limited to a single file.

Reset a File

We can update the staged snapshot of a file to match the version of the specified commit, as shown below.

$ git reset HEAD~1 README.md

The command above will fetch the version of the README.md file in the parent commit of the current commit and add it to the index for the next commit. We can run git reset HEAD README.md to unstage the README.md file.

Git Checkout File

Passing a file path to the git checkout command updates the working directory rather than the staged snapshot. This will not move the HEAD pointer between branches.

Here is an example.

$ git checkout HEAD~1 README.md

This will fetch the version of the README.md file from the parent commit of our current commit and update the README.md file in our working directory only. It simply means we have reverted to the file version in the old commit.

Unlike the git revert command that reverses the changes introduced by the specified commit, this discards all subsequent changes. We can use it to discard unstaged changes to a single file, as shown below.

$ git checkout HEAD README.md

In conclusion, we can easily differentiate between the git reset, git revert, and the git checkout commands by understanding the effects of each command on the commit history, staged snapshot, and the working directory.

Author: John Wachira
John Wachira avatar John Wachira avatar

John is a Git and PowerShell geek. He uses his expertise in the version control system to help businesses manage their source code. According to him, Shell scripting is the number one choice for automating the management of systems.

LinkedIn

Related Article - Git Revert

  • Git Revert Commit Local
  • Revert a Git Repository to a Previous Commit
  • Restore a Reverted Git Commit
  • Delete Local Commits in Git
  • Revert Merge Commit in Git
  • Related Article - Git Reset

  • Make the Development Branch Identical to the Master Branch
  • Various Methods Used to Remove Local Git Changes
  • Revert a Git Merge With Conflicts
  • Difference Between Git RM --Cached and Git Reset File
  • Revert a Git Repository by Commit ID