193

We have a web app that we update and release almost daily. We use git as our VCS, and our current branching strategy is very simple and broken: we have a master branch and we check changes that we 'feel good about' into it. This works, but only until we check in a breaking change.

Does anyone have a favorite git branch strategy for small teams which meets the following requirements:

  1. Works well for teams of 2 to 3 developers
  2. Lightweight, and not too much process
  3. Allows devs to isolate work on bug fixes and larger features with ease
  4. Allows us to keep a stable branch (for those 'oh crap' moments when we have to get our production servers working)

Ideally, I'd love to see your step-by-step process for a dev working on a new bug

Bilal and Olga
  • 3,211
  • 6
  • 30
  • 33

6 Answers6

252

You might benefit from the workflow Scott Chacon describes in Pro Git. In this workflow, you have two branches that always exist, master and develop.

master represents the most stable version of your project and you only ever deploy to production from this branch.

develop contains changes that are in progress and may not necessarily be ready for production.

From the develop branch, you create topic branches to work on individual features and fixes. Once your feature/fix is ready to go, you merge it into develop, at which point you can test how it interacts with other topic branches that your coworkers have merged in. Once develop is in a stable state, merge it into master. It should always be safe to deploy to production from master.

Scott describes these long-running branches as "silos" of code, where code in a less stable branch will eventually "graduate" to one considered more stable after testing and general approval by your team.

Step by step, your workflow under this model might look like this:

  1. You need to fix a bug.
  2. Create a branch called myfix that is based on the develop branch.
  3. Work on the bug in this topic branch until it is fixed.
  4. Merge myfix into develop. Run tests.
  5. You discover your fix conflicts with another topic branch hisfix that your coworker merged into develop while you were working on your fix.
  6. Make more changes in the myfix branch to deal with these conflicts.
  7. Merge myfix into develop and run tests again.
  8. Everything works fine. Merge develop into master.
  9. Deploy to production from master any time, because you know it's stable.

