Menu

Using Git Flow on a Drupal Project

Adam Dowling

Dec 18 2015

One does not simply commit into Master

Gitflow is a branching model for git and is used for projects where you might have multiple streams of work running concurrently. For this labs post I'll assume you are already proficent with git version control and want to be better. An FAQ is provided at the bottom of the post.

If you are using Gitflow on a project then you will have the following 2 main branches:

  1. master - always is in the same state as the production site
  2. develop - only ever contains stable code, ready for production
,

In the Gitflow model, a developer never commits directly into master. Master must always be as production.

In the Gitflow model, a developer never commits directly into master. Master must always be as production.

,

Hotfix branch

If there is an emergency and something needs to be changed in production, but you have work pending in develop which cannot go out to live, you can make a new branch from master - such a branch is called a hotfix branch. It should be named with a prefix of hotfix/ so someone listing out the branches available can immediatley see it is a hotfix. The suffix of its name should be its release number (e.g. if the current release on production is 1.5.0 then the next hotfix release will be 1.5.1 and the name of the hotfix branch will be hotfix/1.5.1)

When the hotfix is finished then its branch is merged into both master and develop so this urgent fix is applied to both the main master environment and the latest code in develop. A new release tag of 1.5.1 can then be cut from master and released.

Feature branch

When a new piece of work which is not an emergency hotfix needs to be done, this should always be placed into a new branch called a Feature branch. Feature branches are always cut from develop and so have all the latest code ready for production in them to build ontop of.

If you are using a project management system such as Jira it is a good idea to tie feature branches to issues so that the conversation and details around what is being developed in git can be connected together. A new developer picking up a feature in progress can go to Jira to read the details and also find the feature easily. Feature branches should be named with a prefix of feature/ and then, ideally, start with the name of the issue they refer to. So Jira issue abc-123 which is to add a search box would be created in feature branch called feature/abc-123-add-search-box.

Release branches

In the standard Gitflow model, when a feature is finished and ready for production then it should be merged back into develop and then deleted. However, sometimes your client or project will need to release only a subset of the total completed features to production. If they are all merged into develop then it will be a complex task to separate out the features or remove them from develop.

Instead, the features can be left in their feature branches until they are ready for release. At this point a new release branch is created from develop. The release branch should be named with the prefix release/ and finish with the next tag release number (e.g. if the last release was 1.5.1 then this will be 1.6.0 giving a release branch called release/1.6.0). The release branch starts like develop, but then each feature for release is merged into it.

The release branch can then be placed onto a staging site for final testing with all the new features ready for release to be tested. Once everyone is happy for release, the release branch is merged into develop and into master and the feature braches in it should be deleted.

A tag can then be cut from master with the name 1.6.0 and released to production.

Sounds hard - anything that can help me?

Yes, there is Gitflow tool which enhances the basic git command line tool to add in additional git flow commands which does some of the things above for us.

To make a git repo ready for gitflow you woud type in git flow init and then just press enter to everything it asks as the defaults are as described here.

To start a new hotfix you woud type git flow hotfix start 1.5.1 to create the hotfix branch cut from master and immedialtey switches to it.

To finish a hotfix you would type git flow hotfix finish 1.5.1 which merges the hotfix into master and develop and creates a tag release from master called 1.5.1

To start a new feature you would type git flow feature start abc-123-new-search-box to create the feature branch cut from develop and immedialtey switches to it.

To start a new release you would type git flow release start 1.6.0 create the feature branch cut from develop and immedialtey switches to it.

To merge feature branches into the release you can just use the basic git command git merge feature/abc-123-new-search-box

To finish a release you would use git flow release finish 1.6.0 which merges the release with all the features into develop and into master then deletes the release branch as it is no longer needed and creates a 1.6.0 tag from master. You would need to manually delete the now released feature branches git branch -D feature/abc-123-new-search-box

The command git flow feature finish abc-123-new-search-box can also be used which merges the feature into develop then deletes the feature branch in one go but we don't do this prefering to create release branches and then manually deleting the feature branches because we often have to release subsets of finished features.

Summary

Hopefully this has shown you how you can manage your workflow more effectivley using the Gitflow branching strategy. Below is a series of frequently asked questions developers new to Gitflow may find useful as a reference.

After some use of this with Drupal you might start to wish you could branch your database as easily as the code base allowing you to work on different db versions as well. We're working on some potential tools for this so stay tuned!

Edit: Branching of the environment is now available via our Rainmaker tool.

Hotfix branch

If there is an emergency and something needs to be changed in production, but you have work pending in develop which cannot go out to live, you can make a new branch from master - such a branch is called a hotfix branch. It should be named with a prefix of hotfix/ so someone listing out the branches available can immediatley see it is a hotfix. The suffix of its name should be its release number (e.g. if the current release on production is 1.5.0 then the next hotfix release will be 1.5.1 and the name of the hotfix branch will be hotfix/1.5.1)

