<p>You are already building and testing code on each of the pull-request and hot-fix branches. This means that in aggregate, the sum of all branches pending on pull-request are your virtual <code>develop</code> branch.</p>

<p>You can create a system when in a test environment, several pull-requests are cherry picked into a temporary branch that is not published to the main repository. This branch is used to integrate a test environment that includes <code>master</code> and several additional pull-requests, but once the testing is done, this branch is no longer available anywhere.</p>

<p>When you create a release from <code>master</code>, you would usually create a tag on that release. Later hotfixes can use that tag to create a new hotfix branch from which a deployment will be made, even though the edge of <code>master</code> is already ahead. On this hotfix branch you would probably also tag a minor release, and make sure that the changes were merged into <code>master</code>.</p>

<p>Removing merged features from a release is quite hard to do with git. The best mechanism for this would be to use <code>git revert</code> on the merge commit. But that makes it almost impossible to get these features/changes back, and history becomes all muddled.</p>

<p>A much better way to handle separation for deployment of code, and release of features, is <em>feature flags</em>. If your developers can hide their features behind some conditions in the code itself, you could deploy their code, but turn off the feature. This is a separate topic, but a lot of information about this exists (including a Q&amp;A on devops.SE).</p>

CC BY-SA 3.0
2017-03-02T16:01:44.853Z
2017-03-02T16:01:44.853Z
Evgeny Zislis
<p>Well @dan-cornilescu says it well for your particular problem, but the more general case for Trunk-Based Development (mentioned in the Continuous Delivery, Lean Enterprise, and The DevOps Handbook) is made here: <a href="https://trunkbaseddevelopment.com/" rel="nofollow noreferrer">https://trunkbaseddevelopment.com/</a></p>

CC BY-SA 3.0
2017-04-01T23:13:04.663Z
2017-04-01T23:13:04.663Z
paul_h
<p>Let's say you take out the master branch  (you can rename develop to master to confuse your team if you like later) and simply use tags for releases either on develop or hotfix branches. You took out a branch, but the difference is just a change in syntax. Change for change sake.</p>

<p>Now let's say you actually take out develop with keeping the locked master branch. What will happen is that integration of code will slow, it will live longer separated in feature branches, especially close to release dates. This will Increase the difficulty of merging each time and slow the process down.</p>

<p>Within the constraints you have laid down I don't see any positive effects of making such change. It would require relaxing the constraints, especially the first one.</p>

CC BY-SA 3.0
2017-03-02T13:12:30.073Z
2017-03-02T13:12:30.073Z
Jiri Klouda
<p>IMHO the problems you're facing are just a side effect of the poor branch strategy you started with: you're effectively plowing new development on <code>develop</code> (i.e. what converges towards the <em>future</em> production code) <strong>through</strong> the <em>current</em> production code on <code>master</code>. This leads to contradicting requirements and problems since typicaly the future code diverges from the current one:</p>

<ul>
<li>the new development destabilizes production - regressions seen after merging <code>develop</code> into <code>master</code></li>
<li>stabilizing the production slows down future development - you need to stabilize <code>develop</code> to make it good enough for merging into <code>master</code></li>
</ul>

<p>Dropping <code>develop</code> won't help (much) - you're not eliminating the problem, you're just transferring the <code>develop</code>-specific portion of the problem into <code>master</code>.</p>

<p>A better approach would be to move the production <strong>behind</strong> the current/future development, to prevent interference with development for future releases, as illustrated in this image from <a href="http://paulhammant.com/2013/12/04/what_is_your_branching_model/" rel="noreferrer">What is Your Branching Model?</a>:</p>

<blockquote>
  <p><a href="https://i.sstatic.net/7g9rx.png" rel="noreferrer"><img src="https://i.sstatic.net/7g9rx.png" alt="enter image description here"></a></p>
</blockquote>

<p>Please note that I'm only referring to the release branches in the above image, not on what's happening in the trunk.</p>

<p>How would this work for you:</p>

