• Modern UX

    Edit and navigate faster in the terminal with Warp's IDE-like input editor.

  • Warp AI

    AI suggests what commands to run and learns from your documentation.

  • Agent Mode

    Delegate tasks to AI and use natural language on the command line.

  • Warp Drive

    Save and share interactive notebooks, workflows, and environment variables.

  • All Features

Undoing Git Commits

Thumbnail for Philip WilkinsonPhilip Wilkinson

Philip Wilkinson

Software Engineer, Amazon

Published: 11/30/2023

About Terminus

Undoing commits in git is a common task that developers perform when they want to undo changes that they have made to a repository. Whether you made a mistake in a commit or want to go back to a previous version of the code, git provides you several ways to undo a commit. 

Using git reset to undo a commit

Using git reset is the most common way to undo changes that have been made to a repository. Resetting is a way of moving the current tip of a branch to a previous commit and thus resetting it to a previous state. This can be done to remove commits from the current branch that are no longer needed, or to undo changes that have already been made.

To use git reset, you need to specify the mode and the commit you want to reset the branch to. This takes the form:

 $ git reset <mode> <commit>

Run in Warp

For <mode> there are three flag options:

  • --soft will reset back to the specified commit, but the changes made in the subsequent commits will remain as part of the working directory and will be staged to be committed.
  • --mixed is the default flag which is used when no other flag is specified. With this, while the working directory is not changed, meaning that no files are changed, none of these changes are staged to be committed. This means that if you run git status you will see all the files that were changed are in red, waiting to be committed.
  • --hard flag will change both the staged snapshot and the working directory to remove all the changes beyond the commit specified. This means that the changes made in subsequent commits will act like the other commits never existed.

And <commit> is then the specific commit you want to refer back to.

You can undo your last commit(s) using HEAD

For example:

 $ git reset --hard HEAD~2

Run in Warp

Which will reset the current branch back two commits and will remove all changes that had been made in the last two commits from the working repository. 

Save this git reset command for easy re-use later

Warp has a predefined Workflow available that Warp terminal users can call by pressing CTRL-SHIFT-R and starting to type “undo most recent git commit”. One of very many Warp Workflows, this is an easier way to remember the syntax for undoing the last commit while leaving the working tree (the state of the files on disk) untouched:

 $ git reset HEAD~

Run in Warp

A word of caution: be careful with using git reset. It will overwrite the commit history. While this isn’t a problem if you are undoing local changes, it can be difficult to untangle when the commits have already been pushed to a remote repository.

Using git checkout to undo a commit

Another way of undoing commits is to checkout a previous commit either for the whole repository or for a specific file. This is commonly used to checkout different branches of code but can also be used to checkout specific commits. 

To checkout a specific commit, you need to specify the hash of the commit you want to checkout. This can be done using the command:

 $ git checkout 

Run in Warp

For this, replace <commit_hash> with the hash of the commit you want to check out. When running this command, `git` will switch the repository to the state that it was in on the specified commit. 

The issue with this approach is that you will end up in a detached HEAD state. This means that you are not currently on any branch, so any changes you make will not be saved in a branch. If you want to make changes, you will need to create a new branch. This can be done using:

 $ git checkout -b 

Run in Warp

Where <branch_name> is the name of the new branch you want to create. From here you can start making new commits on this branch as usual.

Undoing changes to a specific file with git checkout

Alternatively, you can undo changes to a specific file by checking out that version of the file from a previous commit. The command for this is:

 $ git checkout  

Run in Warp

Which will reset the file to that state from the specific commit. It is important to note that this is a destructive operation since it permanently discards any changes made to the file after that commit.

Using git revert to undo a commit

Another approach that could also be used to “undo” commits is git revert. git revert works to undo a change by creating a new commit. This makes it a safe way for undoing changes in a public repository, as it does not change the history. An example:

 $ git revert 

Run in Warp

This will undo all the changes in the <commit_hash> commit and then will create a new commit with those changes undone. If there are no merge conflicts, an editor will open up asking you to name the new commit, and then it will be added to the end of the current head.

This approach preserves the commit history and potentially reduces the amount of merge conflicts that you may have to deal with compared to the use of either git reset or git checkout.

