I have different release branches, let's say
- release_0 (release last year)
- release_1 (release this year)
- release_2 (in development)
- release_3 (in development)
release_2 branch was created a long time ago so it only contains release_0. release_3 branch was created from release_1.
I had the impression that release_2 should have the code of release_3 so I merged release_3 to release_2.
I was told later that release_2 will go live before release_3 so I reverted the merge commit from release_2 (and pushed the revert commit).
However as release_1 is already on production so I tried to merge the changes of release_1 to release_2 (release_2 is based on release_0). Unfortunately git says that 'Already up to date.'. It is because I merged release_3 to release_2 (which was reverted though) and release_3 already contains release_1.
What can I do in this situation? I read the https://stackoverflow.com/a/15737656/1269572 but it doesn't seem to be a solution as I need to remove the release_3 code from release_2.
Thank you!
CodePudding user response:
Essentially you are trying to put release_2
into a state that is equivalent to reverting part of the merge of release_3
into it. (So reverting the revert won't work.) This is unfortunately going to be messy unless you go with a clean hard reset of release_2
to before that merge. I'd consider the hard reset if the following conditions are true:
- There hasn't been much activity on
release_2
since the undesirable merge ofrelease_3
. - Whatever new commits that you need to keep on
release_2
could be re-written without causing issues. - It would be pretty straight forward to communicate to the team that you're resetting
release_2
and you could provide the appropriategit rebase --onto
command to any developer that has a branch in progress based off of it.
If you can't do the reset, then probably the simplest thing to do would be to make a new commit which represents all the changes on release_1
that aren't in release_2
yet and merge it in. (A patch would work too.) Something like this:
# On release_2, identify the commit before the merge; let's call it CBM
# Make a temp branch pointing to release_1
git switch -c release_1-contents origin/release_1 --no-track
# Reset soft to point to the merge-base of this branch and CBM
git reset --soft $(git merge-base HEAD CBM)
git commit -m "Squash contents of Release_1 content"
# now merge it into release_2
git switch release_2
git merge release_1-contents # use the commit message to explain what and why
Side Note: when trying to bring in commits again after a revert, the thing that matters is their commit ID; if you change them you can bring them in again. If there aren't too many commits on release_1
and you don't mind having duplicate commits in the repo forever, you could re-write them via cherry-picking a range or using rebase -f
on release_1
to simply re-write the commit IDs, and then you can merge them in again. If there are many commits though I'd probably lean towards making a single squashed commit instead, as described above.