1

We have two branches: master and dev. Our ci deploys to production upon a merge into master.

Now, we do our development in dev and intend to merge to master when we wish to deploy. We do not do development in master.

When we open pull requests to master from dev we are greetings with 'conflicts'. These conflicts are a list of the changes we made in dev. Resolving these conflicts means going through them manually and selecting the changes from dev in each case.

Why is the merge considering these conflicts? No changes were made to these files in master between merge events. Why isn't automerge just applying all the changes we made in dev to master instead of flagging them?

melchoir55
  • 6,842
  • 7
  • 60
  • 106
  • We'd need more information to help. Can you show `git log --oneline --graph --decorate master..dev` which will show the relevant history. – Schwern Jan 24 '21 at 20:54
  • I have added the output of that above – melchoir55 Jan 24 '21 at 21:05
  • Is dev in `git branch --contains master`? If so that should be a simple merge. If not, you have done development in master. Otherwise, check you have the right base and target for the PR. "melchoir wants to merge 37 commits into master from dev". – Schwern Jan 24 '21 at 21:11
  • 3
    Are you using squash merges or regular merges? – bk2204 Jan 24 '21 at 21:14
  • @Schwern the only item in the list from `git branch --contains master` is `*master` @bk2204 squash merges – melchoir55 Jan 24 '21 at 21:15
  • 1
    @melchoir55 Then master and dev have "diverged". There have been changes to master since dev was branched. dev is no longer sitting on top of master. `git log --oneline --graph --decorate dev..master` will tell you what's in master which is not in dev. And if you squash merge, all bets are off. – Schwern Jan 24 '21 at 21:18
  • To put it another way: A "squash merge" is _not a merge_. It's really bad that it every got the word "merge" in its name. – matt Jan 24 '21 at 22:10

1 Answers1

3

You shouldn't use squash merges to merge two long-lived branches. Always use a merge commit.

The Git FAQ explains why using squash merges in this case is a problem:

When Git does a normal merge between two branches, it considers exactly three points: the two branches and a third commit, called the merge base, which is usually the common ancestor of the commits. The result of the merge is the sum of the changes between the merge base and each head. When you merge two branches with a regular merge commit, this results in a new commit which will end up as a merge base when they’re merged again, because there is now a new common ancestor. Git doesn’t have to consider changes that occurred before the merge base, so you don’t have to re-resolve any conflicts you resolved before.

When you perform a squash merge, a merge commit isn’t created; instead, the changes from one side are applied as a regular commit to the other side. This means that the merge base for these branches won’t have changed, and so when Git goes to perform its next merge, it considers all of the changes that it considered the last time plus the new changes. That means any conflicts may need to be re-resolved.

There is no way to do this with squash merges that avoids this problem.

bk2204
  • 64,793
  • 6
  • 84
  • 100
  • This is illuminating. Is there a way out of my problem? If I manually resolve these conflicts in a new pr and do a normal merge (not squash) will I live a normal life going forward? – melchoir55 Jan 24 '21 at 21:21
  • 1
    Yes, if you manually resolve the conflicts and do a normal merge, things should be much better in the future. – bk2204 Jan 24 '21 at 21:24