If you're getting a lot of conflicts then you have folks working on the same code and diverging it significantly. I honestly don't think that's a problem tooling will improve because it's really an organizational/communication problem. Engineers have to know when to rebase (or merge in changes from the target) if they're working on code with other engineers. If you merge in/rebase sooner, then things tend to be painless. If it's been weeks or months then let the Circus O' Pain begin. This should be fairly easy to recognize in stand up, eg: "Oh, you're working on that module? I need to track your changes, so am I."
It's much more complicated at scale. Many conflicts can come from things like backporting or working on a feature in a codebase that deals with a lot of churn (like some drivers or the Linux kernel). Some open source projects have internal versions of the code within the company that eventually gets upstreamed after internal validation takes place, but that version of the code may not rebase for a while for some very good reasons (unresolved instability on the main branch, for instance). In that case, the code base is now both significantly ahead (with internal changes) and significantly behind (due to the other changes that have come from other massive organizations working on the same project). I have published on the topic of merge conflicts a couple times, and even I didn't understand how inevitable massive merge conflicts can be until I joined a kernel integration team at a large company.
The problem here seems to be devs working on a branch for a whole week. If you break down tasks smaller than this and merge them separately then you end up with far fewer merge conflicts.
I wonder though, there /have/ to be merge conflicts? I suppose you continually rebase on the HEAD of master to keep up to date? So instead of taking care of conflicts at the end of a 'dev cycle' you take care of it in the middle.
I’ve been using git for nearly 15 years and not more than a half dozen times has resolving a merge conflict taken me more than 15 minutes.
This just isn’t a real problem. Try working more incrementally, or try working with colleagues who don’t rewrite large swaths of code without coordinating with their team.
Some people talk about merge conflicts as something inherently bad, but that's a flawed perspective. Merge conflicts are a great feature of a version control system. Given that multiple persons changed the same line, conflicts are the easy way out.
Conflicts have only given me a hard time when someone did something out of the ordinary. Even very large and unstructured open source projects such as the Linux kernel will see people naturally gravitate to different parts of the code. It's not often a filesystem developer suddently change the networking stack, for example.
I will go as far as to say that if you are repeatedly solving merge conflicts with new code you need to seriously revisit your version control choices. Merge conflicts are a tool to help you collaborate, they should not be an impediment.
Imagine if you could resolve such conflicts in a few minutes. The code editor should also be a collaboration tool.
Using an online editor, Mark a struct for changes…call a merge meeting with all affected module owners and everyone changes their code right there and then.
Even using email to talk about code is stupid and an unnecessary hurdle.
Windows, because of the size of the team and the nature of the work, often has VERY large merges across branches (10,000’s of changes with 1,000’s of conflicts).
At a former startup, our product was built on Chromium. As the build/release engineer, one of my daily responsibilities was merging Chromium's changes with ours.
Just performing the merge and conflict resolution was anywhere from 5 minutes to an hour of my time. Ensuring the code compiled was another 5 minutes to an hour. If someone on the Chromium team had significantly refactored a component, which typically occurred every couple weeks, I knew half my day was going to be spent dealing with the refactor.
The Chromium team at the time was many dozens of engineers, landing on the order of a hundred commits per day. Our team was a dozen engineers landing maybe a couple dozen commits daily. A large merge might have on the order of 100 conflicts, but typically it was just a dozen or so conflicts.
Which is to say: I don't understand how it's possible to deal with a merge that has 1k conflicts across 10k changes. How often does this occur? How many people are responsible for handling the merge? Do you have a way to distribute the conflict resolution across multiple engineers, and if so, how? And why don't you aim for more frequent merges so that the conflicts aren't so large?
(And also, your merge tool must be incredible. I assume it displays a three-way diff and provides an easy way to look at the history of both the left and right sides from the merge base up to the merge, along with showing which engineer(s) performed the change(s) on both sides. I found this essential many times for dealing with conflicts, and used a mix of the git CLI and Xcode's opendiff, which was one of the few at the time that would display a proper three-way diff.)
If merge conflicts are that common, either you're all tripping over each other trying to do things in different ways, or they are "artificial" conflicts caused by people rebasing public shared / branches.
Merge conflicts should be occasional, not an everyday occurrence.
Atlassian's golden rule: Never rebase a public branch.
Try to understand where conflicts are coming from. Are people committing different linting/whitespace/line-endings.
If so, then get automated tooling on the repo which enforces a linting and style guide to prevent re-format conflicts.
If they're from genuine refactors, try to understand why people are refactoring so much in a way that is causing conflicts.
Think if you have that many developers you need to start doing it Linux kernel style and have maintainers responsible for certain parts of the project making sure merges go in fine.
And maybe have actual communication in other means than via comments on tickets. The whole hypothetical example could be avoided by typing "hey, I'm changing this field to be that, anything against?" on team's chat
> Since my_branch was merged before it was rebased onto someone_elses_branch, this error goes unnoticed and BAM - main is broken! This is known as a semantic merge conflict — a merge is technically possible, but results in a regression.
Do people not merge master into their branch before pushing? All that seems like mostly problem caused by having too long living branches.
I'm also confused how that even fixes anything, someone still have to go back and fix that code.
In large, distributed teams working on very large monoliths, it's pretty easy to end up with conflicting changes. In such monoliths, the testing process also tends to be long. So you run your tests, get a pass, but someone else merges in before you and there's a conflict. You resolve the conflict quickly (if you're lucky. Some conflicts are not easy to resolve), you rerun your test suite, only to find out that someone else has merged ahead of you again and you have to go through the loop one more time. And all of this assumes that no one breaks the pipeline.
At this point, many teams institute a merge queue. Which works only until more devs are added to the teams, which makes the merge queue very long and it can take several days in the ideal case to get things merged.
If it happened because say someone else did a refactor then rebasing on that refactor (and that might actually mean manually doing a lot of stuff) is easy to inspect. The problem comes through as a commit with something weird unrelated to the change.
It does require line by line code review by the coder, which few might want to do, but I like to do before opening any PR. Because in any case it is so easy to have an editor window open while your cat walks on the keyboard and pastes your password, or whatever :-).
That is a standard problem you face in all projects and the conflict resolution generally happens on a First Come First Serve basis. Of course, the maintainer could decide it on the basis of priority and then the person merging to master next is responsible to fix the new conflicts.
If you're that worried about merge conflicts, isn't the real problem that you haven't refactored enough for SRP? If two people are working on different things, they probably shouldn't be editing the same code.
Of course we still have merge conflicts. You do too. Or is your work just organized such that no two people are ever working on the same file concurrently? If it is then you'd not have any merge conflicts with trunk based development either.
Fundamentally merge conflicts are unavoidable.
The claim by the trunk based development crowd is that smaller, but more frequent merge conflicts produce fewer mistakes. Trunk based development leads to smaller merges because you do them more frequently. That's about it.
reply