23

At our team, in addition to individual units of work (Stories), we have longer-running themes of work (Epics). Multiple stories make an epic.

Traditionally we've had feature branches for each Story, and merged those straight to master when they pass QA. However, we'd like to start holding back on release of completed stories in an Epic until the Epic is deemed "feature complete". We'd only release these features to production when the entire Epic is closed. Furthermore, we have a nightly build server - we'd like all closed Stories (including those that are part of incomplete Epics) to be deployed to this nightly server automatically.

Are there any suggestions on how to manage our repo to achieve this? I've considered introducing "epic branches", where we'd merging closed stories to the related epic branch instead of direct to master, but my concerns are:

  • I worry about the merge conflicts that may arise if epic branches are kept open for long
  • Nightly builds would require merging all epic branches into a "nightly build" branch. Again, merge conflicts could arise, and this is to be done automatically

3 Answers 3

30

Simple suggestion: don't do that.

git branches are not for long-running forks of the code, as discussed here and here. Branches are best treated as transient things used to organize commits by an individual developer on a day-to-day level. So if they have a name that corresponds to something a project manager (let alone end user) might care about you are doing something wrong.

Recommended practice is to use continuous integration with feature toggles or branch-by-abstraction to ensure that:

  • all code is integrated at all times (at least every day, preferably more often)
  • what gets deployed is under explicit control.
5
  • 2
    I suspected this might be a popular answer! My main concerns with this are the overhead of always maintaining both the 'live' and 'next' implementation, and it also requires that the dev working on a feature knows upfront to build changes as new parallel features instead of upgrading (/replacing) the existing functionality. Guess it calls for a larger mindset change in the team.
    – Sitati
    Jan 13, 2016 at 12:45
  • It's ok to use branches to develop code, just never use them to store code. So if you are not sure if a task is a 30 minutes fix or a 2 week rework, then start on a branch. As soon as you know, either merge or refactor to a abstraction/toggle then merge.
    – soru
    Jan 13, 2016 at 14:21
  • @Sitati: I have just merged some code that was in a feature branch for the last four months. In the meantime on devel we have switched to CMake from Autotools, have introduced Travis CI, refactored the code. In the end it was easier to understand the new feature and apply it manually to devel than trying to merge it. We also had new Master students develop a new feature in a branch that they branched off when they started their thesis. After a year they pushed it and there was no effort to get it merged back, so it got harder to merge day after day. Jul 20, 2017 at 8:00
  • 4
    The linked blog post is now 5 years old. I hate feature toggles. What's wrong with branching long term, regularly merging back into the feature branch from main, and adding continuous integration to the long term feature branch? Aug 10, 2017 at 21:54
  • 2
    CI is the name of a process, not a tool. If you have more than one feature branch, they will not normally get continuously integrated with each other. Which means finding problems later rather than sooner.
    – soru
    Aug 11, 2017 at 15:01
5

This is a tricky problem but one that many people face. I prefer using the Gitflow setup as a starting point.

Development -> New stuff being worked on
Master -> Finished stuff needing testing Production -> Stuff that has been published to production.

At minor (shorter) features I create a branch from development do the work there then merger the branch back to development.

At major (long term) features I create a branch from development, create smaller branches from that branch, then merge back to the first branch. Once the major feature is complete then back into development branch it goes.

At regular intervals (depends on project) I merge development back into master and a testing cycle begins. If any fixes come up in testing they are done in the master branch (sub branch then merge in). And development can continue on the master branch during testing.

At any time master should be merged into development, and development should be merged to any of it's long term sub branches.

master should always (in theory) be ready for production. Development should always (in theory) be ready for production. The only reason there is a difference it to provide a solid set of features for testers to test.

When ready, a commit in master that is tested is merged in to production and deployment in production happens from that branch. HOTFIXs that need to be done in an emergency can then take place on Production branch without having to merge in master (which may have many un-tested changes).

My normal Tree looks like

 LongTerm -> Development -> Master -> Production    
 LongTerm <- Development      |            |  
     |       Development -> Master         |  
 LongTerm <- Development -> Master         |  
             Development <- Master         |  
                            Master -> Production  

It is my general rule that no single change should take more then a few hours. If it does then it needs to be made into smaller changes. If it's a huge feature (like a UI re-write) then that goes in long term so that normal development can continue at the same time. LongTerm branches are normally only local branches while Development, Master, and Production are remote branches. Any sub branches are also local only. This keeps the repository clean for others, without loosing the usefulness of git on a long term feature set.

I would like to note, however, that the existence of a long term branch is a rare thing. Normally, all my work is in development. Only when I have a feature (set) that is going to take so long that I need to be able to work on normal dev stuff too, do I use the LongTerm branch. If it's just a set of changes that should be together then I just don't merge to master till there all done.

8
  • "At major (long term) features I create a branch from development" - shouldn't you create new feature (development) branches from Production branch? Seeing as Production branch is release-ready code.
    – robotron
    Apr 8, 2017 at 21:38
  • No, production is already released, master is ahead of production and develop is ahead of master. A new feature like add tax to order totals is pointless if your not working on code that already has orders.
    – coteyr
    Apr 8, 2017 at 22:16
  • But if you branch from dev and later on merge back won't that branch (and consequently master and Production later on) then incorporate all the dev changes made by others up to the point of branching? Some of those changes might not have QA approval. Perhaps were talking about different approaches to release management.
    – robotron
    Apr 9, 2017 at 9:42
  • Yes it will, that's the point. QA tests on a specific SHA in master, but you cant hold dev up for that.
    – coteyr
    Apr 9, 2017 at 14:11
  • "QA tests on a specific SHA in master" -> QA tests each new feature as a standalone? Let me run by you a typical scenario my team faces: say you have 2 long running projects on the same codebase: Project A is in QA for the past month and will be QA'd for another month. Project B was in development for the past 6 months and is now ready for QA. Project A is merged into master and is definitely not production ready due to numerous subtle business rule errors. How do we handle Project B? A and B have to be tested together to check for interactions (B won't cause conflicts during merging).
    – robotron
    Apr 9, 2017 at 16:15
1

I think this is a pretty common problem and boils down to choosing which features to include in a release after the features have been coded rather than before.

eg.

I have features A, B and C for v2 of my product. B and C are related, I don't want to release B unless C is also finished.

I have three devs all working at the same time on the features.

I Have a set in stone release date D

B is finished and merged in, A is finished and merged in. C is delayed... what do I do?!

I do not believe there is a technical solution to this problem. You want to release an untested version of the product with only feature A included. Unless you merge and test all possible combinations of features this is always going to be a possibility.

The solution is a more human one. You have missed your release date and must push it back.

Your Answer

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

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