<ul>
<li>the <code>develop</code> branch dissapears, as you wished, absorbed into <code>master</code></li>
<li>the <code>master</code> branch is your trunk, this is where development happens with no speed restrictions (it's <strong>never</strong> merged into production).</li>
<li>production is/are one or more <code>release</code> branches pulled from a <code>master</code> label/tag considered close enough to production quality (a short list of remaining todo items can be addressed in that branch if needed). These branches can only receive direct hot-fixes and/or cherry-picked fixes from <code>master</code>, they are <strong>never</strong> merged with <code>master</code> or other branches</li>
<li>hotfixes are direct commits into <code>release</code> branches</li>
</ul>

<p>If a hotfix applies only to a production version but not to the <code>master</code> it is directly committed to the <code>release</code> branch. If it applies to both it's typically committed to <code>master</code> first and cherry-picked/double-committed to the <code>release</code> branch as well.</p>

<p>Now looking at what goes into <code>master</code> (which is past the point where the current <code>release</code> branch is pulled off), you have 2 options:</p>

<ul>
<li>continue with feature branches just like you do today, except they'll be based off <code>master</code>, not <code>develop</code>. Converting them to hot fixes remains possible - you'd just have to rebase them to the corresponding <code>release</code> branch instead of <code>master</code></li>
<li>switch to continuous integration and reap its benefits (can be done at any time going forward), including in a progressive manner - gradually pull fewer and fewer feature branches.</li>
</ul>

<p>If you like this approach here's how you get there from where you are today:</p>

<ul>
<li>establish a release naming strategy:

<ul>
<li>you can't have an ongoing release branch with the same name</li>
<li>you can't (shouldn't actually) rebase or sync a production release branch</li>
</ul></li>
<li>pull a <code>releaseX</code> branch from <code>master</code> immediately, following that naming strategy</li>
<li>stop commits from going into <code>develop</code>, they'll be soon going straight to <code>master</code>.</li>
<li>merge <code>develop</code> into <code>master</code></li>
<li>instruct developers to rebase their workspaces on <code>master</code> instead of <code>develop</code>.</li>
<li>open <code>master</code> for commits</li>
<li>delete <code>develop</code> if you desire (or leave it permanently locked/read-only for reference)</li>
</ul>

