Yeah, I know. The workflow in Git, as in any DVCS, is something to be taken seriously. Once your whole team is fluid in branching, merging and rebasing you are ready for a full blown Git workflow like git-flow, or the GitHub flow described by Scott Chacon.
But what if you project is small, and / or you've just migrated from SVN and are still trying to figure it all out, and / or you just don't want a model so complicated?
What would be a good starting point? If you need to, lets say:
- commit or merge code into a main branch with CI
- regularly set milestones for deployment in a QA or staging server
- from time to time release a production version - that's what you are paid for, after all
- do some maintenance and bug fixing on the released code.
After some research and some practice we choosed the following minimalistic workflow to solve those four needs.
1. The master branch is the place where all developers integrate their code.
This may be done:
- By committing their code directly into the master branch - when working in small teams or for small incremental changes.
- On a separate feature or develop branch that is later merged into master - when the circumstances require it.
CI tests should be running on this branch.
2. A fast-forward-only qa branch acts as a "sliding tag" following closely the master head.
This allows you to set temporary marks that will be used for deploying in a QA or staging environment. Some of them will later turn into releases - see the following section.
3. A series of annotated version tags signal each release that will go into production.
The version tag for a release (i.e. v188.8.131.52) is always placed on the commit at the current head of the qa branch (not from the master branch, which may be ahead of the last quality assured build).
Note that in this model, only an annotated tag is initially required for deploying a release into production. Only later, if required, a dedicated branch will be created from this tag.
4. Dedicated branches are created for each release that requires maintenance or fixes.
On early stages of an application development , releases may occur quite frequently and most of the times they will not be updated with fixes - the fix will be included in the next full release from the master / qa branches.
In these cases, the version tag mentioned in section 3 will be enough.
However, when the app or site is in production and releases tend to be more sporadic, the requirements for fixes on the released version are quite common. On the first occasion that a fix is required on a newly created version - initially defined only by a tag - a dedicated branch for that specific release should be created (i.e. release1.0.2)
Each fix release for this major version will be created on the same dedicated branch, and will get a separate tag (i.e. v184.108.40.206, v220.127.116.11, ...)
Changes on the release branch may be merged back - as a whole or cherry picked - into the master tag; never into the qa branch that is following the master in a fast-forward way.
The next full release (i.e. v18.104.22.168) will be created as a version tag on the main qa branch, and later branched from there, if necessary.
My friend Benjamin Eidelman was a key participant in the discussion and contributed many of the basic ideas behind this post.