Git Common-Flow 1.0.0-rc.5 + +Introduction +Common-Flow is an attempt to gather a sensible selection of the most common +usage patterns of git into a single and concise specification. It is based on +the original variant +of GitHub Flow, while taking +into account how a lot of open source projects most commonly use git. +In short, Common-Flow is essentially GitHub Flow with the addition of versioned +releases, optional release branches, and without the requirement to deploy to +production all the time. +Summary + +The “master” branch is the mainline branch with latest changes, and must not +be broken. +Changes (features, bugfixes, etc.) are done on “change branches” created from +the master branch. +Rebase change branches early and often. +When a change branch is stable and ready, it is merged back in to master. +A release is just a git tag who’s name is the exact release version string +(e.g. “2.11.4”). +Release branches can be used to avoid change freezes on master. They are not +required, instead they are available if you need them. + +Terminology + +Master Branch - Must be named “master”, must always have passing tests, +and is not guaranteed to always work in production environments. +Change Branches - Any branch that introduces changes like a new feature, a +bug fix, etc. +Source Branch - The branch that a change branch was created from. New +changes in the source branch should be incorporated into the change branch via +rebasing. +Merge Target - A branch that is the intended merge target for a change +branch. Typically the merge target branch will be the same as the source +branch. +Pull Request - A means of requesting that a change branch is merged in to +its merge target, allowing others to review, discuss and approve the changes. +Release - May be considered safe to use in production environments. Is +effectively just a git tag named after the version of the release. +Release Branches - Used both for short-term preparations of a release, and +also for long-term maintenance of older version. + +Git Common-Flow Specification (Common-Flow) +The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, +“SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be +interpreted as described in RFC 2119. + +TL;DR + +Do not break the master branch. +A release is a git tag. + + +The Master Branch + +A branch named “master” MUST exist and it MUST be referred to as the +“master branch”. +The master branch MUST always be in a non-broken state with its test +suite passing. +The master branch IS NOT guaranteed to always work in production +environments. Despite test suites passing it may at times contain +unfinished work. Only releases may be considered safe for production use. +The master branch SHOULD always be in a “as near as possibly ready for +release/production” state to reduce any friction with creating a new +release. + + +Change Branches + +Each change (feature, bugfix, etc.) MUST be performed on separate +branches that SHOULD be referred to as “change branches”. +All change branches MUST have descriptive names. +It is RECOMMENDED that you commit often locally, and that you try and +keep the commits reasonably structured to avoid a messy and confusing git +history. +You SHOULD regularly push your work to the same named branch on the +remote server. +You SHOULD create separate change branches for each distinctly different +change. You SHOULD NOT include multiple unrelated changes into a single +change branch. +When a change branch is created, the branch that it is created from +SHOULD be referred to as the “source branch”. Each change branch also +needs a designated “merge target” branch, typically this will be the same +as the source branch. +Change branches MUST be regularly updated with any changes from their +source branch. This MUST be done by rebasing the change branch on top of +the source branch. +After updating a change branch from its source branch you MUST push the +change branch to the remote server. Due to the nature of rebasing, you +will be required to do a force push, and you MUST use the +“—force-with-lease” git push option when doing so instead of the regular +“—force”. +If there is a truly valid technical reason to not use rebase when +updating change branches, then you can update change branches via merge +instead of rebase. The decision to use merge MUST only be taken after all +possible options to use rebase have been tried and failed. People not +understanding how to use rebase is NOT a valid reason to use merge. If +you do decide to use merge instead of rebase, you MUST NOT use a mixture +of both methods, pick one and stick to it. + + +Pull Requests + +To merge a change branch into its merge target, you MUST open a “pull +request” (or equivalent). +The purpose of a pull request is to allow others to review your changes +and give feedback. You can then fix any issues, complaints, and more that +might arise, and then let people review again. +Before creating a pull request, it is RECOMMENDED that you consider the +state of your change branch’s commit history. If it is messy and +confusing, it might be a good idea to rebase your branch with “git rebase +-i” to present a cleaner and easier to follow commit history for your +reviewers. +A pull request MUST only be merged when the change branch is up-to-date +with its source branch, the test suite is passing, and you and others are +happy with the change. This is especially important if the merge target +is the master branch. +To get feedback, help, or generally just discuss a change branch with +others, it is RECOMMENDED you create a pull request and discuss the +changes with others there. This leaves a clear and visible history of +how, when, and why the code looks and behaves the way it does. + + +Versioning + +A “version string” is a typically mostly numeric string that identifies a +specific version of a project. The version string itself MUST NOT have a +“v” prefix, but the version string can be displayed with a “v” prefix to +indicate it is a version that is being referred to. +The source of truth for a project’s version MUST be a git tag with a name +based on the version string. This kind of tag MUST be referred to as a +“release tag”. +It is OPTIONAL, but RECOMMENDED to also keep the version string +hard-coded somewhere in the project code-base. +If you hard-code the version string into the code-base, it is RECOMMENDED +that you do so in a file called “VERSION” located in the root of the +project. But be mindful of the conventions of your programming language +and community when choosing if, where and how to hard-code the version +string. +If you are using a “VERSION” file in the root of the project, this file +MUST only contain the exact version string, meaning it MUST NOT have a +“v” prefix. For example “v2.11.4” is bad, and “2.11.4” is good. +It is OPTIONAL, but RECOMMENDED that that the version string follows +Semantic Versioning (http://semver.org/). + + +Releases + +To create a new release, you MUST create a git tag named as the exact +version string of the release. This kind of tag MUST be referred to as a +“release tag”. +The release tag name can OPTIONALLY be prefixed with “v”. For example the +tag name can be either “2.11.4” or “v2.11.4”. It is however RECOMMENDED +that you do not use a “v” prefix. You MUST NOT use a mixture of “v” +prefixed and non-prefixed tags. Pick one form and stick to it. +If the version string is hard-coded into the code-base, you MUST create a +“version bump” commit which changes the hard-coded version string of the +project. +When using version bump commits, the release tag MUST be placed on the +version bump commit. +If you are not using a release branch, then the release tag, and if +relevant the version bump commit, MUST be created directly on the master +branch. +The version bump commit SHOULD have a commit message title of “Bump +version to VERSION”. For example, if the new version string is “2.11.4”, +the first line of the commit message SHOULD read: “Bump version to +2.11.4” +It is RECOMMENDED that release tags are lightweight tags, but you can +OPTIONALLY use annotated tags if you want to include changelog +information in the release tag itself. +If you use annotated release tags, the first line of the annotation +SHOULD read “Release VERSION”. For example for version “2.11.4” the first +line of the tag annotation SHOULD read “Release 2.11.4”. The second line +MUST be blank, and the changelog MUST start on the third line. + + +Short-Term Release Branches + +Any branch that has a name starting with “release-” SHOULD be referred to +as a “release branch”. +Any release branch which has a name ending with a specific version +string, MUST be referred to as a “short-term release branch”. +Use of short-term release branches are OPTIONAL, and intended to be used +to create a specific versioned release. +A short-term release branch is RECOMMENDED if there is a lengthy +pre-release verification process to avoid a code freeze on the master +branch. +Short-term release branches MUST have a name of “release-VERSION”. For +example for version “2.11.4” the release branch name MUST be +“release-2.11.4”. +When using a short-term release branch to create a release, the release +tag and if used, version bump commit, MUST be placed directly on the +short-term release branch itself. +Only very minor changes should be performed on a short-term release +branch directly. Any larger changes SHOULD be done in the master branch, +and SHOULD be pulled into the release branch by rebasing it on top of the +master branch the same way a change branch pulls in updates from its +source branch. +After a release tag has been created, the release branch MUST be merged +back into its source branch and then deleted. Typically the source branch +will be the master branch. + + +Long-term Release Branches + +Any release branch which has a name ending with a non-specific version +string, MUST be referred to as a “long-term release branch”. For example +“release-2.11” is a long-term release branch, while “release-2.11.4” is a +short-term release branch. +Use of long-term release branches are OPTIONAL, and intended for work on +versions which are not currently part of the master branch. Typically +this is useful when you need to create a new maintenance release for a +older version. +A long-term release branch MUST have a name with a non-specific version +number. For example a long-term release branch for creating new 2.9.x +releases MUST be named “release-2.9”. +Long-term release branches for maintenance releases of older versions +MUST be created from the relevant release tag. For example if the master +branch is on version 2.11.4 and there is a security fix for all 2.9.x +releases, the latest of which is “2.9.7”. Create a new branch called +“release-2.9” from the “2.9.7” release tag. The security fix release will +then end up being version “2.9.8”. +To create a new release from a long-term release branch, you MUST follow +the same process as a release from the master branch, except the +long-term release branch takes the place of the master branch. +A long-term release branch should be treated with the same respect as the +master branch. It is effectively the master branch for the release series +in question. Meaning it MUST always be in a non-broken state, MUST NOT be +force pushed to, etc. + + +Bug Fixes & Rollback + +You MUST NOT under any circumstances force push to the master branch or +to long-term release branches. +If a change branch which has been merged into the master branch is found +to have a bug in it, the bug fix work MUST be done as a new separate +change branch and MUST follow the same workflow as any other change +branch. +If a change branch is wrongfully merged into master, or for any other +reason the merge must be undone, you MUST undo the merge by reverting the +merge commit itself. Effectively creating a new commit that reverses all +the relevant changes. + + +Git Best Practices + +All commit messages SHOULD follow the Commit Guidelines and format from +the official git +documentation: +https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines +You SHOULD never blindly commit all changes with “git commit -a”. It is +RECOMMENDED you use “git add -i” or “git add -p” to add individual +changes to the staging area so you are fully aware of what you are +committing. +You SHOULD always use “—force-with-lease” when doing a force push. The +regular “—force” option is dangerous and destructive. More +information: +https://developer.atlassian.com/blog/2015/04/force-with-lease/ +You SHOULD understand and be comfortable with +rebasing: https://git-scm.com/book/en/v2/Git-Branching-Rebasing +It is RECOMMENDED that you always do “git pull —rebase” instead of “git +pull” to avoid unnecessary merge commits. You can make this the default +behavior of “git pull” with “git config —global pull.rebase true”. +It is RECOMMENDED that all branches be merged using “git merge —no-ff”. +This makes sure the reference to the original branch is kept in the +commits, allows one to revert a merge by reverting a single merge commit, +and creates a merge commit to mark the integration of the branch with +master. + + + +FAQ +Why use Common-Flow instead of Git Flow, and how does it differ? +Common-Flow tries to be a lot less complicated than Git Flow by having fewer +types of branches, and simpler rules. Normal day to day development doesn’t +really change much: + +You create change branches instead of feature branches, without the need of a +“feature/” or “change/” prefix in the branch name. +Change branches are typically created from and merged back into “master” +instead of “develop”. +Creating a release is done by simply creating a git tag, typically on the +master branch. + +In detail, the main differences between Git Flow and Common-Flow are: + +There is no “develop” branch, there is only a “master” branch which contains +the latest work. In Git Flow the master branch effectively ends up just being +a pointer to the latest release, despite the fact that Git Flow includes +release tags too. In Common-Flow you just look at the tags to find the latest +release. +There are no “feature” or “hotfix” branches, there’s only “change” +branches. Any branch that is not master and introduces changes is a change +branch. Change branches also don’t have a enforced naming convention, they +just have to have a “descriptive name”. This makes things simpler and allows +more flexibility. +Release branches are available, but optional. Instead of enforcing the use of +release branches like Git Flow, Common-Flow only recommends the use of release +branches when it makes things easier. If creating a new release by tagging +“master” works for you, great, do that. + +Why use Common-Flow instead of GitHub Flow, and how does it differ? +Common-Flow is essentially GitHub Flow with the addition of a “Release” concept +that uses tags. It also attempts to define how certain common tasks are done, +like updating change/feature branches from their source branches for +example. This is to help end arguments about how such things are done. +If a deployment/release for you is just getting the latest code in the master +branch out, without caring about bumping version numbers or anything, then +GitHub Flow is a good fit for you, and you probably don’t need the extras of +Common-Flow. +However if your deployments/releases have specific version numbers, then +Common-Flow gives you a simple set of rules of how to create and manage +releases, on top of what GitHub Flow already does. +What does “descriptive name” mean for change branches? +It means what it sounds like. The name should be descriptive, as in by just +reading the name of the branch you should understand what the branch’s purpose +is and what it does. Here’s a few examples: + +add-2fa-support +fix-login-issue +remove-sort-by-middle-name-functionality +update-font-awesome +change-search-behavior +improve-pagination-performance +tweak-footer-style + +Notice how none of these have any prefixes like “feature/” or “hotfix/”, they’re +not needed when branch names are properly descriptive. However there’s nothing +to say you can’t use such prefixes if you want. +You can also add ticket numbers to the branch name if your team/org has that as +part of it’s process. But it is recommended that ticket numbers are added to the +end of the branch name. The ticket number is essentially metadata, so put it at +the end and out of the way of humans trying to read the descriptive name from +left to right. +How do we release an emergency hotfix when the master branch is broken? +This should ideally never happen, however if it does you can do one of the +following: + +Review why the master branch is broken and revert the changes that caused the +issues. Then apply the hotfix and release. +Or use a short-term release branch created from the latest release tag instead +of the master branch. Apply the hotfix to the release branch, create a release +tag on the release branch, and then merge it back into master. + +In this situation, it is recommended you try to revert the offending changes +that’s preventing a new release from master. But if that proves to be a +complicated task and you’re short on time, a short-term release branch gives you +a instant fix to the situation at hand, and let’s you resolve the issues with +the master branch when you have more time on your hands. +About +The Git Common-Flow specification is authored +by Jim Myhrberg. +If you’d like to leave feedback, +please open an issue on GitHub. +License +Creative Commons - CC BY 4.0