There is a keyword that many people search for, which is "delete a pushed commit". Coincidentally, I previously wrote an article titled I just accidentally committed wrong, how to fix it immediately?. This article ranked high in search results on Google, but the noteworthy thing is that the content does not mention how to solve the problem that people are facing, but simply guides you to delete a "not yet" pushed commit.
Therefore, to avoid confusion, and to help readers have a more accurate solution to this issue, today let’s explore how to delete a pushed commit!
During my working time, I often hear many people say that git is quite "easy" to learn, or confidently "show off" their proficiency in using git. Honestly, for me, git is something very difficult, and I can only use it at an intermediate level. That is, I know how to use basic commands like init
, clone
, pull
, push
, branch
, and a few other commands when working in a team. In reality, git provides many commands along with many options, still push
but with many options that I have never used because I don't know their purposes. Not to mention githooks - an advanced feature in git. Many advanced commands in git are ones that I didn't even know existed, very difficult to understand, and likely suited for large and complex projects. Each person, team, and organization has its own workflow with git, which contributes to the diversity in the way git is used.
Back to the issue, let’s temporarily forget those complexities. Essentially, once you have pushed
a commit to the remote, the ability to delete that commit is quite risky. Without knowing the purpose of deletion: Is it to delete a meaningless commit? Is it to delete a wrong commit to make the git tree look nicer? Or is it simply a whim to delete!? It seems simple but turns out to be very complicated.
Imagine that git was created for collaborative, distributed workflows. Each commit that is pushed
serves as a commitment to code changes. If someone has pulled
your commit and they continue to write more code and push it up, if you could delete any commit, wouldn’t it cause a tremendous chaos in the code? That line of code has existed in subsequent commits, and if someone has modified the code you want to delete, then wouldn’t we have to go through a rebase
process from the point of deletion? It’s truly a nightmare.
At this point, you should abandon any hope of deleting any pushed commit, as git does not encourage doing so. However, if you want to delete the last few commits, it can still be done with minimal risk.
You might see a "golden period" to delete the last commits without affecting anyone, which is after you have pushed
but no one has pulled
it yet. Thus, we can fully use the --force
flag to push all the commits from local to remote. Of course, the --force
flag is always something that is very risky and should not be abused. Most programs that provide a force flag warn you to be sure you know what you are doing. If not, never use it. In summary, there are three scenarios for deleting commits using the --force
flag.
A shared branch refers to a branch that many people participate in developing, such as the develop branch, where everyone continuously commits or merges code.
Suppose the remote develop branch has the last commit that you want to delete; great, take advantage of the time when no one has pulled it and no one has pushed anything new to force push.
# Go back to the previous commit
$ git reset HEAD~1
# Force push all commits from local
$ git push --force
That’s it, now your git tree has returned to how it was before the last commit.
In the case where the last commit is no longer yours, at this point, it is certain that someone has already pulled
your commit, and if you force push at this moment, it will cause a tremendous chaos in the code, easily resulting in the loss of all commits following the commit you want to delete.
The feature branch you are developing has not been merged into develop, and there is a wrong last commit that you want to delete from git; therefore, you can freely use force push to push the code back. Since the branch only contains your commits, there is no chance that anyone will pull the code and push new code up. The process is similar to the above.
# Go back to the previous commit
$ git reset HEAD~1
# Force push back all previous commits
$ git push --force
Use rebase -i
to edit the number of recent commits. For example, the commit you want to delete is in the 10th position.
$ git rebase -i HEAD~10
pick abc123 Commit 1
pick def456 Commit 2
...
pick ghi789 Commit 10
Change pick
at Commit 10 to drop
and save. If you are lucky, you won't have to resolve any conflicts because the deleted commit has no related code to the previous 9 commits. If not, the worst-case scenario is that you need to resolve 9 conflicts that occur in the remaining 9 commits one by one. That’s a nightmare!
Finally, if the commit has been deleted and conflicts have been resolved, you will still need --force
to push all changes to the remote, not forgetting to pray that your colleagues haven’t done anything on that branch.
In git, if you use --force
to push
, it replaces all your local commits to the remote. So, commits from others after the time you force push will "disappear without a trace". Therefore, one golden rule here is: Only force push on a personal development branch; for shared branches, you should not use force. If you still decide to use it, gather everyone and discuss it with them.
Not to mention, many teams have workflows using Protected Branches, which means creating rules to protect the branch, defining who has the rights to pull
, push
, or merge
... Assuming you don’t have the rights, it means there’s no way to force push; the best solution is to explain to your manager.
So far, we have been talking about force, force, force, which sounds burdensome. So, besides that, is there any other way to delete a commit? As far as I know, there is no other way. Commits that are still local can be deleted as mentioned in the article I just accidentally committed wrong, how to fix it immediately?, but once it has been pushed, the only way to delete is to force it, and if you do force, be cautious of the potential loss of others' commits.
If you don’t want to use the force flag but still want to cancel the last commit, try reverting
the last commit. The revert
command creates a new commit with changes that aim to restore what was changed in the previous commit. Everything will return to normal, only you cannot delete that commit.
$ git revert HEAD
$ git push
Finally, this article is for reference only and does not encourage readers to apply it in practice. Be ready to take responsibility for what you are about to do. Remember, only use --force
when you are sure about what it does.
Git was created to solve collaborative, distributed work issues. Each commit in git is like a commitment and is very difficult to delete once it has been pushed to remote. However, you can try using the --force
flag to delete the last commit or a safer solution is to revert the commit.
5 profound lessons
Every product comes with stories. The success of others is an inspiration for many to follow. 5 lessons learned have changed me forever. How about you? Click now!
Subscribe to receive new article notifications
Comments (0)