For more details on this workflow, check out the Branching Workflows chapter in Pro Git.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Jimmy
  • 35,686
  • 13
  • 80
  • 98
  • 7
    Also Scott Chacon has an excellent article on his site on how Github's workflow with Git works - http://scottchacon.com/2011/08/31/github-flow.html – program247365 Dec 29 '11 at 21:51
  • 1
    @program247365 that link is awesome (it should be it's own answer). It's really simple, and if it's good enough for GitHub's 35 employees, it's good enough for me :) – Dustin Boswell Jun 27 '12 at 06:50
  • @DustinBoswell Ok, made it, it's own answer: http://stackoverflow.com/a/11994209/5716 – program247365 Aug 16 '12 at 19:35
  • 75
    I think this is great, except if you create bug fix branches from the develop branch, you are forcing you can't merge it into master and deploy it without also merging in everything else "new" that you've not released yet, which might be a real pain if there is something in that branch that needs documenting / database changes or something else hard to do. I think for urgent "hotfixes", you should make your branch from master. – Richard Sep 01 '12 at 07:45
  • 2
    I can backup Stony's comment with practical experience that this happens more often than you'd hope. Even features can run into this problem if you start work after someone else's has begun merging for QA. You can take the branch at the previous release cut, but in practice not all developers remember. – Luke Puplett Jul 12 '13 at 16:30
  • 6
    What if we are developing 2 separate features, F1 and F2, where F1 is to be released in a week but F2 is to be released in 2 weeks, assuming that the development of F1 and F2 coincide? Any suggestions on that? – Murat Derya Özen Oct 03 '13 at 18:06
  • 1
    Create a branch F1 out of develop, create another branch F2 out of develop branch. Both developers can work on their respective branch with the F2 developer frequently pulling updates from F1. – ziggy Jun 19 '16 at 10:21
  • 5
    The `develop` is an unecessary 'solution' to a problem that git doesn't have. As far as I can tell the success is due to a well written if misguided article with no comments allowed. Here's a counter-article https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/ – Tim Abell Oct 28 '16 at 16:36
  • This doesn't work if you need to maintain multiple versions of a product. – BartoszKP Jan 13 '17 at 13:32
  • 7
    At step 8, merging the develop branch into master sounds like a bad idea given that some of the code in develop might not be ready to go into production. Wouldn't we be better off merging the feature branch into master? – Todd Feb 28 '17 at 19:58
  • @program247365 From the blog (2011): _"That is the entire flow. It is very simple, very effective and works for fairly large teams - GitHub is **35** employees now, maybe 15-20 of whom work on the same project (github.com) "_ - Currently, Wikipedia lists GitHub as having 745!!! – Nicolas Miari Feb 22 '18 at 04:04
47

After coming in as a novice trying to find a straight-forward strategy to teach to other devs who have never used source control. This is the one that fit http://nvie.com/posts/a-successful-git-branching-model/ I tried using the standard GIT workflow thats in the man pages but it confused me slightly and my audience completely.

Over the past 6 months I have only had to fix conflicts twice. I have added steps to always test after a merge and to 'fetch and merge" or 'pull --rebase" a lot (once in the morning and in the afternoon) while developing features. We also used github.com as the central place to pull the latest code.

Clutch
  • 7,404
  • 11
  • 45
  • 56
  • That is an excellent link! That workflow works superbly well for our small team who always work remotely and parallelly on multiple release versions at a time. Very well documented. Thanks Clutch! – keithxm23 Sep 27 '12 at 14:50
  • Ah, so this is where I found that link :-) I looked at several Git strategies before setting up my first Git project (I have moved from SCCS to CVS to SVN over the years and now I wanted to try Git for a new project) and this was the one that made the most sense to me. I recognize your post so I'm pretty sure this is where I found it. So Thanks - it works wonderfully well! – Boise Jul 20 '13 at 22:42
  • 5
    I die a little inside everytime I see someone pick up that blog post. Here's a rebuttal: https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/ – Tim Abell Oct 28 '16 at 16:30
  • I share the same feeling with you @TimAbell; I strongly feel it not right when the `default master branch` is NOT used the most often be developer in this `A successful Git branching model` – Nam G VU Nov 21 '16 at 09:07
35

