It combines [feature driven development](http://en.wikipedia.org/wiki/Feature-driven_development) and [feature branches](http://martinfowler.com/bliki/FeatureBranch.html) with issue tracking.
![Four stages (working copy, index, local repo, remote repo) and three steps between them]() When converting to git you have to get used to the fact that there are three steps before a commit is shared with colleagues.
![Multiple long running branches and merging in all directions]() Since many organizations new to git have no conventions how to work with it, it can quickly become a mess.
Frequently the reaction to this problem is to adopt a standardized pattern such as [git flow](http://nvie.com/posts/a-successful-git-branching-model/) and [GitHub flow]()
[![Git Flow timeline by Vincent Driessen, used with persmission](http://nvie.com/img/2009/12/Screen-shot-2009-12-24-at-11.32.03.png)](http://nvie.com/posts/a-successful-git-branching-model/) Git flow was one of the first proposals to use git branches and it has gotten a lot of attention.
![Master branch with feature branches merged in]() In reaction to git flow a simpler alternative was detailed, [GitHub flow](http://scottchacon.com/2011/08/31/github-flow.html).
Merging everything into the master branch and deploying often means you minimize the amount of code in 'inventory' which is in line with the lean and continuous delivery best practices.
![Master branch and production branch with arrow that indicate deployments]() GitHub flow does assume you are able to deploy to production every time you merge a feature branch.
This is possible for SaaS applications but are many cases where this is not possible.
One would be a situation where you are not in control of the exact release moment, for example an iOS application that needs to pass AppStore validation.
Another example is when you have deployment windows (workdays from 10am to 4pm when the operations team is at full capacity) but you also merge code at other times.
In these cases you can make a production branch that reflects the deployed code.
You can deploy a new version by merging in master to the production branch.
If you need to know what code is in production you can just checkout the production branch to see.
The approximate time of deployment is easily visible as the merge commit in the version control system.
This time is pretty accurate if you automatically deploy your production branch.
If you need a more exact time you can have your deployment script create a tag on each deployment.
This flow prevents the overhead of releasing, tagging and merging that is common to git flow.
![Multiple branches with the code cascading from one to another]() It might be a good idea to have an environment that is automatically updated to the master branch.
Suppose you have a staging environment, a pre-production environment and a production environment.
In this case the master branch is deployed on staging. When someone wants to deploy to pre-production they create a merge request from the master branch to the pre-production branch.
And going live with code happens by merging the pre-production branch into the production branch.
This workflow where commits only flow downstream ensures that everything has been tested on all environments.
If you need to cherry-pick a commit with a hotfix it is common to develop it on a feature branch and merge it into master with a merge request, do not delete the feature branch.
If master is good to go (it should be if you a practicing [continuous delivery](http://martinfowler.com/bliki/ContinuousDelivery.html)) you then merge it to the other branches.
If this is not possible because more manual testing is required you can send merge requests from the feature branch to the downstream branches.
An 'extreme' version of environment branches are setting up an environment for each feature branch as done by [Teatro](http://teatro.io/).
![Master and multiple release branches that vary in length with cherrypicks from master]() Only in case you need to release software to the outside world you work with release branches.
This is called an 'upstream first' policy that is also practiced by [Google](http://www.chromium.org/chromium-os/chromiumos-design-docs/upstream-first) and [Red Hat](http://www.redhat.com/about/news/archive/2013/5/a-community-for-using-openstack-with-red-hat-rdo).
Every time a bug-fix is included in a release branch the patch version is raised (to comply with [Semantic Versioning](http://semver.org/)) by setting a new tag.
![Merge request with line comments]() Merge or pull requests are created in a git management application and ask an assigned person to merge two branches.
This can be done by creating a merge request without assigning it to anyone, instead you mention people in the description or a comment (/cc @mark@susan).
This means it is not ready to be merged but feedback is welcome.
Your team members can comment on the merge request in general or on specific lines with line comments.
The merge requests serves as a code review tool and no separate tools such as Gerrit and reviewboard should be needed.
If the review reveals shortcomings anyone can commit and push a fix.
Commonly the person to do this is the creator of the merge/pull request.
The diff in the merge/pull requests automatically updates when new commits are pushed on the branch.
When you feel comfortable with it to be merged you assign it to the person that knows most about the codebase you are changing and mention any other people you would like feedback from.
There is room for more feedback and after the assigned person feels comfortable with the result the branch is merged.
If the assigned person does not feel comfortable they can close the merge request without merging.
In GitLab it is common to protect the long-lived branches (e.g. the master branch) so that normal developers [can't modify these protected branches](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/permissions/permissions.md).
![Merge request with the branch name 15-require-a-password-to-change-it and assignee field shown]() GitLab flow is a way to make the relation between the code and the issue tracker more transparent.
For many organizations this will be natural since the issue will have to be estimated for the sprint.
Issue titles should describe the desired state of the system, e.g. "As an administrator I want to remove users without receiving an error" instead of "Admin can't remove users.".
When you are ready to code you start a branch for the issue from the master branch.
The name of this branch should start with the issue number, for example '15-require-a-password-to-change-it'.
When you are done or want to discuss the code you open a merge request.
This is an online place to discuss the change and review the code.
Creating a branch is a manual action since you do not always want to merge a new branch you push, it could be a long-running environment or release branch.
If you create the merge request but do not assign it to anyone it is a 'work-in-process' merge request.
These are used to discuss the proposed implementation but are not ready for inclusion in the master branch yet.
When the author thinks the code is ready the merge request is assigned to reviewer.
The reviewer presses the merge button when they think the code is ready for inclusion in the master branch.
In this case the code is merged and a merge commit is generated that makes this event easily visible later on.
Merge requests always create a merge commit even when the commit could be added without one.
This merge strategy is called 'no fast-forward' in git.
![Merge request showing the linked issues that will be closed]() Linking to the issue can happen by mentioning them from commit messages (fixes #14, closes #67, etc.) or from the merge request description.
If you have an issue that spans across multiple repositories, the best thing is to create an issue for each repository and link all issues to a parent issue.
People are encouraged to commit often and to frequently push to the remote repository so other people are aware what everyone is working on.
This will lead to many commits per change which makes the history harder to understand. But the advantages of having stable identifiers outweight this drawback.
And to understand a change in context one can always look at the merge commit that groups all the commits together when the code is merged into the master branch.
After you merge multiple commits from a feature branch into the master branch this is harder to undo.
If you would have squashed all the commits into one you could have just reverted this commit but as we indicated you should not rebase commits after they are pushed.
When using rebase to keep your feature branch updated you [need to resolve similar conflicts again and again](http://blogs.atlassian.com/2013/10/git-team-workflows-merge-or-rebase/).
You can reuse recorded resolutions (rerere) sometimes, but with without rebasing you only have to solve the conflicts one time and you’re set.
There has to be a better way to avoid many merge commits.
The way to prevent creating many merge commits is to not frequently merge master into the feature branch.
We'll discuss the three reasons to merge in master: leveraging code, solving merge conflicts and long running branches.
If you need to leverage some code that was introduced in master after you created the feature branch you can sometimes solve this by just cherry-picking a commit.
If your feature branch has a merge conflict, creating a merge commit is a normal way of solving this.
The last reason is having long lived branches that you want to keep up to date with the latest state of the project.
Martin Fowler, in [his article about feature branches](http://martinfowler.com/bliki/FeatureBranch.html) talks about this Continuous Integration (CI).
At GitLab we are guilty of confusing CI with branch testing. Quoting Martin Fowler: "I've heard people say they are doing CI because they are running builds, perhaps using a CI server, on every branch with every commit.
That's continuous building, and a Good Thing, but there's no integration, so it's not CI.".
The solution to prevent many merge commits is to keep your feature branches shortlived, the vast majority should take less than one day of work.
If your feature branches commenly take more than a day of work, look into ways to create smaller units of work and/or use [feature toggles](http://martinfowler.com/bliki/FeatureToggle.html).
As for the long running branches that take more than one day there are two strategies.
This strategy is [advocated by Linus Torvalds](https://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html) because the state of the code at these points is better known.
![Remove checkbox for branch in merge requests]() We recommend that people push their feature branches frequently, even when they are not ready for review yet.
To see more information about the formatting of commit messages please see this great [blog post by Tim Pope](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
![Merge requests showing the test states, red, yellow and green]() In old workflows the Continuous Integration (CI) server commonly ran tests on the master branch only.
Do not merge in upstream if your code will work and merge cleanly without doing so, Linus even says that [you should never merge in upstream at random points, only at major releases](http://lwn.net/Articles/328438/).