gmcc051 gmcc051 - 1 year ago 45
Git Question

How to share a large git merge amongst team members

When merging two branches together that results in 1000+ conflicts (the branches have diverged a lot), what is the best practice for being able to divide that work up among a team of people?

Say the code base is in a Visual Studio solution comprising of 20 projects, it would make sense for each team member to merge a project at a time, resolve the conflicts then commit and push to a remote so that the other team members can get the merge work that has been completed.

Here's a scenario:

  • There are 3 branches: master, A and B. A was branched off master and B was branched off A.

  • Branch A is continually updated but regularly pushed into master.

  • B has a lot of work done on it but hasn't had A merged into it for a long time.

  • A needs to be merged into B to get B as close as it can to A to make sure everything works correctly before ultimately merging B into A (then A can go into master and B can be deleted)

The problem we've come across is that as soon as a team member pushes their A->B merge work into B, git assumes that the entire merge from A into B merge has been resolved.

e.g. Say the first team member wants to merge Branch A's Project1 into Branch B's Project1. They makes a branch off B (call it B-submerge) and then merge A into B-submerge, fix the conflicts in Project1 then stage, commit and push the Project1 files into B.

This then makes git believe there is no further merge work required when merging from A->B. That means that when another team member attempts to make their own B-sumbmerge2 and merge A into into it in order to resolve the conflicts in Project2, git thinks there's no work to be done.

Is there a strategy that can be used to handle this situation?

Answer Source


So, you have the following branches, right?

 --o--o--------------o-----o--------o--------o   master 
       \            /     /        /        /          
        \          /     /        /        /           
         o--o--o--o--o--o--o--o--o--o--o--o--o--o--o   A
                  o--o--o--o--o--o--o--o--o--o   B      

I interpret the description up till (not including) "push the Project1 files into B" as approximately the following git commands:

cd /the/source/project1
get checkout -b project1.B_submerge B
git merge A
# Fix the conflicts
git add $the_modified_files_in_project1
git commit -m "Merge of branch A into project1"


At this point you want to merge the branch project1.B_submerge to B without carrying on the "something is merged from A" property that the merge from A caused (e.g. create the X version below).

---------o--------o   master
    /        /
   /        /
--o--o--o--o--o--o--o   A
--o--o--o--o--o-----------------X   B
               \        \      *
                \        \    *
                 o--------o--o   project1.B_submerge


This can be done by using the git apply command.

cd /the/source/project1
git checkout B
git diff B project1.B_submerge | git apply
git add .
git commit -m "Merge of project1.B_submerge using git apply"

The git apply command takes a patch and applies to the the current branch, and by feeding it the diff from the current branch and anything else, it will effectively make the current branch 100% identical with the content of that anything else.

So this will make the content of the B branch identical to the content of the project1.B_submerge branch but without any merge references. Notice this will be a single "squashed" commit though.

NB This will completely discard any commits made on B after the get checkout -b project1.B_submerge B command. If this is a possibility create a target branch with

git checkout -b target_B $(git merge-base B project1.B_submerge B)

and use that instead of B in the git apply command section above, followed by a merge or rebase to the tip of B.