When the hotfix is finished then its branch is merged into both master and develop so this urgent fix is applied to both the main master environment and the latest code in develop. A new release tag of 1.5.1 can then be cut from master and released.

Feature branch

When a new piece of work which is not an emergency hotfix needs to be done, this should always be placed into a new branch called a Feature branch. Feature branches are always cut from develop and so have all the latest code ready for production in them to build ontop of.

If you are using a project management system such as Jira it is a good idea to tie feature branches to issues so that the conversation and details around what is being developed in git can be connected together. A new developer picking up a feature in progress can go to Jira to read the details and also find the feature easily. Feature branches should be named with a prefix of feature/ and then, ideally, start with the name of the issue they refer to. So Jira issue abc-123 which is to add a search box would be created in feature branch called feature/abc-123-add-search-box.

Release branches

In the standard Gitflow model, when a feature is finished and ready for production then it should be merged back into develop and then deleted. However, sometimes your client or project will need to release only a subset of the total completed features to production. If they are all merged into develop then it will be a complex task to separate out the features or remove them from develop.

Instead, the features can be left in their feature branches until they are ready for release. At this point a new release branch is created from develop. The release branch should be named with the prefix release/ and finish with the next tag release number (e.g. if the last release was 1.5.1 then this will be 1.6.0 giving a release branch called release/1.6.0). The release branch starts like develop, but then each feature for release is merged into it.

The release branch can then be placed onto a staging site for final testing with all the new features ready for release to be tested. Once everyone is happy for release, the release branch is merged into develop and into master and the feature braches in it should be deleted.

A tag can then be cut from master with the name 1.6.0 and released to production.

Sounds hard - anything that can help me?

Yes, there is Gitflow tool which enhances the basic git command line tool to add in additional git flow commands which does some of the things above for us.

To make a git repo ready for gitflow you woud type in git flow init and then just press enter to everything it asks as the defaults are as described here.

To start a new hotfix you woud type git flow hotfix start 1.5.1 to create the hotfix branch cut from master and immedialtey switches to it.

To finish a hotfix you would type git flow hotfix finish 1.5.1 which merges the hotfix into master and develop and creates a tag release from master called 1.5.1

To start a new feature you would type git flow feature start abc-123-new-search-box to create the feature branch cut from develop and immedialtey switches to it.

To start a new release you would type git flow release start 1.6.0 create the feature branch cut from develop and immedialtey switches to it.

To merge feature branches into the release you can just use the basic git command git merge feature/abc-123-new-search-box

To finish a release you would use git flow release finish 1.6.0 which merges the release with all the features into develop and into master then deletes the release branch as it is no longer needed and creates a 1.6.0 tag from master. You would need to manually delete the now released feature branches git branch -D feature/abc-123-new-search-box

The command git flow feature finish abc-123-new-search-box can also be used which merges the feature into develop then deletes the feature branch in one go but we don't do this prefering to create release branches and then manually deleting the feature branches because we often have to release subsets of finished features.

Summary

Hopefully this has shown you how you can manage your workflow more effectivley using the Gitflow branching strategy. Below is a series of frequently asked questions developers new to Gitflow may find useful as a reference.

After some use of this with Drupal you might start to wish you could branch your database as easily as the code base allowing you to work on different db versions as well. We're working on some potential tools for this so stay tuned!

Edit: Branching of the environment is now available via our Rainmaker tool.

,

Gitflow FAQ

I have just joined a project and checked out the repo. Do I need to enable/initiate Gitflow?

Yes you do for each project you checkout. The Gitflow tools manage the Gitflow workflow locally.

How do I initialise Gitflow locally?

While somewhere in the repo run: git flow init

You can accept all the defaults

If Gitflow is being enabled for the first time for the project (not just your local repo checkout) then it will be necessary to push back to the remote the master and develop branches.

I am ready to start a new feature. Should I do it in a new Gitflow feature branch?

Yes, always.

I am ready to start a new feature in a new Gitflow feature branch. What do I do next?

Firstly, you should make sure you have “init’d” Gitflow locally (see above).

Next you should ensure your master and develop branches are up-to-date with their remote counterparts. If you are unsure how to do this see “How can I ensure the Gitflow master and develop branches are up-to-date?”.

Ensure you know what the feature branch name will be. If you are unsure of our naming conventions that skip forward to “What/how should I name my new feature branch?”

You should be on the develop branch at this point and should ensure you local Drupal DB is up-to-date with the develop branch. If you are unsure how to check if your local Drupal DB is up-to-date with the develop branch see “How can I ensure my local Drupal DB is up-to-date with develop branch?”.

Now execute: git flow feature start <your-branch-name-here>

You should now commit your changes to this feature branch.

I have completed my feature and committed all my changes to my Gitflow feature branch. What do I do next?

Primarily you should ensure you have pushed the branch and all changes up to the remote.

This is dependent upon the project and the workflow agreed by the team. Let us assume that the project is in production, that we are in a support cycle, and that we are adopting a “continual release” workflow ...

