Git-flow
Git-flow was described by Vincent Driessen on his 2010 post A successful Git branching model. I’ve found it to be a great way to organize a repository. In short, you:
- Keep your master branch as the code that has been released,
- Use a develop branch as the current “snapshot” of what will go into the next release - your living beta,
- Spawn off feature branches off develop for every new feature, which are merged back into it when they’re ready,
- When you are ready to release, you merge to master and tag with a release version.
There are other considerations for how to deal with hotfixes, but that’s the gist of it. You can see a git-flow diagram below:
This is a great approach and it has several advantages:
- master always remains as a stable reflection of your live code,
- You can trivially do hotfixes without worrying about unfinished features,
- Feature branches ensure that teams working in parallel don’t trip over each other and that conflicts need to be handled only once (the moment the feature is done),
- It allows teams to cherry-pick changes other teams may be doing on their feature branches, without needing these commits to be on develop already,
- It lets you do a release off develop at any point - if a feature isn’t ready, that’s OK, you just leave it for the next release.
There are helper scripts to assist you with Gitflow. Atlassian’s SourceTree supports it directly as well.
Github-flow
Proponents of Github-flow (and its cousin Gitlab-flow) have a few complaints about it. The main argument is that it goes against continuous delivery, since at some point someone needs to “flip a switch” and do a release from develop into master.
That’s a valid argument. Nothing is less continuous than manual switch-flipping.
The Github-flow proposal is that you should:
- Do away with the develop branch altogether,
- Spawn all feature branches off master, and merge them back into master when ready,
- Version tagging should not be carried by a human, but by an automated process whenever code is pushed to live,
These are valid points and they do result on a lighter-weight workflow. But they ignore that there are cases where you want a manual release, a negotiation of what is supposed to go into any particular version.
My take on it
Both systems have their uses. I think something like Github-flow is a great approach if what you are developing is an application. On that case, just using a master branch plus features branches works well, and you can do your releases in an automated fashion. The deployment itself is the atomic end-product you care about.
When you are building a library, where people outside your team might depend on specific versions, I think git-flow is the right approach. For a library, you want to lump your versioned changes together into a conceptual unit - including potentially separating or delaying breaking changes. At this point, coming to an agreement on what should go into a version makes sense, as does the manual release process of git-flow.
If anybody outside of your team depends on your versioning scheme, or will need to have a clear conceptual overview of what changed on a particular release, I’d recommend using git-flow.
If whatever you are releasing is the final artifact, and it will be used but others will not need to reference its version, then GitHub-flow does the trick.
Top comments (0)