In the past year, most of the rest of my group (of engineers that I work with), has ended up deciding that merge bubbles really aren’t that bad.
At the very least, I’m seeing that other developers do not consider rebasing worth the effort needed to avoid merge bubbles when merging (sometimes very badly structured) pull requests.
Why is it actually not that bad to have merge bubbles in your commit history?
To be clear: I am not asking if merge bubbles are bad or not! I am asking why they are not bad.
First of all, as you already pointed out, they require less work. In my opinion, the burden is on the process that requires more work—in this case the rebase process—to prove its superior utility.
The biggest argument is that merges preserve an accurate history, as the development actually happened. A linear, consolidated history is useful at a higher level of abstraction, such as the quality and release teams. It’s quite the opposite on a development team, where it’s extremely useful to know exactly when and how a bug was introduced. Did it happen because of a merge, or was the bug there during development and I just missed it? If the history gets destroyed, you have no way to answer questions like that.
The other reason is it encourages fluid cooperation in other than star topologies. In centralized version control, the only way to share your work is to commit it to the central server. With distributed, you might have two people working together for a day or two, pulling from each other, then they push to the central server once it’s ready for the larger group. That’s a very efficient and natural way to want to work.
If developers have to worry about if x rebased commit contains the same changes as y commit they pulled from someone else during active development, that creates a cognitive load that discourages that mode of cooperation. Doing merges offloads that tracking effort to the version control software, which is why we have it.
4
Whether a satisfactory answer exists to this question is debatable since merge bubbles are desirable for a variety of reasons.
There is less long-term maintenance required when keeping history linear in git, plus it makes it much easier to see what someone was doing rather than attempting to traverse a bushy and complex history. From experience with a large organization and a large number of developers, there is a much higher rate of issues/bugs introduced due to bad merges when compared to rebase.
Honestly, there is not much overhead to keep history linear to avoid merge bubbles. Is it really that hard to add a –rebase option to git pull? Or to set rebase behavior as the default pull behavior in the configuration?
Additionally, the following benenfits are realized when using rebase instead of merge to avoid merge bubbles:
- Developers only have to worry about the commits they push when using rebase and not all the complexity and unnecessary commits they added to the history with merges. This greatly simplifies the code review process as well.
- Change history analysis is greatly simplified with less time/effort is required.
- Reverting changes is a straight-forward process when the history is kept linear through rebase. With merge bubbles in the history, reverting can be more effort than it is worth.
In general, best practices regarding when to use rebase vs merge can be described with the following two use cases:
- Rebase should be used for typical development work of individual contributors since it has nearly no additional overhead when compared to a merge.
- Merge should only be used by someone in a branch or release management capacity for merging changes between project, organizations, and/or teams.
As a quick disclaimer, with smaller development teams these considerations don’t come into play too often, but should still be followed as a best practice. With large organizations though, the benefits of using rebase to keep the history linear greatly outweighs an ill-conceived notion that merge has less overhead than rebase.
2
The reason merge bubbles are considered bad in the first place is that they mess up the history log. When it’s only one bubble per segment it’s not that bad – but when a large team uses merge all the time the history graph starts looking like one of these follow-the-line mazes.
If your team decided that merge bubbles are not so bad, than either:
- They are willing to accept the messy history graph
- They are willing to use flags like
--first-parent
to make it look linear - The team is not big enough for this to go out of hand(not likely)
- Any other reason that allows you to comply with messy history graphs
2