55

Say multiple branches are being developed, A and B, as well as a incremental "bug fix" branch C.

Now C is already "finished" and merged into master. A and B are still in development and will not be fixed before (maybe) another bug fix branch is merged into master.

Is it a good idea to merge C as soon as possible in the new feature branches? So that the new features stay as close to master as possible? Or is it better to let the new feature be developed in their own "world" only merging into master once they are finished?

There will be conflicts anyhow, so time needs to be spent on fixing those.

9
  • 2
    Possible duplicate of What is a good frequency for merging up feature branches to a main line?
    – gnat
    Jul 22, 2019 at 11:44
  • 6
    @gnat that is about merging features branches into a main line, I'm wondering if merging main back into feature while feature is being developed is good, to "resolve conflicts early".
    – paul23
    Jul 22, 2019 at 11:59
  • 1
    @paul23, I would say that is a practical necessity. Jul 22, 2019 at 16:19
  • 6
    Honestly, a huge deal of my versioning problems went away when I started to use proper design on my code, like isolating modules and creating a well defined model of work. If you're stumbling too much on issues during merges, you may have another, more serious problem lurking somewhere. A good design is incredibly helpful in avoiding uncessary conflicts.
    – T. Sar
    Jul 23, 2019 at 14:29
  • 4
    You may want to merge in from master regularily to stay close "enough" not to make the merge later too painful. Jul 23, 2019 at 15:26

5 Answers 5

85

The longer a branch lives, the more it is able to diverge from the main branch and the messier and more complicated the resulting merge will be when it's finally finished. Ten small conflicts are easier to resolve than 1 massive conflict, and may actually prevent developers from duplicating or wasting effort. Given that, you should merge master into A and B regularly; once a day is a pretty common recommendation, though if you have a lot of activity on your branches you may wish to merge multiple times a day.

In addition to making conflict resolution easier, you specifically mention C is a bugfix branch. As a developer, I'd want my branch to have all of the latest bugfixes, to ensure I'm not repeating behavior that led to a bug, or writing tests based on erroneous data.

There will be conflicts anyhow, so time needs to be spent on fixing those.

If you know there will be conflicts, you may wish to adopt a different branching strategy. Keep multiple changes to the same file(s) on the same branch whenever possible, and you reduce or eliminate the number of conflicts. Refactor stories so that they are completely independent as much as possible, and rework branches to possibly cover multiple stories (branch, feature, and story are not always interchangeable).

8
  • 34
    Merge or rebase, as rebasing often produces a cleaner commit history. Jul 22, 2019 at 20:47
  • 12
    @chrylis: Rebasing may be dangerous if "branches cover mutliple stories" is taken to mean that two developers work on the same branch.
    – meriton
    Jul 23, 2019 at 7:28
  • 13
    @meriton from the official docs: Do not rebase commits that exist outside your repository and people may have based work on them. If you follow that guideline, you’ll be fine. If you don’t, people will hate you, and you’ll be scorned by friends and family. LOL
    – Aritz
    Jul 23, 2019 at 11:52
  • 6
    @XtremeBiker: A rebase in Git changes history. Git works like real-life in this regard: in order to change history, you need a conspiracy. There is a branch in the repository for Git itself that is regularly rebased, and it is a highly public one. The reason this works is that there is a conspiracy: everybody using this branch agrees to rewrite history at certain times, so they will make sure that they are in a position to have everything merged by those times. Jul 23, 2019 at 21:57
  • 1
    @paul23 Seriously consider delivering A and B to a new shared branch before delivering them to master. If they are both radical overhauls you want them together for a round of testing before inflicting the combination on master. If you are confident you could deliver one directly to master and then deliver the other to a fresh updated branch. You likely want to be able to look at the original code from the second feature in case the merge goes badly or you need to redesign something.
    – Sinc
    Jul 23, 2019 at 22:15
14

Assuming your intention is to eventually merge A, B back into master and maintain a single code base, it is never a good idea to deviate from master too far. Deviating from master for too long, especially when bug fixes and other development are merging to master as A, B are being developed, will certainly cause conflicts.

