Solution for How to revert to several older commits including merge but have one commit on top of the head of reverted commit? [closed]
is Given Below:
I have a list of commits like this:
Author: xyz Date: Fri Jul 30 11:48:40 2021 -0700 update tests commit 76810c2bdf91cd84661fabb06f00f37fc0e6b264 Author: abc Date: Thu Jul 29 16:38:33 2021 -0700 fix for issue commit b9a1642c3d778524291c98895425aa0248ed5766 Merge: baeb6428 6b722171 Author: abc Date: Thu Jul 29 16:36:58 2021 -0700 Merge branch commit 6b722171718f7aa70236613c544d8ca9f6cdeea9 Author: abc Date: Thu Jul 29 17:15:02 2021 +0000 Use new type commit baeb642886c19135c6057fba94849768b5ffc5a3 Author: abc Date: Wed Jul 28 16:24:10 2021 -0700 old commit
I want to go back to old commit but have one commit
76810c2bdf91cd84661fabb06f00f37fc0e6b264 included. How should I do that?
git revert <hash> for each one of the commits manually and
git revert -m 1 <merge hash> for merge commits but it is not working as expected. Also, I have a long list of reverts to do and it is a tedious task to do it manually. Is there a simpler way to do this?
This scenario sometimes happens in our team on release/integration branches, where the release of certain features is to be aborted/canceled but those have been already committed or merged on the release/integration branch.
From your comment:
I want A <- B <- C <- D to be like B <- D
Instead of trying to find a solution with
git revert, we’d rather do:
- Create a new branch on D
- See How do I create a new Git branch from an old commit?
- If B is a single or small set of commits, just
Following the hashes on your example, it would be:
# git checkout -b <new-branch-name> <old commit> $ git checkout -b new-branch baeb642886c19135c6057fba94849768b5ffc5a3 # git cherry-pick <specific commit> $ git cherry-pick 76810c2bdf91cd84661fabb06f00f37fc0e6b264 # make new branch available to rest of team $ git push -u origin new-branch
Now we have new-branch which is based on old commit + that one commit on top of it. There might be conflicts on
cherry-pick if the commit you are cherry-picking depends on changes from C which isn’t included here anymore.
D -> C -> B -> A [old-branch] -> B [new-branch]
Note that nothing’s really reverted here, as the old-branch with the commits you don’t want anymore is still there. But at least here, people’s local copies have fewer chances of getting messed up since they simply need to checkout this new-branch. (We usually keep old-branch for a while as a reference, because sometimes people change their minds…).
To complete a revert operation, we can then simply delete old-branch which deletes all those commits you didn’t include anymore in new-branch. This has the same destructive effect as
git revert, so take care that you really don’t need any of those commits anymore, especially merged branches (you might want to re-create those branches).