Search code examples
gitgithubgit-merge-conflict

How to solve git conflict with master that has too many commits ahead?


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

Solution

  • 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.