See if there is a release branch and create one if not. This is essentially a place where we can merge features that we are ready to release to a the client for feedback/sign-off/review.

Checkout the release branch and ensure it is up-to-date with upstream changes in the remote repo. If you are unsure how to do this then see ”Ensuring my release branch is up-to-date with the remote release branch”.

Now you can merge you feature branch into the release branch with the command: git merge feature/my-feaure-branch

Finally you should push your changes from the feature branch back to the remote using the command: git push

Note: There should never be code in the release branch which is not in either a feature branch or the develop branch.

The client has reviewed my feature and would like additional changes. What should I do?

Make the relevant changes and commit into the feature branch you created originally for the work. Push the branch and changes back to the remote repository. Checkout the release branch, ensure it is up-to-date, merge in your feature just as your did before, and push the release branch back to the remote.

I have received sign-off from the client should I merge my feature into a release?

This is a decision of the project team to decide if it is the right time to merge your feature into the active release branch. If the client's happy then thats usually a good sign.

How should I merge my feature into the develop branch?

Generally this is frowned on. We normally merge our features into the active release branch.

If you must merge into develop then there are two ways. One is to “finish” the feature with Gitflow. Be warned that by default Gitflow will remove a feature branch locally as part of its clean-up upon the merge completing. It is strongly advised that you suppress this with the “keep” option and delete the branch manually when it is no longer of any use. This is a safeguard to ensure if finishing a feature should fail, that the feature branch is still available to attempt finishing again.

The optimal command for finishing a feature through Gitflow is:

git flow feature finish --keep my-feature-name

The second way and this is my preference is that the feature is finished using a “squash” commit, as squash commits yield a very clean and clear Git log. You can perform a squash commit by adding the --squash option to the previous command:

git flow feature finish --keep --squash my-feature-name

Once you have committed your changes into the develop branch you should push the changes to the develop branch back to the remote repository with the command: git push origin develop

Finally, upon making changes to the develop branch, you should make sure to keep the release branch up-to-date. See “Ensuring the release branch is kept up-to-date with develop”.

Ensuring my release branch is up-to-date with the remote release branch

Find the release branch using git branch -r to list them all.

Checkout your local release branch with the command: git checkout release/[release number]

You should ensure your local refs for the release branch are up-to-date which you can do with the following command: git fetch origin release/[release number]

If you local release branch is “behind” the remote ref then you should bring you local branch up-to-date with the remote branch using the command: git merge --ff origin/release/[release number]

Ensuring the release branch is kept up-to-date with develop

If you have just committed a changes into the develop branch then it is paramount that the release branch is kept up-to-date with those changes.

To do this checkout the release branch and ensure it is up-to-date. If you are unsure how to do this then see ”Ensuring my release branch is up-to-date with the remote release branch”.

You can now merge the changes from develop into your release branch with the following command: git merge develop

Once the changed from develop have been merged into the release branch you should push the changes to the release branch back to the remote repository with the following command: git push origin release

Can I commit my changes for multiple JIRA issues, Basecamp to-dos, etc into the same Gitflow feature branch?

No. It would defeat the point of having a feature/bugfix/unit of work per feature branch, which is important to allow us to easily merge/release individual features/bugfixes/unit of works as they are completed and approved by the client.

I am using Gitflow is it ever acceptable to commit a change directly to master?

Never. Ever (ref Sean Bean above)

I am using Gitflow is it ever acceptable to commit a change directly to develop?

As a general rule, no. However, there are a few cases where it may be the right thing to do. Discuss the scenario with the project team if you think you should be committing to develop.

How can I ensure the Gitflow master and develop branches are up-to-date?

While somewhere in the repo filesystem you can issue this command: git fetch --all

That will update all your local pointers (aka references/refs) to where in the graph the remote branches are currently. Then you can use PhpStorm’s version control log viewer, or Source Tree or Tig and see if you pointers for master and develop match the same commit in the graph as their remote counterparts.

If they are not then you can update as follows. We will assume the develop branch here for our example:

git checkout develop

git merge --ff origin/develop

What/how should I name my new feature branch?

Ideally, you will be have a JIRA ticket. If not, why not? If you have a Basecamp to-do and your project is in JIRA then why not create a new JIRA ticket? JIRA is great for managing issues, Basecamp is great for managing the client.

If you have got a JIRA issue then the issue will have a project short code as a prefix and then an issue number. For example DSD-140. You should name your Gitflow feature branch using the issue Id.

How can I ensure my local Drupal DB is up-to-date with develop branch?

Ensure the develop branch is up-to-date. Now run the following commands which make sure your local setup has the right modules enabled (via use of the Drupal Master module), has the latest db updates applied, has the latest feature changes applied and has a fresh, clean cache.

drush @vdd master-exec
drush @vdd updb
drush @vdd fra -y
drush @vdd cc all

Adam Dowling

About the author

Adam Dowling

Senior Developer