Git Flow#
Git Flow was one of the first proposals for the use of Git branches. It
recommended a main
branch and a separate develop
branch as well as
various other branches for features, releases and hotfixes. The various
developments should be brought together in the develop branch, then transferred
to the release
branch and finally end up in the main
branch.
Drawbacks of Git Flow#
While Git Flow is a well-defined but complex standard, it creates two practical problems:
Most developers and tools assume that the
main
branch is the branch from which branches and merges are executed. With Git Flow, there is additional work involved because you always have to switch to thedevelop
branch first.The
hotfixes
andrelease
branches also bring additional complexity, which should only bring advantages in the rarest of cases.
In response to the problems of Git Flow, GitHub and Atlassian developed simpler alternatives that are mostly limited to so-called Feature branch workflows.
First steps#
Git-flow is just an abstract idea of a git workflow, where the branches and the merges are given. There is also software, git-flow, to assist with this workflow.
Installation#
$ wget -q -O - --no-check-certificate https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | bash
$ sudo apt install git-flow
$ brew install git-flow
Initialise#
git-flow
is a wrapper for Git. The git flow init
command not only
initiates a directory, but also creates branches for you:
$ git flow init
Initialized empty Git repository in /home/veit/my_repo/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master] main
Branch name for "next release" development: [develop]
How to name your supporting branch prefixes?
Feature branches? [feature/]
Bugfix branches? [bugfix/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
Hooks and filters directory? [.git/hooks]
Alternatively, you could have entered the following:
$ git branch develop
$ git push -u origin develop
This workflow provides two branches to record the history of the project:
main
contains the official release history, and all commits in this branch should be tagged with a version number.
develop
integrates the features.
Feature branches#
Each new feature should be created in its own branch, which can be pushed to the
remote repository at any time. However, a feature branch is not created from the
main
branch but from the develop
branch; and when a feature is finished,
it is also merged back into the develop
branch.
You can create such feature branches with git flow
:
$ git flow feature start 17-some-feature
Switched to a new branch 'feature/17-some-feature'
Summary of actions:
- A new branch 'feature/17-some-feature' was created, based on 'develop'
- You are now on branch 'feature/17-some-feature'
…
… or with
$ git switch -c feature/17-some-feature
Switched to a new branch 'feature/17-some-feature'
Conversely, you can complete your feature branch with
$ git flow feature finish 17-some-feature
Switched to branch 'develop'
Already up to date.
Deleted branch feature/17-some-feature (was a2d223f).
…
… or with
$ git switch develop
$ git merge feature/17-some-feature
$ git branch -d feature/17-some-feature
Deleted branch feature/17-some-feature (was a2d223f).
Release branches#
If the develop
branch contains enough features for a release or a fixed
release date is approaching, a release
branch is created from the
develop
branch, to which no new features should be added from this point on,
but only bug fixes and changes related to this release. If the release can be
delivered, the release
branch is on the one hand merged into the main
branch and tagged with a version number, and on the other hand merged back into
the develop
branch, which may have developed further since the creation of
the release
branch.
$ git flow release start 0.1.0
Switched to a new branch 'release/0.1.0'
…
$ git flow release finish '0.1.0'
Switched to branch 'main'
Deleted branch release/0.1.0 (was a2d223f).
Summary of actions:
- Release branch 'release/0.1.0' has been merged into 'main'
- The release was tagged '0.1.0'
- Release tag '0.1.0' has been back-merged into 'develop'
- Release branch 'release/0.1.0' has been locally deleted
- You are now on branch 'develop'
… or
$ git switch develop
$ git branch develop/0.1.0
…
$ git switch main
$ git merge release/0.1.0
$ git tag -a 0.1.0
$ git switch develop
$ git merge release/0.1.0
$ git branch -d release/0.1.0
Hotfix branches#
Hotfix branches are suitable for quick patches of production versions. They are
similar to release
branches and feature
branches, but are based on the
main
branch instead of the develop
branch. This makes it the only branch
that should be forced directly from the main
branch. Once the hotfix has
been completed, it should be merged into both the main
and develop
branches and, if necessary, into the current release
branch. The main
branch should also be tagged with a new version number.
$ git flow hotfix finish 37-some-bug
Switched to branch 'develop'
Merge made by the 'recursive' strategy.
…
Deleted branch hotfix/37-some-bug (was a2d223f).
Summary of actions:
- Hotfix branch 'hotfix/37-sombe-bug' has been merged into 'main'
- The hotfix was tagged '0.2.0'
- Hotfix tag '0.2.0' has been back-merged into 'develop'
- Hotfix branch 'hotfix/37-some-bug' has been locally deleted
- You are now on branch 'develop'
… or
$ git switch main
Switched to branch 'main'
…
$ git merge hotfix/37-some-bug
$ git tag -a 0.2.0
$ git switch develop
$ git merge hotfix/37-some-bug
$ git branch -d hotfix/37-some-bug