The only way I know is to revert the revert. Or to reapply the original change. [1] In the case of merge commits that is.
Because reverted merges have to be treated with some care.
With this:
git revert --mainline 1 <faulty> ... git revert <revert>
You will end up with this (top is most recent):
- d68cbf7a7d0 Reapply "Merge branch 'tb/multi-pack-reuse-dupfix' into next"
- ...
- f04a3d85c83 Revert "Merge branch 'tb/multi-pack-reuse-dupfix' into next"
You can then point to the original merge commit in the reapply/revert-of-revert commit message:
Reapply "Merge branch 'tb/multi-pack-reuse-dupfix' into next" The dust has settled. Reapplies: 32792297e5 (Merge branch 'tb/multi-pack-reuse-dupfix' into next, 2024-11-16)
Not using revert
I use reverts for small screwups. Little obvious (I think) mistakes which, when removed, will make the otherwise obviously correct enough snapshot correct again.
But you don’t need to revert or make any other oh-whoops commits: you can instead deploy a previous commit.
Given this history (top is most recent):
- (empty slot)
- Good commit (deployed)
- Good commit
- Bad commit
- Good commit
- Good and well-tested commit
You deployed (2) but found out that (4) was fishy. So you make the revert:
- Revert (4) (deployed)
- Good commit
- Good commit
- Bad commit
- Good commit
- Good and well-tested commit
Now you have the problem of potentially reverting a large (100 commits! e.g.) merge commit. Which might just be reapplied again right after since you want to fix the problem more surgically. Okay but let’s assume that the revert causes no merge conflicts. Then you just have massive version control churn.
But there is another problem. Is (1) a well-tested commit? No it isn’t. The snapshot of (1) might be completely untested. Yeah (4) had some bad stuff in it. But it might have been what held (3) and (2) together—that hasn’t been tested.
The only good and well-tested commit here is (6). You can deploy that:
- (empty slot)
- Good commit
- Good commit
- Bad commit
- Good commit
- Good and well-tested commit (deployed)
There’s nothing stopping you. Either tag that or just use the hash—a SHA-1 hash is going to identify your deployment uniquely just fine.
Caveats to deploying previous snapshots: stateful changes
You can’t deploy a previous version if you did stateful changes to the application in one of the intervening commits. For example:
- Revert (4)
- Good commit—deployed
- Good commit & DB updates
- Bad commit
- Good commit
- Good and well-tested commit (deployed)
(3) here throws a wrench in things. Maybe you changed some DB tables. The application is going to get confused if you reset to a previous version.
Notes
- According to Git:
- Revert-of-revert = reapply
git replace --grafttemporarily to let Git think it has never merged the branch.