CC BY-SA 3.0
2017-03-31T19:39:12.980Z
Thank you for the detailed suggestions. I'm not sure yet if release branches are a good idea outside of product development, but I'll reconsider it, it could make sense for this project
Fabian Schmengler
CC BY-SA 3.0
2017-03-31T20:04:59.660Z
You also have the continuous deployment alternative, which puts the development in the same place with the production (as opposed to pushing through or preceeding it), but for that you need a culture shift (as it implies dropping all integration and feature branches).
Dan Cornilescu
CC BY-SA 3.0
2017-04-01T23:10:50.823Z
I recognize that diagram :)
paul_h
CC BY-SA 4.0
2020-05-06T13:01:06.493Z
I have a doubt about committing hotfixes in master first and then cherry-picking to release. Example - my manager asks for a hotfix. If I implement it on master and then pick it into a release branch, it can (by Murphy's law, master will have code changes that affect the hotfix) turn out to be incompatible with the state of the release branch. So, now I have to spend time on rewriting the hotfix specifically for the release branch and also explain to the manager why I couldn't fix the issue on the release branch first to deliver it ASAP, and later deal with fixing the hotfix to fit master.
JustAMartin
CC BY-SA 4.0
2020-05-06T15:51:17.903Z
@JustAMartin: either order works just as well, the master and release branch(es) are totally independent. If you have incompatibilities, though, the hotfix is NOT equally applicable, it can't be cherry-picked.
Dan Cornilescu
CC BY-SA 4.0
2020-05-07T12:00:28.673Z
I mean mostly from management perspective - release hotfixes should always have the highest priority, master branch can wait. So, if you have to develop a fix from scratch, it makes sense to implement straight in the release branch first, and only after that merge it back into master and deal with master branch consequences after the hotfix release branch has been tested and delivered.
JustAMartin
CC BY-SA 3.0
2017-03-31T18:42:21.520Z
2017-03-31T18:57:53.343Z
2017-03-31T18:57:53.343Z
Dan Cornilescu
<p>In a continuously developed web project (not a product) we currently have the following branching strategy, roughly based on <em>git flow</em>:</p>
<ul>
<li>develop branch: latest working version</li>
<li>master branch: version to be released / released version</li>
<li>feature branches: features in development</li>
<li>hotfix branches: urgent bugfixes in released version</li>
</ul>
<p><strong>Master</strong> is read only, updated via pull requests from <strong>develop</strong> or <strong>hotfix branches</strong>. Each update results in a release candidate being built and deployed to the staging system. Release candidates are deployed to production after manual approval.</p>
<p><strong>Feature branches</strong> are created based off <strong>develop</strong>, or from the last commit that has been merged into master. A pull request from a feature branch to develop is built, deployed to a free test system where integration tests and acceptance tests (automatic &amp; manual) are executed. When successfully tested and reviewed, the PR gets merged, so that it will become part of the next release (i.e. merge from develop to master).</p>
<h2>My goal</h2>
<p>I would like to simplify this and get rid of the develop branch. The develop branch has mostly historical reasons and since it is always a successfully tested version, I think it is unnecessary to keep it separated from master. Removing it will also simplify the release process because there is no additional merge anymore.</p>
<h3>I have the following constraints:</h3>
<ul>
<li>releases are scheduled and should not be fully automated</li>
<li>while feature branches are typically short lived, some stay unmerged for several weeks (e.g. a redesign) but need to be tested as well (currently as open pull requests to develop)</li>
<li>sometimes a single feature should be released outside the regular release, effectively turning it into a hotfix. With the current strategy I can rebase a feature branch and merge it directly into master</li>
<li>it also happens that we need to hold back features after acceptance tests with external systems on staging failed</li>
</ul>
<h3>Where I am not sure about the transition:</h3>
<ul>
<li>currently I am building pull requests for testing and merge commits for releases. Can I unify this?</li>
<li>how to deal with hotfixes when the master is ahead of the latest release. Should I build and deploy releases directly from hotfix branches?</li>
<li>is there a sensible way to deal with features that should be excluded from a release after they have already been merged? Is a separate develop branch really an advantage for these cases? Most of the time I end up reverting and re-reverting commits manually anyways.</li>
</ul>

CC BY-SA 3.0
2018-04-16T20:18:25.520Z
What about using the [GitHub Flow](https://guides.github.com/introduction/flow/)?
030
CC BY-SA 3.0
2017-03-02T12:58:01.360Z
It seems that on the one hand, you say you don't need the DEV branch, but then go on to explain why you really do need it.  Feature branches that live for weeks would be very difficult to merge to master after diverging for that long.  Are you *sure* you want to do away with DEV?
Dave Swersky
CC BY-SA 3.0
2017-03-02T13:05:57.947Z
@DaveSwersky good question! I am not sure, that's why I am asking here :) About long lived feature branches: the difficulty to merge is a problem that already exists and would just be moved to another place. And with regular merges back from the main branch it's doable. How would it be more difficult if the main branch is master?
Fabian Schmengler
CC BY-SA 3.0
2017-03-02T13:08:21.140Z
Long-lived branches will always be a challenge, though perhaps *more* of a challenge merging to master than to a DEV branch.  The solution to that problem may be to break the work apart better to keep those branches short-lived.  If you can prevent topic/feature branches from living more than 24-48 hours, you might have better luck eliminating DEV.
Dave Swersky
CC BY-SA 3.0
2017-03-02T13:32:28.400Z
@FabianSchmengler What is the real reason you want to remove the dev branch? It really sounds like you need it for cases when things don't go as planned.
avi
CC BY-SA 3.0
2017-03-03T18:48:59.533Z
call it master or develop or whatever you want, you will need an integration branch if you want to have real CI, or if you delegate it to the feature branches, it will only be outer integration of them against current release in isolation.
ᴳᵁᴵᴰᴼ
<git><release-management><builds><branch>
How to get rid of develop branch for simplified Git flow
Fabian Schmengler
# How to get rid of develop branch for simplified Git flow

(Asked by: username_0 on 2017-03-02)

In a continuously developed web project (not a product) we currently have the following branching strategy, roughly based on *git flow*:

* develop branch: latest working version
* master branch: version to be released / released version
* feature branches: features in development
* hotfix branches: urgent bugfixes in released version

**Master** is read only, updated via pull requests from **develop** or **hotfix branches**. Each update results in a release candidate being built and deployed to the staging system. Release candidates are deployed to production after manual approval.

**Feature branches** are created based off **develop**, or from the last commit that has been merged into master. A pull request from a feature branch to develop is built, deployed to a free test system where integration tests and acceptance tests (automatic & manual) are executed. When successfully tested and reviewed, the PR gets merged, so that it will become part of the next release (i.e. merge from develop to master).

## My goal

I would like to simplify this and get rid of the develop branch. The develop branch has mostly historical reasons and since it is always a successfully tested version, I think it is unnecessary to keep it separated from master. Removing it will also simplify the release process because there is no additional merge anymore.

### I have the following constraints:

* releases are scheduled and should not be fully automated
* while feature branches are typically short lived, some stay unmerged for several weeks (e.g. a redesign) but need to be tested as well (currently as open pull requests to develop)
* sometimes a single feature should be released outside the regular release, effectively turning it into a hotfix. With the current strategy I can rebase a feature branch and merge it directly into master
* it also happens that we need to hold back features after acceptance tests with external systems on staging failed

### Where I am not sure about the transition:

* currently I am building pull requests for testing and merge commits for releases. Can I unify this?
* how to deal with hotfixes when the master is ahead of the latest release. Should I build and deploy releases directly from hotfix branches?
* is there a sensible way to deal with features that should be excluded from a release after they have already been merged? Is a separate develop branch really an advantage for these cases? Most of the time I end up reverting and re-reverting commits manually anyways.

**Tags:** git, release-management, builds, branch

> **Comments:**
> **username_2**: It seems that on the one hand, you say you don't need the DEV branch, but then go on to explain why you really do need it.  Feature branches that live for weeks would be very difficult to merge to master after diverging for that long.  Are you *sure* you want to do away with DEV?  
> **username_0**: @DaveSwersky good question! I am not sure, that's why I am asking here :) About long lived feature branches: the difficulty to merge is a problem that already exists and would just be moved to another place. And with regular merges back from the main branch it's doable. How would it be more difficult if the main branch is master?  
> **username_2**: Long-lived branches will always be a challenge, though perhaps *more* of a challenge merging to master than to a DEV branch.  The solution to that problem may be to break the work apart better to keep those branches short-lived.  If you can prevent topic/feature branches from living more than 24-48 hours, you might have better luck eliminating DEV.  
> **username_3**: @FabianSchmengler What is the real reason you want to remove the dev branch? It really sounds like you need it for cases when things don't go as planned.  
> **username_4**: call it master or develop or whatever you want, you will need an integration branch if you want to have real CI, or if you delegate it to the feature branches, it will only be outer integration of them against current release in isolation.  
> **username_1**: What about using the [GitHub Flow](https://guides.github.com/introduction/flow/)?  

---

## 4 answers

### Answer by username_8 on 2017-03-31. Score: 8 | Accepted answer

IMHO the problems you're facing are just a side effect of the poor branch strategy you started with: you're effectively plowing new development on `develop` (i.e. what converges towards the *future* production code) **through** the *current* production code on `master`. This leads to contradicting requirements and problems since typicaly the future code diverges from the current one:

* the new development destabilizes production - regressions seen after merging `develop` into `master`
* stabilizing the production slows down future development - you need to stabilize `develop` to make it good enough for merging into `master`

Dropping `develop` won't help (much) - you're not eliminating the problem, you're just transferring the `develop`-specific portion of the problem into `master`.

A better approach would be to move the production **behind** the current/future development, to prevent interference with development for future releases, as illustrated in this image from [What is Your Branching Model?](http://paulhammant.com/2013/12/04/what_is_your_branching_model/):

> [![enter image description here](https://i.sstatic.net/7g9rx.png)](https://i.sstatic.net/7g9rx.png)

Please note that I'm only referring to the release branches in the above image, not on what's happening in the trunk.

How would this work for you:

* the `develop` branch dissapears, as you wished, absorbed into `master`
* the `master` branch is your trunk, this is where development happens with no speed restrictions (it's **never** merged into production).
* production is/are one or more `release` branches pulled from a `master` label/tag considered close enough to production quality (a short list of remaining todo items can be addressed in that branch if needed). These branches can only receive direct hot-fixes and/or cherry-picked fixes from `master`, they are **never** merged with `master` or other branches
* hotfixes are direct commits into `release` branches

If a hotfix applies only to a production version but not to the `master` it is directly committed to the `release` branch. If it applies to both it's typically committed to `master` first and cherry-picked/double-committed to the `release` branch as well.

Now looking at what goes into `master` (which is past the point where the current `release` branch is pulled off), you have 2 options:

* continue with feature branches just like you do today, except they'll be based off `master`, not `develop`. Converting them to hot fixes remains possible - you'd just have to rebase them to the corresponding `release` branch instead of `master`
* switch to continuous integration and reap its benefits (can be done at any time going forward), including in a progressive manner - gradually pull fewer and fewer feature branches.

If you like this approach here's how you get there from where you are today:

* establish a release naming strategy:
  + you can't have an ongoing release branch with the same name
  + you can't (shouldn't actually) rebase or sync a production release branch
* pull a `releaseX` branch from `master` immediately, following that naming strategy
* stop commits from going into `develop`, they'll be soon going straight to `master`.
* merge `develop` into `master`
* instruct developers to rebase their workspaces on `master` instead of `develop`.
* open `master` for commits
* delete `develop` if you desire (or leave it permanently locked/read-only for reference)

> **Comments:**
> **username_0**: Thank you for the detailed suggestions. I'm not sure yet if release branches are a good idea outside of product development, but I'll reconsider it, it could make sense for this project  
> **username_8**: You also have the continuous deployment alternative, which puts the development in the same place with the production (as opposed to pushing through or preceeding it), but for that you need a culture shift (as it implies dropping all integration and feature branches).  
> **username_6**: I recognize that diagram :)  
> **username_9**: I have a doubt about committing hotfixes in master first and then cherry-picking to release. Example - my manager asks for a hotfix. If I implement it on master and then pick it into a release branch, it can (by Murphy's law, master will have code changes that affect the hotfix) turn out to be incompatible with the state of the release branch. So, now I have to spend time on rewriting the hotfix specifically for the release branch and also explain to the manager why I couldn't fix the issue on the release branch first to deliver it ASAP, and later deal with fixing the hotfix to fit master.  
> **username_8**: @username_9: either order works just as well, the master and release branch(es) are totally independent. If you have incompatibilities, though, the hotfix is NOT equally applicable, it can't be cherry-picked.  
> **username_9**: I mean mostly from management perspective - release hotfixes should always have the highest priority, master branch can wait. So, if you have to develop a fix from scratch, it makes sense to implement straight in the release branch first, and only after that merge it back into master and deal with master branch consequences after the hotfix release branch has been tested and delivered.  

---

### Answer by username_7 on 2017-03-02. Score: 11

Let's say you take out the master branch (you can rename develop to master to confuse your team if you like later) and simply use tags for releases either on develop or hotfix branches. You took out a branch, but the difference is just a change in syntax. Change for change sake.

Now let's say you actually take out develop with keeping the locked master branch. What will happen is that integration of code will slow, it will live longer separated in feature branches, especially close to release dates. This will Increase the difficulty of merging each time and slow the process down.

Within the constraints you have laid down I don't see any positive effects of making such change. It would require relaxing the constraints, especially the first one.


---

### Answer by username_5 on 2017-03-02. Score: 5

You are already building and testing code on each of the pull-request and hot-fix branches. This means that in aggregate, the sum of all branches pending on pull-request are your virtual `develop` branch.

You can create a system when in a test environment, several pull-requests are cherry picked into a temporary branch that is not published to the main repository. This branch is used to integrate a test environment that includes `master` and several additional pull-requests, but once the testing is done, this branch is no longer available anywhere.

When you create a release from `master`, you would usually create a tag on that release. Later hotfixes can use that tag to create a new hotfix branch from which a deployment will be made, even though the edge of `master` is already ahead. On this hotfix branch you would probably also tag a minor release, and make sure that the changes were merged into `master`.

Removing merged features from a release is quite hard to do with git. The best mechanism for this would be to use `git revert` on the merge commit. But that makes it almost impossible to get these features/changes back, and history becomes all muddled.

A much better way to handle separation for deployment of code, and release of features, is *feature flags*. If your developers can hide their features behind some conditions in the code itself, you could deploy their code, but turn off the feature. This is a separate topic, but a lot of information about this exists (including a Q&A on devops.SE).


---

### Answer by username_6 on 2017-04-01. Score: 3

Well @dan-cornilescu says it well for your particular problem, but the more general case for Trunk-Based Development (mentioned in the Continuous Delivery, Lean Enterprise, and The DevOps Handbook) is made here: <https://trunkbaseddevelopment.com/>


---

