The team I am on is using the git implementation in Azure DevOps. We have been using almost the GitFlow model. We are using story branches instead of feature branches, and the long-lived develop and master branches.

The develop branch is deployed to the development environment, and the master branch is deployed to the QA (and later to production) environments.

When a developer completes coding for the story, a pull request is created into develop. Assuming all goes well with testing, the developer would then create a pull request from develop to master.

My question comes in when there are multiple developers working in the same repository. Developer 'A' completes a PR into develop, but that code is not QA-ready (not fully tested, bugs, etc). Developer 'B' then completes a different PR into develop, and would like to get that code into master. We currently have developer 'B' cherry-pick the PR into master, but that leads to some interesting history.

We would like to be able to merge individual stories to master as the stories are ready. Is there a different workflow that would better support this?

I've been through a number of articles today, GitLab flow seems to be the closest, but seems to want to take the latest master commit into production.

Recent Edits

(I'm adding these edits to try to cover some of the recent comments, hope that's acceptable)

Our current workflow is that developers work on story (or potentially bug) branches created from 'develop'. When that code is ready, a PR is submitted to merge the code into 'develop'. That is then deployed to the development environment for initial testing. Assuming that testing goes well, the developer performs a cherry-pick to create a PR into 'master'. The 'master' branch is deployed to the QA environment, and later to production.

This is wrong on a number of levels, Stop cherry-picking for one.

It is up to the individual developer to say when code is ready to go to QA. Code is deployed to QA a few times a day, and to production a few times a week.

I am hoping at some point we move away from the 'develop' branch, and just move to 'master'-based development with story branches. I'm afraid we're not there yet.

  • Tell me more about Developer B. Why is Developer B submitting a PR to develop when they really want their changes in master? Is developer B working on a bug fix for production? Feb 11, 2020 at 9:23
  • Is develop used for QA testing and then merge to master once testing is complete? Feb 11, 2020 at 9:25
  • 1
    The solution is simple - don't merge code that can't be deployed. You don't need a "complete feature" to have deployable code. If your devs are committing broken code, what they need is education on an alternative methodology that allows them to write code incrementally in such a way that it's always in a working, deployable state. VCS is not designed as a tool for patching over dodgy software engineering practices with convoluted process. Ditch the develop branch, branch off master for features (if at all) and merge in when it's safe to do so.
    – Ant P
    Feb 11, 2020 at 11:52
  • @GregBurghardt Developers A and B are working on stories. Our flow (currently) is that code merges into 'develop' for deployment to the development environment, then merges into 'master' for deployment to QA and later production.
    – mcollins
    Feb 11, 2020 at 14:15
  • @AntP I really like this approach. Reading between the lines, it sounds like we'd need to implement feature flags - something we're not doing yet.
    – mcollins
    Feb 11, 2020 at 15:26

3 Answers 3


What worked for me for several years is this:

  • Every developer uses their own branch per PR (feature branches).
  • Every day (or more often), the developer does git pull --rebase develop (or whatever other branch the PR is slated for). This way, any changes that might have happened in the target branch are always addressed early, and after resolving them, the branch is always technically ready to merge.
  • Merging to the target branch is git merge --ff-only --squash, so the common history is a history of merges. If anyone wants feature development history, they can check out the feature branch.
  • Thank you! I'm not exactly sure this gets at what I'm looking for (maybe I need to clarify the question). I have a PR that was merged into develop. What's the best way to get that same code into master? There might be other things in develop that aren't ready for master, so merging develop to master doesn't work.
    – mcollins
    Feb 10, 2020 at 22:17
  • What is your policy of merging to master? How do you cut releases, or do something else to determine whet goes there? It would inform the answer.
    – 9000
    Feb 11, 2020 at 3:21

This approach works well for managing development and change control for a self hosted product, such as a website, or a Single Service in a Service oriented architecture. It requires that you can release small, and in isolation, and that you have good automated testing on deployment to reject broken deployments.

When i am following this branching and releasing strategy, these are the outcomes that we consistently get:

  1. Small, frequent incremental change.
  2. A focus on simple clear design, testable and valid changes.

In summary, if you are always less than a few days from going live, you are always thinking about how am i going to demonstrate that this change delivers the expected functional change, and that it works robustly without errors.

These are the basic rules that we follow:

  • The Master branch contains all changes that are already deployed, and successfully running in the live environment. Everything else are isolated in their own separate branches, each managed by their own story / task / bug ticket.

  • Each branch is intended for a small piece of work. Ideally something that can be completed in under 5 days in total for development, testing, QA and release. The goal is to release small, frequent, low risk changes.

  • This is the opposite of continuous integration. Every change is managed in complete isolation from all other changes that are under development. As the confidence in the changes improves, changes are deployed into QA and staging environments and then deployed into production - and only merged into master after they have successfully deployed into production.

  • We continually incorporate all production releases, the build server fails builds if they do not have all of the changes available in master.

It does not work well if you are releasing a product to other teams to incorporate as an input into their project, or are releasing shrink wrap software that customers install themselves. The high rate of releases will upset your customer base, and you will be missing the important successful deployment that validates that the newly deployed code is successfully running


In GitFlow the develop branch is supposed to be continuously "work in progress." At some point you need to cut a release branch that contains all of the items in the next deployment. After a new release branch has been created, the develop branch is open for work to be included in the release after that. The master branch gets updated when deploying to production.

It sounds like you are missing "release" branches. This allows you to isolate a group of stories in order to send them through user acceptance testing before shipping them out to production. Now Developer B, whose story has been through testing, gets included in a release branch, and Developer A is free to merge a new story into the develop branch in order to be included in the release after.

Your Answer

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

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