Go to content
The Codest
  • About Us
  • Services
  • Our Team
  • Case studies
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About Us
  • Services
  • Our Team
  • Case studies
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
2019-08-13
The CodestSoftware Development

GitFlow

Daniel Grek

GitFlow - Image

This document was written in order to unify the internal company Git Flow rules. This method is not introducing pure Git Flow, as it is a mix of both Git Flow and GitLab Flow, with best company practices worked over many years. It helps keep a clean and readable history of the repository and better control over changes and project lifecycles.

This document was written in order to unify the internal company GitFlow rules. This method is not introducing pure GitFlow, as it is a mix of both GitFlow and GitLab Flow, with best company practices worked over many years. It helps to keep a clean and readable history of the repository and better control over changes and project lifecycles.

Initializing repository

After initializing the repository, create a develop and master branch if it wasn’t included by default. The develop branch should contain a development code that is a mirror of the master branch with new features included. The master contains a stable version of code, representing the production state. Both have infinite lifetimes, and in comparison to other branches in Git Flow, will never be removed. Set up proper protection rules: require to pull request reviews before merging and require status checks to pass before merging. You may also consider allowing only chosen team members to merge changes to the master.

GitFlow

$ git init
$ git commit --allow-empty -m "Initial commit"
$ git checkout -b develop master

NOTE: Sometimes it is important for the project to add more infinite branches, for example, to represent available environments. However, keep the “rule of two” if possible.

Feature branches

When starting to work with a given feature, first ensure you have your develop branch synced.

$ git checkout develop && git pull --rebase

Then, checkout to your feature branch. Name it respectively to the given schema: feature-JIRA-TASK-ID or you can also break that rule and name it differently. In this case, ensure that it does not conflict with patterns reserved for release, hotfix, bugfix, development or the master branch. Keeping JIRA task IDs will help you manage your feature branches more effectively.

$ git checkout -b feature-JIRA-TASK-ID develop

This branch should exist as long as the given feature is developed and then merged to the parent branch. To commit to your local branch, please follow this command:

$ git add .
$ git commit -m "JIRA-TASK-ID: Task description"

It is recommended that you add more commits to your local branch, following the “Commit early and often” rule. However, in the end, they must be squashed into a single commit representing a JIRA Task. Often committing will help you to manage your development history. When the feature is ready, it is time to open a Pull Request to develop a branch. First, you may push your local branch if it wasn’t pushed too far:

$ git push origin feature-JIRA-TASK-ID

When the branch is ready, open your pull request on GitHub, by following this article: https://help.github.com/en/articles/creating-a-pull-request

Before opening a pull request, please ensure the following:

  • a proper description has been given – usually, you would link your JIRA task, but you may also include some useful information related to the current code

  • CircleCI steps were passed successfully

  • your team members were assigned – it is good practice to include all your team members as assignees

  • the reviewers were selected – the number of reviewers depends on your team

  • your code is actually ready for review – take a last look at your code, think again if there is anything left to refactor, test it locally and ensure that it is ready for further steps.

  • there are no merge conflicts and a branch is up-to-date with develop – if there are any, resolve them first

$ git checkout develop && git pull --rebase
$ git checkout feature-JIRA-TASK-ID && git rebase develop # use -i flag for squash
$ git push -f origin feature-JIRA-TASK-ID #use this carefully as -f flag overwrites remote repository
  • keep only important commits – each commit should be represented by JIRA task, for example, JIRA-TASK-ID: New feature configuration; others should be squashed while rebasing your branch with the develop branch

  • you have the proper destination branch selected

  • you don’t forget to change the status of your JIRA task

Merging feature branch

It is time to merge your changes to develop branch when:

  • the pull request was approved by selected team members

  • all tests finished successfully

  • there are no merge conflicts and the commit history looks fine

This can be done by either the project manager or feature developer. In order to perform the merge, follow these steps:

$ git checkout develop
$ git merge feature-JIRA-TASK-ID
$ git push origin develop
$ git branch -d feature-JIRA-TASK-ID
$ git push origin :feature-JIRA-TASK-ID

Now, JIRA task status can be changed.

Releases

Release branches should be created by a person responsible for the current release. Usually, releases are created periodically, for example, according to the sprint lifecycle.

Semantic versioning

