14

In short, we have one repo which hosts code for different functional teams, i.e. server-side, mobile, ci, automation qa etc.

Now when we are trying to pull down from support-branch bug fixes into dev-release-branch a lot of conflicts appear related to different teams/areas of development. Since we don't have single person covering server-side and mobile, it's really tough to resolve conflicts for one individual.

The question here is: is it possible somehow to resolve only some of the conflicts (e.g. server-side), then push to intermediate branch, and let other teams resolve conflicts related to their area of development. And only after all teams resolve all the conflicts finally merge intermediate branch.

Maybe we are doing something wrong here. Any suggestions would be appreciated (except splitting code base into separate repo, too late for this).

monitor
  • 251
  • 2
  • 9

2 Answers2

2
git checkout -b server-team-merge dev-release-branch
git merge support-team-fixes
# fix the conflicts you can fix here
git commit -m "server-team partial merge of $(git describe support-team-fixes)"

and each other team does likewise. Then merge the partial-merge branches -- if the results were truly disjoint you can do them all at once, it'll be a trivial operation,

git checkout dev-release-branch
git merge {server,mobile,ci,automation}-team-merge

but if that complains merge them in one at a time to ferret out the different ideas about how some of the conflicts should be resolved.

When you merge a branch, git regards the result as a correct and complete merge of the merged history in the resulting commit, so any subsequent merge will identify the entire history as shared and there'll be nothing left to do. But if you do multiple independent merges from the same parents, those merges aren't in each others' histories and can have any results you want; in subsequent merges of those results Git can see the commits' ancestry and identify the correct base.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • Sorry, it's not quite clear what I should do with fixes out of my scope after merge - just simply leave them hanging in conflict state and do not commit? – monitor Dec 15 '17 at 18:12
  • also could we exclude from commit all files merged automatically if they do not belong to our scope? I wanna server branch contains only server related fixes. – monitor Dec 15 '17 at 18:18
  • You could certainly overwrite all local changes to out-of-scope files before committing merge results, `xargs -d\\n git checkout MERGE_HEAD -- – jthill Dec 15 '17 at 18:33
  • But unconflicted changes should be automerged the same way in each merge, so it won't matter where the final merge gets its content from, it's literally all the same difference. On thinking about it I don't see any need for the reset. For conflict resolution, presumably you've got some way of identifying who, making changes in which merge, has the authority to resolve each conflict, so just take that branch's version, so whatever was done in the other branches makes no difference at all. – jthill Dec 15 '17 at 18:47
1

Well, you may try something like this:

  1. Checkout dev-release-branch and begin the first merge with support-branch.
  2. Resolve as many conflicts as possible (by a single person). Files and directories that couldn't be merged by that guy should be reverted back to its dev-release-branch state.
  3. Commit the resulted state as a-half-of-a-merge, save it as a (temporary local) tag.
  4. Revert dev-release-branch to its pre-merge state
  5. Perform anothermerge with support-branch by another guy who's able to merge other parts of the source tree. Again, revert changes not to be considered as in step 2.
  6. If there're changes to be merged repeat steps 3-5 (certainly, choose a different tag name).

When all conflicts from the last "domain" are resolved, but the merge commit hasn't been created yet, let's start combining the changes from different "half-tags".

  1. Add the current set of changes to the index.
  2. cherry-pick changes from the first half-tag. You will have to specify the merge parent with -m switch (likely -m 1) and --no-commit
  3. resolve any conflict you get on this stage. Hopefully the list will be short or obvious
  4. add the changes to the index
  5. repeat steps 2-4 for all half-tags
  6. finally commit The Great merge.
  7. Now all the half-tags can be safely deleted.

As you might have noticed the whole process is somewhat long, complex and cumbersome. For future releases I would suggest to split the project into an appropriate number of subprojects and combine them into a big project using git submodules.

user3159253
  • 16,836
  • 3
  • 30
  • 56
  • We have something similar in mind, but I was under impression that we are missing something and there should be a simpler way to do it in git. – monitor Dec 15 '17 at 16:35
  • Well, there's a slightly simpler way — check @jthill's answer. But his approach leaves a mess of intermediate merges in the history graph, and what may be more important, it effectively blows mechanical minds of CI robots. – user3159253 Dec 15 '17 at 22:47