54

We have a developer team of 4 and have recently moved to Git. We want to learn best practices regarding workflow with branching and merging.

We are using a lightweight version of Git Flow. We have a dev, staging and a master branch which are all linear with each other.

  • staging is branched from master
  • dev is branched from staging

On top of that we use feature and hotfix branches to work on new features and fix bugs.

I have the following questions:

  1. Should we branch feature branches from dev or from master?
  2. When a feature branch is ready, should we merge the feature branch into dev, then merge dev into staging, or merge the feature branch into staging and then the feature branch into master?

I think we should branch from master and merge the feature branch up, because there might be something in dev that we might not want to merge to staging and master.

What is your opinion? What are the best practices?

Gaui
  • 8,723
  • 16
  • 64
  • 91
  • 1
    Possible duplicate of [git with development, staging and production branches](http://stackoverflow.com/questions/15072243/git-with-development-staging-and-production-branches) – Liam Feb 21 '17 at 09:09
  • 5
    IMHO this is no duplicate. Closely related? Yes. Duplicate? No. This question is based on the git flow model while the linked question references an article with a similar but not identical workflow. – Sascha Wolf Feb 21 '17 at 09:51
  • https://git-scm.com/docs/merge-strategies – Channa Jul 17 '20 at 19:26

3 Answers3

43

While Git Flow is an excellent branching model, the questions you are asking are a symptom of a bigger problem: Git Flow is too heavy for a small team working on a consumer web product (I am making an assumption that you are working on consumer web product, feel free to ignore if you are coding nuclear power plant control room).

I would like to encourage you to consider Continuous Deployment (CD) with an extremely simple branching model:

Master -> Branch

It is very easy to setup CD nowadays:

  1. Use Travis, CodeShip, Jenkins or similar system to run a full build and test suite on every commit pushed on every branch of your codebase
  2. Setup Travis/Codeship/Jenkins to deploy to production every commit to master that passes the tests.
  3. Create a new branch from master for every new feature.
  4. Code a new feature and test it on a branch.
  5. Merge a feature branch into master, and watch it go live.

There are a lot of common objections to it, that all can be summarized as "but what if I introduce a bug?!". The answer is "You'll fix it!". If you write tests, if you monitor your production site, if you do code reviews, if you practice pair programming, if you use feature flags, and if you keep your features small, then the benefits you get from CD will outweigh the occasional problems any day.

I encourage you to try. It will free your mind to focus on what truly matters: building a great product! If you do not believe me, take a look at this excellent presentation from Github.

quarterdome
  • 1,559
  • 2
  • 12
  • 15
  • 1
    Thank you, this is the dream goal. But managers want code deployed to test, staging and live environments. Not sure how that fits into this simplicity. – Gaui May 14 '15 at 22:01
  • 2
    It actually fits quite nicely. Whatever you put on a branch can go through any amount of testing: you can test on your machine and merge or you can put it on "staging" and throw QA team of 10 people for two weeks on it. You need to use appropriate level of testing for each feature. One-liner messaging change should not go through the same testing process as a new shopping cart checkout flow. CD allows you to do just that, keeping your branching simple. – quarterdome May 15 '15 at 01:01
  • 4
    This seems like the best solution for smaller teams, as you mentioned. There is no reason to complicate the process. Thanks for sharing the slide-show as well. – Adam Nov 01 '17 at 14:37
  • 1
    Another point of view for what @Airborne said: This seems like the best solution **is to have** smaller (and cross-functional) teams. There is no reason to complicate the process. – Matruskan Jan 17 '18 at 19:13
  • I like this answer, but the first reaction is to recoil. What? we need all these branches and processes and lockdowns so bugs don't get shipped. But that flow happens I think because the things in your "ifs" section are skipped. It's this going for monolithic builds every x weeks that scares people. – redOctober13 Dec 14 '18 at 16:35
  • it's so easy to get locked down and panicked by the possibility you might allow a bug to slip through the cracks, but such is a natural part of learning. You have to learn to love failure, or at least tolerate it, in order to get anywhere. Just do your best to write effective tests, remember the principles of secure coding, and if something goes wrong, assuming you've been committing routinely, the whole point of git is that you can roll it back to figure out WHY. – Twisted on STRIKE at1687989253 May 15 '23 at 14:58
30

This always depends on how do you want to work and the team agreement. That said.

  1. A feature starts from the dev branch into its own branch. From the master branch you should only branch hotfixes because the master branch should always be the stable version of your software.
  2. When a feature branch is done, it should be merged into dev, then at some point you should branch your next release from dev (including some features) into a new 'release/*' branch which will be merged into master once it is stabilized and well tested.

In the Atlassian page you have a very nice explanation of this workflow

The whole idea with this kind of workflows is to have a stable version branch in which you can work and fix any bug immediately if you need to with enough confidence that it will still be stable and no new feature or refactorization will slip in without noticing.

Also to have isolation and freedom for each new feature which will be developed in its own branch with no noise from other features. Then finally you will merge your features into your dev branch and from there into the master branch for the next release.

The only thing I would recommend for you is to learn how to rebase your feature branches on top of the dev branch each time another feature is merged into dev to avoid resolving conflicts on merge time, but in isolation on the feature branch where you know what your changes are.

It also looks like this question was asked before

Community
  • 1
  • 1
Pablo Carranza
  • 409
  • 3
  • 5
  • What if you don't have (pre-defined) releases and you don't want everything from `dev` to end up in `staging` or `master`? Wouldn't the best way to branch the feature branch off from master, work on that feature in isolation, then merge it up to dev. If it's ok, merge the feature branch up to staging. If accepted, merge the feature branch up to master and deploy to production. If we merge the feature branch to dev and then merge dev to staging, there might be some features we don't want on staging. Also if something is on staging that shouldn't go to master. – Gaui Jul 05 '14 at 16:13
  • Usually dev is something you can call *your next release*. I did something like what you say in one project and it ended up fine, but it did brought a lot of rework when merging, mostly because you can merge a feature in master that comes from a long forgotten release, and the codebase changed a lot. So it is up to you and how you plan your work, but my guess is that at some point you will be able to say something like: ok, this features should be released next, and then is when you will have to merge into "dev" or scratch "dev" and just use releases branches from master. – Pablo Carranza Jul 05 '14 at 19:34
16

We settled on a workflow called Git Flow, but instead of branching features from dev, we branch them from the current release. This makes us able to work on seperate issues in different speeds. If they are successful in QA, they go into the release.

Regarding branches and deployment:

  • The dev branch is deployed automatically to test servers.
  • The current release branch is deployed automatically to staging servers.
  • The master branch is deployed manually to live servers by the release-master.

The workflow is the following:

  1. Create a release branch from master in the beginning of each release/sprint, e.g. release/2015-may .
  2. Create a dev branch from release/2015-may
  3. Working on a new feature, branch from release and name it feature/ISSUE_NUMBER.
  4. Work on your feature.
  5. When it's ready for testing, merge it into dev.
  6. If it's accepted, merge it into the current release branch.
  7. If it's not accepted, go to step 4.
  8. When the release is ready, merge it into master

After the release has been deployed to live and a critical bug is discovered, we branch a hotfix branch from master (e.g. hotfix/ISSUE_NUMBER), merge it back into master and deploy again.

Gaui
  • 8,723
  • 16
  • 64
  • 91
  • But how this approach will be, if suppose 2+ new features are started in parallell ? For example, release/2015-may -> dev -> then feature/1 and feature/2. So what would it be, if both feature/1 and feature/2 are merged to dev and only feature/1 is accepted ? – Kamalakannan J Feb 13 '17 at 16:10
  • @KamalakannanJ Then only feature/1 would be merged into staging/release. – Gaui Feb 21 '17 at 22:15
  • So we have to merge feature/1 directly into staging/release ?? not through dev-> staging/release ? – Kamalakannan J Feb 28 '17 at 15:34
  • Yes, first merge the feature into dev. If it's accepted on dev you merge the feature into staging/release. – Gaui Mar 02 '17 at 13:02