0

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!

TTT
  • 22,611
  • 8
  • 63
  • 69
Viktor
  • 1,325
  • 2
  • 19
  • 41
  • 1
    You cannot re-merge a reverted merge, because what you reverted was the _code_, not the merge topology. See, always see, the classic https://github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt – matt Apr 19 '22 at 13:09
  • Hmm, so in this case release_2 branch cannot be fixed? I mean that I cannot merge the code of release_1 to release_2? The only option is to create a patch file with the changes? I hoped there was a solution as the problem above doesn't seem to be an extra special one. – Viktor Apr 19 '22 at 13:45

1 Answers1

1

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:

  1. There hasn't been much activity on release_2 since the undesirable merge of release_3.
  2. Whatever new commits that you need to keep on release_2 could be re-written without causing issues.
  3. It would be pretty straight forward to communicate to the team that you're resetting release_2 and you could provide the appropriate git 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.

TTT
  • 22,611
  • 8
  • 63
  • 69
  • Thanks for the explanation, it makes sense! At least I have two options (reset & cherry-picking), will think which one would be the best option for me. – Viktor Apr 20 '22 at 07:50
  • @Viktor Note there is a minor difference between cherry-picking the one big squashed commit, and merging in that one commit as I suggested. Functionally the end result should be equivalent, but if you later ever wanted to look back and confirm that the squashed commit was identical to `release_1`, it would be easier with the merge compared to a cherry-pick, since with merge you'll have two commit IDs in your history which you can compare that should be identical. (With cherry-pick you won't have that.) This is possibly more important If there are any conflicts with that merge or cherry-pick. – TTT Apr 20 '22 at 14:14