In this series we've learned how to merge or split commits using the git rebase
command, now it's time to learn how to make rollbacks using the git revert
understanding how this works and how to rollback a revert and when this can be useful. 🪄
The commit ID
The commit ID (SHA) is used by Git to identify a commit, and it can be regenerated using git rebase --force-rebase
.
git rebase --force-rebase HEAD~1
By default, the rebase makes a fast-forward when it's possible 🤔. This means that the commits aren't re-created when they're being applied over the same previous commit, keeping the commit ID unchanged.
This also happens with you use git cherry-pick
, this command applies changes changing the parent commit and that means a new commit ID is used for these picked changes.
When is a new commit ID useful? This may be useful in those sad days when GitHub has issues detecting new commits in the repository and fails to trigger the GitHub Actions or the pull request is out of sync with the Git repo. 🌚
Also, this could be useful when you revert a failed merge and you need to remerge the same code now expecting to work properly 🤞 without reverting the reversion 😵💫. Let's explain this complex scenario a little more.
Making a rollback of a merge
For this example we merge a topic branch into a shared branch as always.
git checkout staging
git merge mytopic-branch
git push origin staging
But let's say you merged these changes too soon, or you need another topic to be merged into staging
first. Then you need to revert the merge.
git revert mytopic-branch
git push origin staging
And we've reverted to a Git merge effortlessly.
Remerging a reverted merge
After pushing more commits into staging
it's time to remerge your topic 🎉 again, then you get a Git output worse than a merge conflict. 🙀
$ git merge mytopic-branch
Already up to date.
Why are we getting Already up to date
if the merge of mytopic-branch
was reverted? Since Git is inspired by the patch-set workflow of open-source development, the mytopic-branch
's commits already exist in the staging
branch even if they have been reverted. You can still see the reverted commit in the log:
commit 68ab202e93cb059d01feaaae1cf7d988e2c470a1 (HEAD -> staging)
Author: Axel N <...@gmail.com>
Date: Wed Oct 16 19:09:13 2024 -0000
Revert "Upgrade to Rust v1.81 (#87)"
This reverts commit 0680aa76b96a29b3052482c2e38f817363ac88a8.
commit 0680aa76b96a29b3052482c2e38f817363ac88a8 (origin/staging)
Author: Axel N <...@gmail.com>
Date: Wed Oct 16 10:46:05 2024 -0000
Upgrade to Rust v1.81 (#87)
Let's use git rebase
to recreate this commit of the topic branch:
git checkout mytopic-branch
git rebase --force-rebase HEAD~1
Now, let's do the merge again!
git checkout staging
git merge mytopic-branch
And, it's done!
What if mytopic-branch
is a shared branch like development
and I can't rewrite its history? You could revert the reversion using this:
git checkout staging
git revert 68ab202 # SHA of the revert commit.
In this latest scenario we're undoing the reversion and you can get Git conflicts too. Just resolve it as always. You can choose any method to do this but if anyone is not too familiar with Git a revert of a revert could be too hard to understand by just checking the Git log. Try to keep the commit message clear enough about what happened and what commits you're reapplying.
Conclusion
We have learned how to rollback a merge and how to recreate commits when it's needed.
Always remember that the commit ID is used by Git for traceability, If you change the commit ID of a set of changes this is not the same commit for Git.
I hope you find this post useful. Let me know in the comments how you resolved the revert the reversion. 👇 See ya!
Top comments (0)