Home > Mobile >  How to approach a large merge with many conflicts that are not all best handled by the same person?
How to approach a large merge with many conflicts that are not all best handled by the same person?

Time:09-10

Say we have a develop branch and a feature branch. The develop branch receives many updates, very frequently, from dozens of developers. It often gets very far ahead of the feature branch.

On one occasion, a merge from develop into feature results in 300 low-level conflicts. These conflicts touch many different areas of the codebase, and no single developer is familiar with all of it. Therefore, it is difficult for any single developer to be able to resolve every conflict on his local machine in order to push a logically correct, conflict-free version of the project.

I understand that the best solution would be to avoid this situation. However, precluding that - due to organizational dysfunction, fait accompli, etc., this situation exists - how best to use git to extricate oneself?

My understanding of git is that it is not possible to commit anything that remains in a conflicted state; by staging, you are indicating that it is not conflicting. Yet, that seems to require that any and all conflicts become the unshared, un-collaborated-upon responsiblity of the person doing the merge. This is undesirable because the conflict resolution is a large task, with parts best handled by separate people.

Two potential ways out occurred to me. However, neither one sounds great. First, I contemplated trying to resolve what conflicts I could, committing those resolutions only, and then leaving other developers to the parts to which they are suited. However, as far as I know, git does not support any kind of interim merge commits, and indeed won't let you begin a merge and subsequently commit unless you locally add every conflicted file, thus marking it resolved. I believe this answer supports my apprehension.

That led me to my second idea, which was to merely fix what I could, and commit the rest including conflict markers. Fortunately, I was able to resolve all high-level conflicts (file renames/deletions, etc.) but if I hadn't been, those would remain an issue. Setting aside that the feature branch would be in a non-compiling state, I am concerned that git would no longer consider these files to be in conflict; it would mean that we would have to rely on our IDEs and other tools to detect the git conflict markers.

My preference would be to only commit files that are actually resolved, allowing other developers to pull them, while files that are not actually resolved remain indicated as conflicted, to them.

I also noticed that there is a --no-commit option available to git merge, and I am wondering if this is the way to go, since I presume that it would allow me to only commit files I've actually reviewed, understood, and resolved, while leaving the remaining conflicts uncommitted locally.

Is there a more effective strategy to use git to split responsibility for this merge among several developers?

CodePudding user response:

There are ways to cope with it. Say, merge on a separate branch that will be used to... let's say, stabilize it..... keep a list of the conflicted files. Commit the results with conflicts (awful, I know..... it will make sense in the end, continue reading). Let the developers now work on that branch to solve the conflicts (provide the list of files, assign who will work on what and so on).... keep on working on this branch (with pull requests, if you deem it necessary).... normal development flow... well, normal within merge conflict resolution.

When it is finally stabilized, all conflicts resolved and so on (and here's the beauty of git), just squash all revisions used to stabilize it and amend the merge revision. So... something like:

git checkout -b stabilize main
git merge the-other-branch
# you get a gazillion of conflicts....
git status > status_merge.txt # keep the list of stuff
git add .
git commit -m "Merging with conflicts.... this is not finished"
# let's set a temporary branch on this revision, so that it is easier to go into the final steps
git branch broken-merge
git push the-remote stabilize

Now pass around the list of files to work on and let your developers have fun on top of that branch until it is finally resolved.... when it is resolved, you can come back to wrap it up:

git fetch the-remote
git checkout the-remote/stabilize
git reset --soft broken-merge # this is your magic wand in action
# now, all the changes that developers had to do to stabilize the branch are in index
git commit --amend -m "Real merge, stabilized"
# and now you have the _real_ results of the merge... and you get the credit for it :-)
git branch -f main # let's set main over here
git push the-remote main
# take a bow

And that's it. It's not the most elegant, I agree.... but it would work.

CodePudding user response:

Unfortunately, any commit you make after git merge is the "final result" as far as Git itself is concerned. That's why eftshift0 suggests making an extra, bogus, temporary branch on which you and others build a bunch of temporary results to make progress towards the final real merge.

The way this works in a sort of graphical nutshell is like this:

                 ----------
                /          \
       o--...--o   <-- br1  \
      /         \            \
...--*                    
  •  Tags:  
  • git
  • Related