Version control systems such as Git allow developers to track changes, collaborate seamlessly and manage projects efficiently. However, even the most careful developers can occasionally make mistakes such as pushing code to a remote repository prematurely. This could be because you pushed to the wrong branch, the code is not ready for deployment, or sensitive information was accidentally pushed to a public repository.
Using Git reset
If you need to make sure that the changes introduced by the pushed commits are no longer a part of the repository, then you can use the git reset command to undo a git push.
For this, you need to find the commit hash to which you want to reset your branch. This can be done using the git log command to view your commit history and identify the desired commit hash. You then need to perform a git reset to move the branch pointer to the desired commit:
$ git reset --soft <commit-hash>
Run in Warp
Using the --soft flag will ensure that the changes in the commits will remain as part of the working directory and will be staged to be committed. If however, you want to completely remove the changes introduced then you can use the --hard flag which will remove all changes from the working directory.
Once you have performed the reset you will then need to push the new history back to the remote repository. This can be done using the --force flag:
$ git push --force
Run in Warp
This will push the current branch to the remote repository and overwrite the remote history to remove the undesired commits.
It is important to note that by doing this you are overwriting the history of the remote repository. You need to make sure that no other developers are using the changes that you are overwriting as otherwise, this can cause conflicts and headaches for your team.
Easily retrieve this command using Warp’s AI Command Search
If you’re using Warp as your terminal, you can easily retrieve this command using the Warp AI Command Search feature:
Entering git push force into the AI command search will prompt a git command that can then be quickly inserted into your shell by doing CMD+ENTER.
Using Git push force
Alternatively, if you don’t want to change your local repository but rather only want to overwrite the changes to the remote repository then you can simply overwrite the remote history. This can be done using:
$ git push --force origin <last_known_good_commit>:<branch_name>
Run in Warp
This will overwrite the history of the remote repository with the last known good commit (identified by using git log) from the specified branch name. The benefit of this is that it does not involve changing your local repository to undo the git push that was performed.
With this, just like the git reset, you need to be careful that no other users of the repository are fetching the incorrect changes or trying to build on top of the commits that you are wanting to remove. This is because with this commit you are rewinding history which can lead to conflicts if other developers already have the changes checked into their local repositories.
Using Git revert
A less dangerous method for undoing a git push is using the git revert command. This is because git revert will revert the changes introduced by a specific commit by creating a new opposite commit. This ensures that the history of the remote repository is preserved and will make it easier if other developers have already checked out the changes made in the remote repository.
You need to first identify the commit that you want to undo using git log. Once you have identified this commit then you can run the command:
$ git revert <commit_hash>
Run in Warp
This will create a new commit that will undo the changes in the commit hash specified. To then undo the original git push, you can simply perform git push again to add the new commit that undoes the undesired commit.
This is beneficial when other developers have already checked out the change and when the push that you want to undo does not contain any secrets. This is because the commits in the first git push will still remain a part of the history of the repository and so will still be visible to others.
Undoing a Git push force
Generally you don’t want to use the -f or --force option unless you really mean to overwrite the history of the remote repository. This can often make it hard to recover any changes you make, especially if you have used git reset --hard to reset the branch before the forced push.
The ability to recover from a forced push depends on the operations done before performing the push and whether Git has done any cleanup since. However, you can usually use the git reflog to identify the state of the branch before performing the forced push. In this case, you can often simply reset the branch to the state before the push as:
$ git reset --hard origin/<branch_name>@{1}
Run in Warp
You need to make sure that this is the desired commit and you may need to use the git reflog again to find the desired commit and reset --hard to that one. You can then push the branch back to the remote server using:
$ git push -f origin <branch_name>
Run in Warp
Which will again overwrite the remote history but with the branch before if was force pushed originally.
Preventing future mistakes
Undoing a git push is a valuable skill but prevention is even better. Here are some strategies to minimize the chances of making such a mistake in the future:
Using a feature branch
You can develop new features and bug fixes on separate feature branches. This reduces the risk of pushing incomplete or untested code to the main branch. You should push any changes to the feature branch first and once you are okay with the changes then you can merge them back into the main branch.
Code Reviews
You should implement code review processes to catch mistakes before they are pushed. A second pair of eyes can often identify issues that may have been overlooked. This stage happens before the changes are merged into the main branch to ensure that only the correct code is merged in correctly.
Git Hooks
You can set up pre-push and pre-commit hooks to enforce checks before a code is pushed or merged into the main branch. These hooks can run tests, linting and other validation processes to ensure that the code does not introduce any breaking changes.
Git Stash
If you are uncertain about a push or part of a push, you can use git stash to temporarily save your changes without making a commit. This allows you to revert back to a clean state if needed.
Written by
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.
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.
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.
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.
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.
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.
Undo a Git Rebase
This post will show you how to undo a rebase using git reset, git rebase and git revert
Git Push Origin
A breakdown of git push origin
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 Push Tags
This post will show you how to push a single tag, multiple tags, all tags, and tags with commits.
Undoing Git Commits
Explore ways to undo a commit, including git reset, git checkout, and git revert with git while preserving commit history.
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.