39

On our team, we use Git as our source control. We have several areas of code that are almost independent but have some overlap. Lately we have been discussing workflows and approaches to using source control. One complaint that comes up when I promote using a feature branch workflow is that people often run into complicated merge conflicts that they incorrectly resolve. By complicated, I mean "not obvious as to how to resolve". In light of this, other workflows are being more actively used, such a "pull rebase"-based workflow.

As an advocate of the feature branch approach, I'm not really getting the complaint. Yes, you have to keep your local feature branches up-to-date from master or wherever, but that's about the only real problem I see. I'm thinking that if your merges are always complicated and may have secondary effects, then that's more of a teamwork problem than a Git problem.

Am I correct in thinking this? Are complicated merge conflicts a sign of anything good or bad?

6
  • 1
    How long do features last? How well modularized is the code? Could you (for example), cherry pick in the test code commit (it was done first, and separate from the actual code, right?) to see how the functionality changed?
    – user40980
    Commented Aug 16, 2013 at 15:22
  • @MichaelT The code base is for our automated test code base. We're about to start work on a new addition to our project which will likely need some parallel development for a bit. Hence the discussion of feature-branches vs others. Commented Aug 16, 2013 at 15:56
  • 9
    Do people actually run into this kind of problem, or do they just fear those problems may appear? Commented Aug 16, 2013 at 17:50
  • 2
    By the way AWESOME tutorial you have linked to :)
    – Vorac
    Commented Aug 19, 2013 at 8:51
  • 1
    Rebasing the feature branch or merging it with trunk results in similar merges. Rebasing actually does more merges and as such is more likely to create bad conflicts. What matters is how often it is done.
    – Jan Hudec
    Commented Aug 20, 2013 at 15:51

7 Answers 7

28

It's not impossible that the problem is your code. If your codebase has a lot of inter-relationships between modules, then every change is going to have tendrils everywhere, and every a dev interacts with anyone else's code, it's going to be a nightmare.

I'd tend to think you'd notice this in other ways first, but it's possible that you're so used to it that you can't see it anymore.

3
  • 11
    This was my first thought. Complicated merge conflicts occur when multiple changes are made to the same code. If you have a fairly young project then this is common, but if you have a good-sized codebase then this could be a sign of "god objects" or that some modules/classes are doing too much and need to be refactored. It can also stem from over-zealous committers committing dozens of small changes, but that's less common.
    – TMN
    Commented Aug 16, 2013 at 16:52
  • 1
    The fact our codebase is somewhat "young" (approx 6 months old, gone through several major refactors) could be an indicator of this. Commented Aug 16, 2013 at 19:42
  • 12
    @joshin4colours If you're refactoring while somebody is writing a large feature, you're in for trouble. Commented Aug 16, 2013 at 20:20
21

I am used to the "fetch-rebase-push" workflow. Which is actually the first, most primitive, workflow, that is described in your tutorialHere are the advantages:

  • True continuous integration
  • Early conflict management - right after one has written and tested the code
  • Rapid response - "-Hey, Bob, the cubic interpolation you wrote is giving funny output, could you look at it while I am at lunch?"
  • No merge commits - clean timeline as if one developer wrote everithyng

Now, concerning complicated merge conflicts. I do not understand how one could experience both frequent and complicated merges. Complication arises from not rebasing/cherry-picking for a long time, working on that lone feature for a month.

I personally would prefer to deal with frequent, easy merge (actually rebase) conflicts, rather than rare, all-encompassing merge horror.

4
  • 1
    Great description of a good Git workflow, but this doesn't quite answer my question. Commented Aug 16, 2013 at 15:54
  • 2
    @joshy this is true. Only the middle paragraph kind of address your question. But here is a direct answer. If merging is frequent and difficult, then this is certainly an indication of problematic workflow/communication problem/architecture problem/division or the roles problem.
    – Vorac
    Commented Aug 16, 2013 at 17:22
  • Won't you just get conflicts during the rebase instead of during a merge? Its the same conflict either way. Commented Dec 29, 2019 at 2:54
  • @DaveInCaz of course conflicts don't magically disappear. As far as I understand it, rebasing solves conflicts per-commit while merging solves conflicts per-branch.
    – Vorac
    Commented Dec 29, 2019 at 11:38
9

Merges and rebases should cause the exact same conflicts, for those inherent conflicts that a human must resolve (i.e. two developers changing the same line of code). For other conflicts, merges actually tend to be cleaner, because you're not changing the SHA-1 of commits all over the place. I'm not sure how you're managing to get into a state where merges cause more conflicts than rebases, but it's certainly a sign that some people's workflow is messed up, and they probably need more training on how git works. Are they removing other people's merge commits when they do their local rebases, or something like that?

The benefit and drawback of the pull-rebase method is it's very similar to centralized workflows that a lot of people are used to. You don't have to understand branching in order to use it.

At any rate, it's perfectly feasible to do a feature branch workflow only locally, if you can't get other people to sign on to it.

6

The project I am working on has this type of problem from time to time and it seems to result from a couple of factors:

  • We are using Visual Studio and files like the Visual Studio .sln are just XML documents ( which don't respond well to textual merges ) full of Guids ( which Git can't understand any better than the rest of us ) and can easily be badly merged and cause files to be lost.
  • Some people are working on similar areas of the code, so that the changes getting pushed can be right next to each other in classes. Although unavoidable in this situation, this type of configuration is going to be very hard work for any source control system. Even if you have great communication in your team, sometimes people won't realise they are bumping into one another's code and conflicts arise.

I'm interested by the potential for Semantic Merge to help with some of those problems, but obviously that is only any use if you're working in a language it can parse and I haven't yet run into any significant challenges when I'm using it, so I can't vouch for its effectiveness.

6

Unless developers are modifying historical commits (instead of pure merges), the conflicts in a feature workflow type git model are a sign of a tightly coupled codebase (/brandnew codebase) or overlapping feature assignment.

1

You have a main (master) branch and everybody works in their feature branches.

Work in the feature branches can take anything from few hours to few months.

Every now and then somebody will reverse merge their changeset back into the main branch. Your team lead needs to make sure that only one person does a reverse merge at a time. Once this has been done, you need to forward merge from Main branch into your feature branch. Once everybody does a forward merge, another person can be allowed to reverse merge into main branch. Otherwise too many changes will be reverse merged and you'll have tons of merge conflicts on your forward merge.

Just to clarify the terminology, by "reverse merge" I mean merging from feature branch into main branch, and by "forward merge" I mean merging from main branch into feature branch. Based on what I've experienced before, you are likely to see more merge conflicts on reverse merge, as opposed to forward merge.

3
  • 4
    Merging into main branch must never have any conflicts. You always merge main to feature first, so feature to main is then conflict free.
    – gnasher729
    Commented Jan 23, 2017 at 8:24
  • @gnasher729 - I think that's what this answer's saying - the suggestion as I see it is that every developer merges from main to their feature branches every time anyone commits anything to main, so that all of the conflicts are immediately resolved on the feature branches. Commented Jan 23, 2017 at 9:53
  • He said "you are more likely to have conflicts merging from feature to master"
    – gnasher729
    Commented Jan 23, 2017 at 18:05
1

Two things that may help: One, avoid any tools that make changes on their own. Two developers using different tab settings is a recipe for disaster. Two, make changes in different locations. You get a problem for example if three developers add code at the end of the same file - much better if they add code in different places.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.