0

How can I solve conflicts with master in GitHub without bringing all ahead commits of master?

Scenario:

  1. I've created a branch A from master, which is a protected branch
  2. While I was working on the branch A, the master branch received many commits (up to hundreds modified files. Some of them are files that I'm also working on)
  3. I have a PR to merge my branch A onto master, but there are conflicts

How can I update my branch with these conflicting files with master to solve them, and only them?

I cannot solve this conflict directly on GitHub because GitHub doesn't allow me to do it, they're too complex to solve on web editor.

Solution attempt:

  1. If I merge the local master onto my branch A, then all master commits that were ahead of my branch A will appear on my branch A, therefore my pull request will have hundreds of modified files beyond what I've been working on. This is a problem because each file might have a different code owner, and they're already on master, there is no need for reviewing that again
  2. If I simply checkout the file that has conflict in my branch, for some reason GitHub keeps saying that the file has conflict, it does not recognize that I've solved the conflict
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
mateusvl
  • 131
  • 12
  • You probably want to rebase `A` atop `main`. But there will still be conflicts to resolve. The best practice here is to pull integration branches (main in this case) early and often so you aren't drifted too far. Unfortunately the scenario is unavoidable, but the smaller the differences, the easier it is to rectify. – erik258 Apr 07 '23 at 14:08
  • 1
    You can still retroactively merge intermediate commits from master into A to keep the conflicts manageable and repeat this until you have merged all of master. – mkrieger1 Apr 07 '23 at 14:14
  • I would merge `master` in piecemeal sizes so that merge resolution is manageable at each merge. The result is the desired final state. Tag it. Reset to before the first merge. Merge `master` again in one fell swoop. Resolve conflicts by using the result from the tagged commit (that's a no-brainer now). That state can you now post as pull request, because does not cause conflicts anymore. – j6t Apr 07 '23 at 14:49

2 Answers2

2

The premise of the question is false:

If I merge the local master onto my branch A, then all master commits that were ahead of my branch A will appear on my branch A

No, that's not true. The pull request won't include any of those. It's a diff with master, displaying all commits reachable from A but not from master; commits that are already present on master thus won't appear in the pull request for A after doing the reverse merge of master into A.

And this is indeed the best way to resolve the conflicts. Yes, it will take time, but you have just one "resolve these conflicts" situation to deal with. Rebasing could give you conflicts on every individual commit, which would drive you insane.

In short, reverse merge is the right way to resolve conflicts between a pull request branch and the branch it is to be merged into.

matt
  • 515,959
  • 87
  • 875
  • 1,141
1

Most frequent cases

When you merge master into your branch, then you do not review the changes performed on it. You will, instead have to solve the conflicts in the files where you have at least such a conflict and the other files will be trivially easy to merge. So, by default you should not worry about merging large diffs from master into your branch, that's quite normal and usual and you usually don't need to worry about the files you do not have a conflict at.

However, in reality there might be peculiar problems, because the changes at master obviously were done without taking your changes into account. For example, if there is an f(a) function at master and you have changed it to f(a,b), then you might end up having issues if at master new calls are added to f(a), in which case the two branches are incompatible.

So, this is how you need to proceed:

  • git checkout master
  • git pull
  • git checkout yourbranch
  • git merge master
  • if there are conflicts then
    • look at each conflict and solve it to the best of your abilities
    • commit your merge
    • if you have code validation of any kind, including build processes, then try doing it and fix any issues you may find
    • search for all relevant parts in the code that interact with yours and make sure, preferably including, but not limited to testing that besides your new features, the old features that were not changed by you are also working
    • if you have unsureties/questions, make sure that you clarify them in your pull request and/or notify those who need to be notified about it

The merge is broken, you have trouble and you do not see any reliable way to get through it

In this case you could run

git log

while you are on master and divide your large merge problem into chunks, by creating a list of commit hashes for yourself (possibly every 5th commit hash, but it's up to you) and then do

git merge <commit hash1>

fix merge conflicts, perform the tests and proceed to your next hash until you either successfully complete your process, or find what specifically caused your problem. If you know what caused your problem, then you can fix the issue and see whether the consequent merges are going in an easier manner.

If the process above still fails and you lack knowledge/information about the others' works, then you can list only the commits that affected the files you are interested about, list those commits and then do the following for each of them and handle them.

git cherry-pick <some commit hash>

How to avoid issues for the future

Make sure that you do not create mammoth commits, that is, your commits are atomic: each of them are responsible for a very specific atomic change.

Make sure that you regularly merge master.

Make sure that project branches are created for larger units of work, so you will not always have to merge master into your branch, you can interact with a branch of more specificity and lesser volatility instead.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175