Tread carefully with undoing commits in remote repositories

While the methods above seem simple when it comes to undoing commits in a local repository, this can become an issue when undoing commits in a remote repository. If you are using a remote repository and collaborating with others, changing that history can affect the development path taken and can create merge conflicts. The effect of this depends on the method you use:

  • git reset overwrites commit history. This means that your history will be different to the remote repository. If other developers are using the commits you have undone, then this will cause conflicts. This is why `git reset` is generally not recommended for use with a remote repository unless you are working on your own development branch.
  • git checkout can also overwrite commit history when you checkout a previous commit for the full repository. To resolve this issue, you will need to create a new branch and then resolve the merge conflicts when merging back into the main branch.
  • git revert is the safest way of undoing commits as it does not overwrite the commit history. Instead it creates a new commit that undoes the changes introduced in a previous commit while retaining the history of the origin commit. Other contributors will be able to see the commit was reverted and adjust their work accordingly.

If you decide to use git reset or git checkout to overwrite commits, then you can use git push --force to overwrite the remote branch with your local branch. This will overwrite any commits that were made after your last pull. This can create problems if other contributors have made changes that conflict with those that you are pushing, so you need to make sure you communicate clearly with others and coordinate your changes carefully.

How do I decide which approach to use?

If you don’t care about commit history, you should use git reset. If you don’t care about keeping the same branch, then you can use git checkout. If you care about history and the branch structure, then you can use git revert.

Written by

Thumbnail for Philip WilkinsonPhilip Wilkinson

Philip Wilkinson

Software Engineer, Amazon

Filed Under

Related Articles

Undo A Git Pull

How to effectively remove the commits introduced by a pull in Git using git-reset and preserve your local changes using git-stash. Also, how to cancel an unmerged pull request on GitHub.

Git
Thumbnail for Glory KimGlory Kim

Undo a Git Merge

How to rollback the changes introduced by a merge in Git by adding new opposite commits using git-revert and effectively removing commits using git-reset.

Git
Thumbnail for Philip WilkinsonPhilip Wilkinson

Prompt Show Git Branch In Prompt

Enhance your terminal with a custom Git prompt. Learn different ways to integrate this contextual info, from custom shell functions to Warp context chips and toolkits like Starship and P10K.

Git
Thumbnail for Gabriel ManricksGabriel Manricks

How To Remove Secrets From The Git History Remove Secrets From The Git History

Learn how to remove secrets from the Git history using the BFG and git-filter-repo command-line tools.

Git
Thumbnail for Utsav PoudelUtsav Poudel

Adding a Submodule in Git

This post will show you how to simply add a submodule to a local repository, clone a repository with a submodule, and work within a repository that has a submodule.

Git
Thumbnail for Philip WilkinsonPhilip Wilkinson

Undo a git push

This post will show you had to simply undo a git push three different ways.

Git
Thumbnail for Philip WilkinsonPhilip Wilkinson

Undo Git Add

Learn how to effectively use 'git add' to stage files in Git for committing, and discover two powerful methods to undo accidental stagings.

Git
Thumbnail for Glory KimGlory Kim

Undo a Git Rebase

This post will show you how to undo a rebase using git reset, git rebase and git revert

Git
Thumbnail for Philip WilkinsonPhilip Wilkinson

Git Push Origin

A breakdown of git push origin

Git
Thumbnail for Amanda KhooAmanda Khoo

Create Folder In GitHub Repository

Learn how to create and push one or more empty directories in a Git repository using `.placeholder` and `README.md` files using both the CLI and the GitHub interface.

Git
Thumbnail for Razvan LudosanuRazvan Ludosanu

Git Push Tags

This post will show you how to push a single tag, multiple tags, all tags, and tags with commits.

Git
Thumbnail for Philip WilkinsonPhilip Wilkinson

Delete Local Git Branch

Learn how to delete local branches from your git repository, including ones with unmerged changes, as well as local remote-tracking branches.

Git
Thumbnail for Philip WilkinsonPhilip Wilkinson

Trusted by hundreds of thousands of professional developers

Download Warp to get started

Download for Mac
Thumbnail for null