So you want your Team to start using Git? – Part 4: Team Workflows

comments

So you’ve got your own personal Git use dialled in, you’ve got a server environment configured with commits flying into your project like crazy, now you’re ready to start leveraging the power of Git with others. New workflows exist for distributed version control systems that offer big gains in terms of developer workflow, interaction, quality assurance and overall delivery process. Let’s take a look at one of them – GitFlow, so we can turn your team’s Git usage up to 11.

Workflows

One of the problems that comes from using source control in a team of any more than just a few developers is common regardless of the tooling you use: Developers editing the same files and working on the same projects and treading on each others toes. It’s a recipe for disaster.

Every Source Control tooling I've used over the years has had a different community approach to how this issue is dealt with; an informal “gold standard” for branching and merging. The Git community’s most common answer to this is an approach/workflow named “GitFlow”.

In essence GitFlow is a branching strategy that takes the best bits from a number of very successful strategies from CVS communities (SVN/TFS) and mashes them together.

A really good early write up of using GitFlow can be found here.

Foundations

At it’s core GitFlow uses the speed, simplicity and power of Git’s branching and merging features to take full advantage of this for your team’s betterment.

It operates on a few key principles and assumptions.

  • Commits are cheap.
  • Branches are cheap.
  • Merging in Git is so super pain free, so this works well for code reviews/peer review.
  • Teams need an approach to building features away from production code.
  • Teams need an approach to rolling out hotfixes without mixing in any untested development code.
  • Having a way to record previous releases is an important way of story workflow progression (tagging).

At a high level, GitFlow is the use of Git’s branching strategy to take care of a need for hotfixes, releases, development and team feature branches.

image

This translates directly into the following:

“master” branch

Your current latest production ready codebase at any time resides in the “master” branch. This is only merged into once a release has successfully gone out and is tagged for easy rollback.

“develop” branch

Your “develop” branch is your currently integrated work in progress branch. If you’re deploying your staging or pre-prod integration codebase from here, you’re probably doing it right :-)

Feature branches for everything

Branching in Git is cheap in terms of speed and disk space - mostly because it’s not how you’d normally think of branching. Merging is super easy and mostly merge conflict free. So every time you pick up a new user story or backlog item, create a new branch.

Release branching is used for pre-release tweaks/integration

It’s not rare for you to work towards a release and have to make some last minute tweaks against your highly integrated “develop” codebase. For this we create a branch of “develop” and use it to pre-merge “master” into it resolving any last minute kinks while allowing your team to carry on.

Support to work on hotfixes as a first class citizen

Someone’s reported a sev 1/critical/end-of-world-drop-everything bug, and you need to just tweak something quickly to resolve it. Branching off master for a hotfix before a quick reintegration and double merge back into “master” and “develop” makes this easy.

Tagging to remember all of your teams greatest hits

Tagging releases with semantic versioning conventions make rolling back a piece of cake.

Down to Business

Whether you’re in the command line, or using the SourceTree GUI, implementing GitFlow is easy. SourceTree actually makes this even easier by supporting GitFlow natively with an easy to use wrapper over the top of the Git commands necessary for it’s use. Want a new feature? Simply use the button just for that!

image

Working on code away from the current release

The first thing any team wants to ensure is that you’ve got a stable working copy of your source code to deploy at the drop of a hat while you continue working.

The way GitFlow approaches this is with two standard branches.

The “master” branch is where we keep our stable source codebase. Our current releases.

We then create a branch called “develop” to store your current development integration branch. If you like to run Continuous Integration and Deployment for your team’s current stable development work then this might be where you’d do it.

image

To set this up in the command prompt or with your Git bash:

$ git checkout master
$ git checkout -b develop

This checks out your current master branch and then branches it into a new branch named “develop” for you to continue your work in.

To get this some setup in Source Tree while also letting Source Tree know that you want to use GitFlow:

Open Source Tree with your current Repository open.

Click on the “GitFlow” icon:

image

This will then bring up a dialog asking you what defaults you’d like to use for your branch naming conventions. I suggest just going with the defaults.

image

Press OK, and Source Tree will create you a new “develop” branch and check it out.

image

If you open up your .git folder and look closely you’ll notice that SourceTree has also edited your “.git\config” file to add your GitFlow configuration (I’ve highlighted the new bits in red).