I would consider strategies similar to following

  1. Whoever is responsible for A,B should watch master closely and merge in any changes.
  2. Better yet, if you have build and test automation, make sure A,B merge in master, and pass tests nightly.
  3. Base on you comment to other answer, it seem that A,B could take a while to develop. In this case, you may even consider to have A,B merge each other as well so that in the end you don't have major trouble merging both back into master.
  4. At a higher level, think about why you need 2 separate line of long development. Could you breakdown into smaller merges? Could you break into separate micro services?
6

Usually often is better than a massive one.

Smaller, more frequent, pull requests are almost always better.

I've started using configuration flags primarily so that I can do early smaller pull requests so that I can, in turn, merge code more easily, but leave the feature deactivated. The smaller the pull request, the easier it is to review the code, even if there are more total pull requests. Most humans of any sort will not be able to do meaningful reviews of massive pull requests. It's just too tough on one's mental RAM to understand all the possible implications of a massive code change.

There is extra overhead in creating a configuration flag, so it's not worth it on smaller features. But then your pull request will be small anyway.

There may be situations, however, where the feature has to be released all at once. Even then it might be better to do smaller pull requests to another branch made for that purpose.

Most of my colleagues groan when someone creates a massive pull request, and for the most part, rightly so.

Also note that sometimes I need to cherry pick commits into a separate branches. If what needs to be cherry picked can be put into a single commit it makes it easier to move it around to other branches. This is a case where actually having few commits is better, but its not exactly the standard process if your cherry picking around.

2
  • 1
    Feature flags can be costly (USD 450 million in 45 minutes). This example is also mentioned by Uncle Bob (but without any technical whatsoever (as one would expect)). Jul 23, 2019 at 21:53
  • 1
    Yeah, there is the overhead of eventually removing them, though its usually not that hard. One might maintain them for longer, but then the flag is providing some greater usage. I agree if done hap haphazardly or without follow up, then things can go bad. Though things can go bad when a large pull request becomes difficult to review. On the other hand, some people may not be a in a position to add something like a configuration flag to the app they are working. Generally it helps with UAT and the rollout of a feature. Jul 23, 2019 at 22:59
3

In Refactoring by Martin Fowler, the advice that he gives is never to let a branch be branched off from master for longer than a day. IIRC, you should make a small change, test to make sure that you did not break anything, and then merge it back.

4
  • 2
    Well A and B hold major radical new overhauls to how the application works, they are not "done" within a month. However they are also useless before they are done...
    – paul23
    Jul 22, 2019 at 12:09
  • 8
    They may not be useless before they are done - they provide value by being a step towards the full result, and reducing the work required in future. Using techniques like feature toggles, branch by abstraction, or simply doing the user interface part last it should be possible to safely merge ithe incomplete work in to master.
    – bdsl
    Jul 22, 2019 at 13:31
  • 1
    that's why rebasing your local on top of any changes in the master branch is handy for longer term development. Keeps your work as though it was just branched off the latest
    – NKCampbell
    Jul 23, 2019 at 17:00
  • If you're purely refactoring, lots of small (completed) changes merged back is good. When developing something, it may take longer to have good, tested, working code. In that case you want to keep it up to date with the latest changes (merge master into feature) but not merge back until done.
    – Baldrickk
    Feb 24, 2020 at 16:15
3

Another option for really long lived changes that may be finished but not ready for use is to put them behind a feature flag so they can be merged in to master but have no risk of breaking anything. Then when they are ready to be used the feature flag can be removed.

3
  • 1
    Feature flags = zombie code (until resurrected)? Jul 23, 2019 at 21:21
  • @PeterMortensen Well you have to aim to remove flags as soon as possible but it could work for certain situations
    – Qwertie
    Jul 24, 2019 at 0:17
  • 3
    @PeterMortensen not if the flag is turned on for at least one person
    – Ian
    Jul 24, 2019 at 10:15

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