Git/Branch-Per-Feature – Composable Deployments/Releases?

Now that I’m starting to use Git a lot more, I’ve been thinking about and starting to use branch-per-feature a little bit. This morning I had a term pop into my head as I was thinking about branch-per-feature: “Composable Deployments/Releases”. Now I’m still getting the hang of this whole branch-per-feature thing, so this might be old hat for a lot of you, but I noticed something in some of my recent work with Git and how my workflow was starting to shape up. Here is an example of how using Git and Branch-Per-Feature is starting to make my life easier.

Disclaimer

I’ve only been using Git for a couple weeks, so go easy on me…

Life With Subversion

I manage my church’s web site and have used subversion for managing the code for a long time. As I’m working on new projects for this web site, I deploy them to a “staging” site that is used to review and test out new changes with our Pastors and ministry leaders. In the meantime, small changes and content updates get done and deployed to “production” in parallel to these new, larger projects that get pushed to “staging”. One of the issues I’ve always had is how to easily work on these new projects separately and deploy new features in isolation from one another. Using the typical trunk/branches style of subversion, I’ve always done most work directly in trunk and sometimes creating branches for larger projects. Unfortunately trying to do this with subversion is Not Fun(TM). Also this made it tough to separate “staging” deployments from “production” ones. Of course I could have managed environment-specific branches in subversion and done the merging dance with subversion, but again, Not Fun(TM).

Enter Git

I’ve been using Git for a couple weeks locally to manage local branches for my “day job”, where we still use subversion as our main VCS (for now…muwhahaha ). But for my church site I decided to make the full move to use Git with Beanstalk [http://beanstalkapp.com], which is where I’ve been doing my subversion hosting for a while now. Beanstalk just recently added Git support and so far it’s working out great.
One of the first things I noticed as I started using Git was how easy it is to branch and merge code. So I figured I’d try out this whole Branch-Per-Feature [http://www.lostechies.com/blogs/derickbailey/archive/2009/07/15/branch-per-feature-source-control-introduction.aspx] thing all the cool kids are talking about these days. Needless to say I’m liking it a lot.

Ok, so getting to the point of this post, here is a peek at the branches I’m managing right now:

master (gets deployed to production)

staging (environment branch used to push to a staging site)

faith (feature branch for a new statement of faith page)

visitors (feature branch for a new visitors page)

<insert other temporary branches here for one-off changes that get merged into master and deployed>

One of the things I *really* like about this is that I can keep work nice and isolated in feature branches and easily merge them as needed into the appropriate environment-specific branch (staging or master) when it’s ready to be deployed. My current workflow is something like this:

The way I’m treating the staging branch is mainly as a “merge and deploy” branch. I’m not usually making any direct changes in the staging branch. So, in theory, once the feature in the faith branch is tested and ready for to be deployed to production, I could just merge that feature branch straight into master and then do my normal production deployment. This seems like a really nice way to work. That’s why I called it “composable deployments/releases” because it’s really nice to be able to “compose” a deployment simply by merging in the appropriate feature branches as needed.

I’m still a Git n00b for the most part, so I’d be very interested in your feedback and improvements. I’m sure my thoughts on this will change the more I learn and use Git, but so far this is really working for me quite well.

We’ve certainly seen benefits from approaching Git this way, especially as we also have TeamCity labelling builds for us.

The upshot is that if we have a problem with the deployed version (version number embedded in the dll) we can create a hotfix branch from that specific build without affecting any of our feature/master/staging branches.

The branch-per-feature approach also does a good job of ensuring developers work in a modular fashion rather than a scatter-gun, change twenty things at once assault on the code!

One thing I miss from your setup is a long-running ‘development’ branch. I use this branch to branch off features and then merge them back into the ‘development’ branch. We then keep development and master as the common branches pushed/pulled among developers. Staging seems to be serving that purpose for you, but I prefer the methodology in this post: http://nvie.com/git-model , where releases are in a separate branch for the release, which is then merged back into development and master.

Dugald,
Wow, that is a great article! Thanks! That model looks very attractive. I have thought about a using a long running “dev” branch somehow, but wasn’t sure how best to fit it into the flow. This helps explain it a lot.

Yes, that article does a great a job outlining how things fit together. We use it, and then branch per feature, merging back into develop. Then, other developers can just pull from develop and do the same. I also like master as always having stable releases and being the goto for that. Then, everything else is fluid and temporary.

This is largely the same pattern my current team is using with Subversion; we have a build branch off the trunk that maps to your staging branch and we branch feature branches off the build branch then merge back into the build branch as they are ready to deploy to stage for testing.

That said, I think most of those branches and merges would go much faster and more smoothly w/ git than w/ svn.