It's been 4.5 years now since Vincent Driessen published his thought-provoking article on git branching workflows: A successful Git branching model.
In a slight conflation of names, Driessen's workflow model has been known by the name of a toolset that he also contributed, which helps implement the model: git-flow.
In the years since, there have been a wealth of variations, elaborations, and alternatives tossed into the ring. Reading them is a fascinating way to keep up with the ongoing debate about how teams work, and about how their tools can help them work.
- A successful Git branching model
We consider origin/master to be the main branch where the source code of HEAD always reflects a production-ready state.
We consider origin/develop to be the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. Some would call this the “integration branch”. This is where any automatic nightly builds are built from.
When the source code in the develop branch reaches a stable point and is ready to be released, all of the changes should be merged back into master somehow and then tagged with a release number. How this is done in detail will be discussed further on.
Therefore, each time when changes are merged back into master, this is a new production release by definition. We tend to be very strict at this, so that theoretically, we could use a Git hook script to automatically build and roll-out our software to our production servers everytime there was a commit on master.
- Why Aren't You Using git-flow?
I’m astounded that some people never heard of it before, so in this article I’ll try to tell you why it can make you happy and cheerful all day.
- git-flow Cheatsheet
Git-flow is a merge based solution. It doesn't rebase feature branches.
- Issues with git-flow
At GitHub, we do not use git-flow. We use, and always have used, a much simpler Git workflow.
Its simplicity gives it a number of advantages. One is that it’s easy for people to understand, which means they can pick it up quickly and they rarely if ever mess it up or have to undo steps they did wrong. Another is that we don’t need a wrapper script to help enforce it or follow it, so using GUIs and such are not a problem.
- On DVCS, continuous integration, and feature branches
The larger point I’m trying to make is this. One of the most important practices that enables early and continuous delivery of valuable software is making sure that your system is always working. The best way for developers to contribute to this goal is by ensuring they minimize the risk that any given change they make to the system will break it. This is achieved by keeping changes small, continuously integrating them into mainline, and making sure there is a comprehensive suite of automated tests to verify that changes behave as expected and don’t introduce any regressions.
- My Current Java Workflow
I then setup a Jenkins job called “module-example snapshot”. This checks out any pushes to the develop branch, runs the gradle build task on it (which runs tests and produces artifacts on successful test passes) and then pushes a snapshot release to our in house artifactory server. This means any push to develop will trigger a build that releases a snapshot jar of that module that others could use for their development.
- GitFlow and Continuous Integration
So, what does one do with this information? Is use of GitFlow or promiscuous integration a bad idea? I think that it can work very well for some teams and could be very dangerous in others. In general, I like it when the VCS stays out of the way and the team gets in the habit of pushing changes and looking to the CI server validation that everything is ok. Introducing promiscuous integration could interrupt this cycle and allow code changes to circumvention the mainline longer than they should. This branching scheme feels complex, even with the addition of GitFlow.
- Another Git branching model
But cheap merging is not enough, you also need to be able to easily pick what to merge. And with Git Flow it’s not easy to remove a feature from a release branch once it’s there. Because a feature branch is started from develop it is bound by its parents commits to other features not yet in production. As a result, if you merge a feature without rebasing you always get more commits than wanted.
- Branch-per-Feature
Most of this way of working started from the excellent post called “A Successful Git Branching Model”. The important addition to this process is the idea that you start all features in an iteration from a common point. This would be what you released for the last one. This drives home the granular, atomic, flexible nature that features must exhibit for us to deliver to business in the most effective way. Git flow allows commits to be done on dev branches. This workflow does not allow that.
- git bugfix branches: choose the root wisely
The solution I like best involves first finding the commit that introduced the bug, and then branching from there. A command that is invaluable for this is git blame. It is so useful, I would recommend learning it right after commit, checkout, and merge. The resulting repository now looks like Figure 3, where we have found the source of the bug deep inside the development history.
- Some thoughts on continuous integration and branching management with git
Given a stable/production branch P, and a set of feature branches, say, FB1, FB2 and FB3, I want a system that:
- Combines (merge) P with every branch and test it, say P + FB1, P + FB2, P + FB3.
- Select the successful branches and try to merge them together. Say FB2 failed, so we would try to build and test P + FB1 + FB3 and make it a release candidate.
- Should a conflict appear, notify the developers so they can fix it.
- The conflict resolution is saved so not to happen again.
- The process is repeated continuously.
- A (Simpler) Successful Git Branching Model
At my work, we have been using a Git branching strategy based on Vincent Driessen’s successful Git branching model. Over all, the strategy that Vincent proposes is very good and may work perfectly out of the box for many cases. However, since starting to use it I have noticed a few problems as time goes on
- Two Git Branching Models
In current projects, we tend to float between two branching models depending on the requirements of the customer / project and the planned deployment process.
- Git Branching Model
A workflow for contributions is usually based on topic branches. Instead of committing to the particular version branch directly, a separate branch is made for a particular feature or bugfix where that change can be developed in isolation. When ready, that topic branch is then merged into the version branch.
- What is Your Branching Model?
Perforce from the middle 90’s and Subversion from 2001 promoted a trunk model, although neither preclude other branching models. Google have the world biggest Trunk-Based-Development setup, although some teams there are going to say they are closer to Continuous Deployment (below). Facebook are here too.
- Git Tutorials: Git Workflows
The array of possible workflows can make it hard to know where to begin when implementing Git in the workplace. This page provides a starting point by surveying the most common Git workflows for enterprise teams.
As you read through, remember that these workflows are designed to be guidelines rather than concrete rules. We want to show you what’s possible, so you can mix and match aspects from different workflows to suit your individual needs.
- Git Branching - Branching Workflows
Now that you have the basics of branching and merging down, what can or should you do with them? In this section, we’ll cover some common workflows that this lightweight branching makes possible, so you can decide if you would like to incorporate it into your own development cycle.
No comments:
Post a Comment