Giving a release branch a proper name and corresponding tag is not an easy task at the very beginning. It is good practice to start using semantic versioning (https://semver.org/) which allows better control and makes reading the git history easier. The version string is constructed according to MAJOR.MINOR.PATCH schema:

  • MAJOR – change representing incompatible API changes

  • MINOR – adding new features in a backwards-compatible manner

  • PATCH – adding backwards-compatible bug fixes

You may also use special suffixes, such as those representing beta or legacy branches, or create pre-releases. In that case, name it properly, e.g. 1.1.0-beta.4, 1.1.0-beta.5 or 1.1.0-alpha.

Making a release

The release branch should be a child of develop and could contain only commits connected with bugfixes.

The branch name should be based on the release version, with the release- prefix: release-MAJOR.MINOR.PATCH. The release branch should be fully tested both automatically and manually on the staging environment. If bugs occur, this is the last opportunity to push proper fixes and re-run the whole process, as long as it won’t be positively checked and ready for further processing. Then, the release commit should be pushed, with changes of the current release version string in files, such as package.json. It should also have an impact on the CHANGELOG.md file. This will help you track all changes before a proper release and prepare the content for GitHub release when the merge process is completed. The single file update should consist of all release changes grouped into three categories: features, fixes and maintenance.

In the first step however, make sure you have both of your develop and master branches up-to-date.

$ git checkout master && git pull --rebase
$ git checkout develop && git pull --rebase
$ git merge master
$ git checkout -b release-M.M.P
$ git add .
$ git commit -m "Product Name M.M.P release"
$ git push origin release-M.M.P

At this point, one may decide to create another pull request to the master with the release branch. It may be a good idea to run an additional check if all tests pass well on the remote machine.

$ git checkout master
$ git merge release-M.M.P
$ git tag -a M.M.P # addition message may be set via -m flag
$ git push origin M.M.P
$ git push origin master
$ git branch -d release-M.M.P
$ git push origin :release-M.M.P

Then go to the GitHub releases page and press the “Draft new release” button. In the displayed form, select the current version tag, set the release title similar to the release commit (Product Name M.M.P release) and a proper description, based on the CHANGELOG.md file. For public projects, the description should contain a list of all PR included in the current release.

In case some bugfixes were applied on the release branch, ensure you have your develop branch updated:

$ git checkout develop && git merge master
$ git push origin develop

Hotfixes and Bugfixes

The main difference between a bug and hot fixes is their target branches.

Bugfix

Bug fixes should patch release branches as the only form of updating code before merging it to master. First, create the branch from the current feature branch. Make sure you have it up-to-date locally.

$ git checkout release-M.M.P && git pull --rebase
$ git checkout -b bugfix-M.M.P

Then commit the necessary changes. After the process is finished, create a pull request and target it to the release branch. Follow guidance from the feature branch section. Your final commit title should match the given schema: “Bugfix M.M.P: Problem essence fix”. When the pull request is approved, it is time to merge it to the current release.

$ git checkout release-M.M.P
$ git merge bugfix-M.M.P
$ git push origin release-M.M.P

Hotfix

In order to perform a hotfix on the master branch, very similar steps to a bugfix must be taken, keeping in mind that the target branch is now the master branch.

$ git checkout master && git pull --rebase
$ git checkout -b hotfix-X.Y.(Z+1) # M.M.P represents current release

Then, follow the usual development steps and when the process is finished, create a pull request with the master branch as a target. Keep in mind that the final commit should match the given schema “Hotfix X.Y.(Z + 1): Problem essence fix”. When every checkpoint has passed successfully, perform a merge to master. These steps differ from the one presented for a bugfix, as we need to bump the current release version.

$ git checkout master && git pull --rebase
$ git merge hotfix-X.Y.(Z+1)
$ git tag -a X.Y.(Z+1) # addition message may be set via -m flag
$ git push origin X.Y.(Z+1)
$ git push origin master
$ git branch -d hotfix-X.Y.(Z+1)
$ git push origin :hotfix-X.Y.(Z+1)
$ git checkout develop && git merge master
$ git push origin develop

Cheat sheet

Init repository

$ git init
$ git commit --allow-empty -m "Initial commit"
$ git checkout -b develop master
$ git push origin develop
$ git push origin master

Features

$ git checkout develop && git pull --rebase
$ git checkout -b feature-JIRA-TASK-ID develop

# Start your development and commits
$ git add .
$ git commit -m "IRA-TASK-ID: Task description" #initial commit
$ git push origin feature-JIRA-TASK-ID
# Open pull request

# Rebase and prepare for pull request
$ git checkout develop && git pull --rebase
$ git checkout feature-JIRA-TASK-ID && git rebase develop # use -i flag for squash
$ git push -f origin feature-JIRA-TASK-ID #use this carefully as -f flag overwrites remote repository

# Merge changes and delete branch
$ git checkout develop # branch should be synced with develop branch at this stage
$ git merge feature-JIRA-TASK-ID
$ git push origin develop
$ git branch -d feature-JIRA-TASK-ID
$ git push origin :feature-JIRA-TASK-ID

Releases

$ git checkout master && git pull --rebase
$ git checkout develop && git pull --rebase
$ git merge master
$ git checkout -b release-M.M.P

# Create release commit
$ git add .
$ git commit -m "Product Name M.M.P release" #initial commit
$ git push origin release-M.M.P
# Open pull request

# Merge changes, release and delete branch
$ git checkout master # branch should be synced with master branch at this stage
$ git merge release-M.M.P
$ git tag -a M.M.P # addition message may be set via -m flag
$ git push origin M.M.P
$ git push origin master
$ git branch -d release-M.M.P
$ git push origin :release-M.M.P

Bugfix

$ git checkout release-M.M.P && git pull --rebase
$ git checkout -b bugfix-M.M.P

$ Commit fixes
$ git add .
$ git commit -m "Bugfix M.M.P: Problem essence fix" #initial commit
$ git push origin bugfix-M.M.P
# Open pull request

# Merge changes and delete branch
$ git checkout release-M.M.P # branch should be synced with current release branch at this stage
$ git merge bugfix-M.M.P
$ git push origin release-M.M.P
$ git branch -d bugfix-M.M.P
$ git push origin :bugfix-M.M.P

Hotfix

$ git checkout master && git pull --rebase
$ git checkout -b hotfix-X.Y.(Z+1) # M.M.P represents current release

$ Commit fixes
$ git add .
$ git commit -m "Hotfix M.M.P: Problem essence fix" #initial commit
$ git push origin bugfix-M.M.P
# Open pull request

# Merge changes, release and delete branch
$ git checkout master # branch should be synced with current master at this stage
$ git merge hotfix-X.Y.(Z+1)
$ git tag -a X.Y.(Z+1) # addition message may be set via -m flag
$ git push origin X.Y.(Z+1)
$ git push origin master
$ git branch -d hotfix-X.Y.(Z+1)
$ git push origin :hotfix-X.Y.(Z+1)
$ git checkout develop && git merge master
$ git push origin develop

Read more:

  • Codest’s good practice for building software: CircleCI

  • How to create Google Chrome Extensions using the Netflix subtitles styler?

  • React: the most popular JavaScript framework

Related articles

The Codest

Project management in SCRUM

SCRUM is a project management methodology based on empirical process control theory, which is consistent with the values of the Agile manifesto (2001). This is not a restrictive work methodology but rather a framework that allows...

Mateusz Lesniak
The Codest

The Codest Core Value #1

The Codest believes in four crucial values that are the core of all actions taken by The Codest teams. In this article, our CEO and co-founder, Greg Polec, explains what acting fast and focusing on the bigger picture means to us.

Greg Polec
The Codest

The Codest's Success Story: Meet Lukasz Brzeszcz

This time the star of The Codest Success Story is Lukasz Brzeszcz, our Ruby software developer and programmer. How did Lukasz’s journey with The Codest begin and what helped him to become an awesome manager? Read this article to...

Monika Krupa
The Codest

The Codest's Success Story: Meet our Finance Lead Iza

In this article series, we share the stories of The Codest teammates who have had an impact on the present shape of our company. In the following piece, we ask our Financial Lead, Iza, some questions about her career at The...

Monika Krupa

Subscribe to our knowledge base and stay up to date on the expertise from industry.

About us

Tech company specializing in scaling tech teams for clients and partners thanks to top-class development engineers.

    United Kingdom - Headquarters

  • Office 303B, 182-184 High Street North E6 2JA London, England

    Poland - Local Tech Hubs

  • Business Link High5ive, Pawia 9, 31-154 Kraków, Poland
  • Brain Embassy, Konstruktorska 11, 02-673 Warsaw, Poland
  • Aleja Grunwaldzka 472B, 80-309 Gdańsk, Poland

    The Codest

  • Home
  • About us
  • Services
  • Case studies
  • Know how
  • Careers

    Services

  • PHP development
  • Java development
  • Python development
  • Ruby on Rails development
  • React Developers
  • Vue Developers
  • TypeScript Developers
  • DevOps
  • QA Engineers

    Resources

  • What are top CTOs and CIOs Challenges? [2022 updated]
  • Facts and Myths about Cooperating with External Software Development Partner
  • From the USA to Europe: Why do American startups decide to relocate to Europe
  • Privacy policy
  • Website terms of use

Copyright © 2022 by The Codest. All rights reserved.

We use cookies on the site for marketing, analytical and statistical purposes. By continuing to use, without changing your privacy settings, our site, you consent to the storage of cookies in your browser. You can always change the cookie settings in your browser. You can find more information in our Privacy Policy.