(Made my comment above it's own answer, as I should have initially.)

From Scott Chacon of Github:

How We Do It So, what is GitHub Flow?

  • Anything in the master branch is deployable
  • To work on something new, create a descriptively named branch off of master (ie: new-oauth2-scopes)
  • Commit to that branch locally and regularly push your work to the same named branch on the server
  • When you need feedback or help, or you think the branch is ready for merging, open a pull request
  • After someone else has reviewed and signed off on the feature, you can merge it into master
  • Once it is merged and pushed to ‘master’, you can and should deploy immediately

See the entire article for more details: http://scottchacon.com/2011/08/31/github-flow.html

Note that "pull requests" are a Github invention, and it's something that's baked into their website, not Git itself: https://help.github.com/articles/using-pull-requests/

Community
  • 1
  • 1
program247365
  • 3,951
  • 7
  • 33
  • 44
  • 4
    With a smaller team and devs less experienced with git, this workflow's simplicity wins out. The only thing we do differently is having a 'staging' branch between the feature branch and master that acts as a live QA site for non devs to okay the feature in a production like environment. – Squadrons Mar 09 '15 at 16:50
  • @Squadrons sounds like you need [octopus deploy](https://octopus.com/) for that, that has gates built in to ok/deny builds getting onto different environments and doesn't pollute your source control with such things. – Tim Abell Oct 28 '16 at 16:32
  • Creating feature branches off of master and then merging them back in for deployment is OK, so long as you have a tag so there's a safe rollback point. Deployments don't always go according to plan. Whether you believe in "roll forward only" doesn't matter much when you're haemorrhaging money. – Razor Jan 18 '17 at 12:52
16

Use the master branch as your development branch and create release branches for performing bug fixes.

Any new features will go on master during the development window (either committed directly or as topic branches with pull-requests, up to you -- not shown in graphic). Once all your planned features are implemented, enter feature freeze, and perform testing. When you're happy, tag the release on master as v1.0.

Over time your users will find bugs in v1.0 so you'll want to create a branch from that tag (e.g. name it after the release 1.0) and fix those bugs in the branch. When you've got enough bugs fixed that you think it warrants a new release then tag it as v1.0.1 and merge it back into master.

Meanwhile a new development window can be happening on the master branch which will eventually be tagged as v1.1.

Rinse & repeat.

This follows Semantic Versioning numbering logic.

 ---------(v1.0)--------------------------------(v1.1)-----------------------------> master
             \                                     \  
              ---(v1.0.1)---(v1.0.2)---> 1.0        ---(v1.1.1)---(v1.1.2)---> 1.1
Leif Gruenwoldt
  • 13,561
  • 5
  • 60
  • 64
  • 5
    Don't forget to merge your `1.0.1` changes back into `master` – kwahn Oct 23 '15 at 16:08
  • 1
    And always keep in mind to rebase `1.1` on master after merging `1.0.1` - this helps minimize confiction. – Nam G VU Nov 21 '16 at 09:00
  • @NamGVU I wouldn't recommend that. `1.1` is a release branch and has tags representing the exact state of one or more releases. Rebasing that branch would cause you to lose that representation. I'd strongly recommend setting your release branches to deny force pushes to prevent this. – Leif Gruenwoldt Nov 22 '16 at 00:23
  • 1
    No. Don't merge release branches back into master! It can give you all sorts of headaches that you do not need (merging in release-only stuff, merge conflicts with newer releases, breaking builds, non-linear history, etc. Believe me, I've seen it happen more than once). Instead, treat releases as forks. See http://www.bitsnbites.eu/a-stable-mainline-branching-model-for-git/ – m-bitsnbites Dec 29 '16 at 08:47
  • 5
    cherry-pick is a better option for retrieving release changes into master – BartoszKP Jan 13 '17 at 13:41
4

In a VCS, having just a "master" branch shows quickly its limits because you cannot pursue all the development effort at the same time on one branch.
That means you need to know when to branch.

But in a DVCS (as in "Decentralized" VCS), you also have a publication issue, with branches you keep local to your repositories, and branches you are pushing to or pulling from.

In this context, start by identifying your concurrent development effort, and decide on a publication (push/pull) process. For instance (and this is not the only way):

  • prod is a read-only public branch with the code in production. Everyone could pull from it in order to:
    • rebase its current development on top of it (for local testing, or for integrating on the local dev repo a hotfix done in the prod repo on the prod branch)
    • branch to do new features (from a known stable code)
    • branch to start the next release branch (the one which is to be in production)
      no one should push directly to prod (hence the read-only)
  • release is a read-write consolidation branch, where the relevant commits are cherry-picked to be part of the next release.
    Everyone can push to release to update the next release.
    Everyone can pull from said release in order to update his/her local consolidation process.
  • featureX is a private read-write branch (in that it does not need to be push to the central prod repo), and can be pushed/pulled between dev repos. It represents middle to long term effort, different from the daily dev
  • master represents the current dev, and is pushed/pulled between the dev repos.

Other release management processes exist, as this SO question attests.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
3

Read through ReinH's Git Workflow for Agile teams here: http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html

This works very well for small teams. The goal here is to make sure everything that might be potentially unstable goes in to a branch of some kind. Only merge back to master when you are ready for everyone working outside of the feature branch to use it.

Note: this strategy is hardly git specific, but git makes implementing this strategy pretty easy.

whaley
  • 16,075
  • 10
  • 57
  • 68