DEV Community

Cover image for Implementing effortless rollbacks in Git
Axel Navarro for Cloud(x);

Posted on

Implementing effortless rollbacks in Git

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

The developer is sad because he received an

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)
Enter fullscreen mode Exit fullscreen mode

Let's use git rebase to recreate this commit of the topic branch:

git checkout mytopic-branch
git rebase --force-rebase HEAD~1
Enter fullscreen mode Exit fullscreen mode

Now, let's do the merge again!

git checkout staging
git merge mytopic-branch
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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)