[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
    hideDotFiles = dotGitOnly
[gitflow "branch"]
    master = master
    develop = develop
[gitflow "prefix"]
    feature = feature/
    release = release/
    hotfix = hotfix/
    support = support/
    versiontag =

With this completed you’re now ready to get going using GitFlow with SourceTree.

You then want to make sure you push this new “develop” branch up to your remote so your team can see it. By default this won’t occur, so we need to make sure your remote knows about the branch.

On the command line:

$ git push origin feature/user-story-123

In Source Tree you simply press the “Push” icon, and make sure you’ve checked your new develop branch.

image

Separate the different pieces of work you and your team are developing

I mentioned above that Git was great because commits and branches are so cheap. This makes working in parallel really easy as everyone can work with their own branch.

GitFlow gives you a framework for taking this even further, and guiding you to use a new branch for every new piece of work – by creating “feature” branches.

image

To follow this convention, every time you want to work on something new, checkout your develop branch, and then branch from it.

$ git checkout develop
$ git checkout -b feature/user-story-123

Protip: if you’re big into using GitFlow on the commandline, there is actually a set of bash extensions that make this more implicit. Give them a go to save yourself the keystrokes.

If you’re using Source Tree you do this by checking out your “develop” branch (right click on it and choose “checkout”).

Then press the GitFlow icon and select “start new feature”

image

Then give your feature a name, hit OK and you’ve created a new feature branch and checked it out.

image

After you’ve done some work you need to make sure you push this new branch to your remote so your team can see it and potentially work on it also.

On the command line:

$ git push origin feature/user-story-123

In Source Tree you do this the same way you did with your develop branch, press the “Push” icon and select your new feature branch.

image

Many commits later you’ve finished your work.

You’re ready to close out your feature and merge it back into “develop”.

We need to merge your feature branch into “develop”

On the command line:

$ git checkout develop
$ git merge feature/user-story-123
$ git branch –d feature/user-story-123

This merges“develop” into your feature, then checks out “develop” and merges your feature into develop, then deletes develop.

If you suffer from a merge conflict on the command line, i recommend this guide to help walk you through an interactive command line merge.

In Source Tree:

Click on the GitFlow icon.

 image

Then press “Finish feature”.

image

You can then select the feature branch you’d like to finalise and click OK.

image

Both of the above use cases will take the Git default of conducting a “fast forward” merge if possible, which can be a little unsettling if you’ve never used Git before. This is because depending on what’s gone on in the “develop” since you branched, any visibility over what went on in your feature branch may disappear with your merge and appear like the work was done in “develop” all along. In the case that nothing has changed since you branched, your feature branch has now become the past for the “develop” branch. You can change this behaviour, but have a read so you understand whether this matters to you or not.

In the case that you encounter a merge conflict because your team has made changes to “develop” while you were working, you can follow this guide to help you work through a merge conflict with Source Tree and Git (hint; it’s quite easy).

You’ve now completed your first feature branch using GitFlow. This allows each of your team to work on separate pieces of functionality without affecting each other while at the same time keeping a clean development integration copy of your team’s work in progress and your current production release of code for a redeployment or rollback at anytime.

Starting a new Release and segregating it so work can carry on

Another important team productivity boost from GitFlow is it’s ability for you to “work on a release” while normal development work continues in “develop” and your feature branches. It does this by taking a branch of your current “develop” branch named “releases/0.1” (following semantic versioning conventions). This allow your team to continue working while some of your team or DevOps guys finalise your release.

image

To accomplish this what we’re going to do:

  1. Checkout “develop”
  2. Branch “develop” into “release/0.1”
  3. Make some last minute changes.
  4. Merge “release/0.1” into master and “develop”.
  5. Delete our release branch.

To do this on the command line:

$ git checkout develop
$ git checkout -b release/v0.1

Now make any commits you need to finalise your release.

When you’re done, it’s time to merge into “master” and “develop”, and tag your release on the command line.

$ git checkout develop
$ git merge release/v0.1
$ git checkout master
$ git merge release/v0.1
$ git tag -a v0.1 -m 'Our release of version v0.1'
$ git branch –d release/v0.1

To do this in Source Tree:

Checkout your “develop” branch by right clicking on “develop” and selecting “checkout “develop branch”.

Now click on the “GitFlow” icon.

 image

Now press the “Start New Release” button.

image

Give your release a name. I’m naming mine “v0.1” as it’s my first release.

image

You are now checked out into your new release branch.

image

You can then make any final changes and commits, while your team keeps working on the next one.

When you are done with your release changes, you finish your release by again pressing the GitFlow icon.

 image

Press the “Finish Release” button.

image

Enter a comment for your release finalisation message and press OK.

image

And with that you’ve finished your first release!

Fixing production issues without stopping the music

The last thing that most teams need from a great source control workflow is the ability to take into account out-of-band hotfixes for bugs found in production.

GitFlow has you covered here, as it includes a branching strategy for hotfixes. This is incredibly important because a hotfix to production is usually a small tweak, and you want to make it only to your current production codebase while keeping it very segregated from unstable changes happening elsewhere in your repository. By using GitFlow to create a branch of “master” specifically to work on this fix, you allow your team to continue on it’s work in “develop” or feature branches without slowing them down at all – all while being incredibly safe.

image

What this means in reality:

  1. Your team finds a bug in production.
  2. You create a branch of “master” named “hotfix/v0.1.1” or similar.
  3. Your team completes a fix by committing to this branch.
  4. You merge this hotfix branch back into “master” and “develop” and delete the release branch.
  5. You tag this merged commit for later rollback.

Doing this on the command line:

$ git checkout master
$ git checkout -b hotfix/v0.1.1

Now make any commits you need to finalise your hotfix.

These commits will be kept separate from everything else going on in your repo.

When completed with your hotfix, it’s time to merge it into “master” and “develop” and delete it.

$ git checkout master
$ git merge hotfix/v0.1.1
$ git checkout developer
$ git merge hotfix/v0.1.1
$ git tag -a v0.1.1 -m 'Fix a cross browser compatibility issue on homepage'
$ git branch -d hotfix/v0.1.1

Doing this in Source Tree:

Checkout your “master” branch by right clicking on it on the left and opting the “Checkout master”

image

Now press the “GitFlow” icon to open the GitFlow menu.

 image

Select the option for “Start New Hotfix”

image

Give your hotfix a name.

image

You’ll notice that Source Tree gives your branch the name “hotfix/v0.1.1” to follow the GitFlow naming convention.

image

Then work with and commit your fixes to this branch.

When you’re done we’ll finish the hotfix, by pressing the GitFlow icon again and then selecting “Finish HotFix”

image

Now enter a description for your closing merge, and press OK.

image

When you action this merge you’ll notice that Source Tree has also tagged your hotfix release with the name of your hotfix.

image

And with that you’ve also taken care of fixing a bug in production while your team continues to work.

Summary

I hope the last 4 parts of this blog series helped you get a start using Git with other people in your team. Like a lot of new development team approaches I wouldn’t expect you to all be Git Gurus on day one, but I hope these posts are enough to get you and your team started.

Checkout the rest of the posts in this series: