Merging two protected branches in gitlab after squashing commits

62 Views Asked by At

So the situation is this: we have two protected branches in gitlab "develop", and "test" (over which we dont have permissions to push onto without merge requests), we merged the develop branch to test, deciding to squash the commits as we had to use 100+ commits to do something trivial due to architectural constraints, now after trying to once again merge from develop to test we end up with merge conflicts, of course as i am not very experienced in git and even less my understanding of it's mechanics, i researched about this in git documentation and it is pointed out that squashing commits between two long running branches is not recommended as it inevitably will cause these issues. What i am trying to figure out is, what is the cleanest way to go about:

  1. Solving the current merge conflicts
  2. Appease the branches so that in the future we'd be able to merge directly from develop to test and NOT from a branch of develop without running into merge conflicts as that goes against the policy we're given
  3. (Possibly) avoiding bloating the test branch commit history with all the junk from develop

The approach i was currently thinking of was making a separate branch from develop, opening a MR to "test" with it and solving the conflicts from there, then push that onto develop and then try to merge from develop to test, which however i am not sure would fix it, and also bring some of the "test" commits in the "develop" branch history. Is there a better course of action that will make less of a mess without having to contact repository administrators?

1

There are 1 best solutions below

5
eftshift0 On

Ok.... you will first need to make git understand what you did in the first merge, then you could try the second merge and then finally you could post that as a PR to be merged into the test branch.... so, first, hunt down the last commit from develop that was merged into test in the first merge. Let's call this commit X. Also, identify the first merge commit in test and let's call it M1.

So, we will create a new merge commit out of thin air that will be what you should have kept in test when you did the first time you merged.... so, something like:

git commit-tree -p M1^ -p X -m "what the merge should have been" M1^{tree}

That command will print a commit id. Let's call this commit realM1. Check that its history looks ok (it should have as parents the 2 commits of test and develop that were originally merged. And if you diff realM1 with M1, there should be no differences:

git diff realM1..M1

If everything looks good, let's check it out and start working from it

git checkout realM1
git merge -m "Merging what we have in test" test

This should not give much trouble. If you get conflicts, then use the tip of test as the source of truth, no need to redo any work:

git restore --worktree --staged --source test -- .
git merge --continue

Now is where the real work begins. We will try the second merge of develop into this new fake history of test.

git merge -m "Second merge of develop into test` develop

You should not see any conflicts that were taken care of in the first merge... it should only be fair and square conflicts related to the second merge. Work on that as usual till you have a final merge commit... which is what you would like to see in the history of test having both merges of develop in there the way they should have been from the beginning. You could setup a branch over here and push it into a PR... that should be fine.... but the history might be a little messy..... if you would like to see something cleaner, then you can continue like this:

Let's call the result of that second merge realM2. Now, let's create another commit that only has test and develop as parents, using what we have in realM2 as its content:

git commit-tree -p test -p develop -m "The real 2nd merge of test and develop" realM2^{tree}

Again, we get a commit ID as the output. Set up a branch on it and push it and create a PR to merge into test. The history will still be a little messy, but not as much as the previous one.

That should work with the minimum effort possible and getting your 2 branch merged for real without redoing work.

Warning: there is the general assumption that test and develop are not moving while you are doing this work.