Git best practices: How to minimize code conflicts

Code conflicts suck, any developer knows how painful it is to pull changes from a Git repository just to discover that she will need to invest another hour working on solving conflicts caused by the work of another developer in the same file. Probably, she will end doing a pair review with the other developer to ensure that changes are not lost, which ends generating reprocesses and affecting the sprint.

The good news is that this problem can be avoided by using the following concept of branches, which will allow developers to work under a more organized version control environment and minimize the risk of conflicts.

The main branches – master and develop

A Git repository holds two main branches with an infinite lifetime: master and develop.

  • The master branch always reflects a production ready state. The live site mustn’t be ahead master. Code releases are tagged from master.
  • The develop branch is only used for code integration, and it reflects a state with the latest delivered development changes for the next release(s). Implement automated testing on this branch.

These branches should never be modified directly!

Supporting Branches

Supporting branches are used by developers to work independently on their local environments and avoid stepping on their toes. For instance, if I need to perform security updates in a Drupal project, I just need to create a new branch from master or develop – depending on how critical is that update – and work independently without affecting the work that other people are doing in the same project under different branches.

There are three types of supporting branches:

Feature branches

These branches are created from develop, and are used to implement new features. Once developers are done with their changes, those branches are merged back to develop.

Release branches

Release branches are created from the develop branch as well. They are used to isolate the changes merged in the develop branch and get them ready for a new production release. This branch allows the develop branch to receive more updates without affecting that release.

Usually, a release branch is deployed in a testing environment to follow a final quality assurance process. If bugs are discovered during that process, they will be fixed and pushed to that release branch. Notice that the develop branch won’t be affected either with those new updates.

Once a release branch is free of errors and ready to be released, it is merged into the master branch so it is later on deployed to production, and to the develop branch, to pull all the bug fixes that were implemented during quality assurance.

Hotfix branches

Hotfix branches are created from the master branch, they are used when changes on develop are not release-ready and a fix to production is required that cannot wait until the upcoming release is stable.

These branches are also deployed in a testing environment to follow a quality assurance process. If bugs are discovered during that process, they will be fixed and pushed to that hotfix branch.

Once a hotfix branch is free of errors and ready to be released, it is merged into the master branch to be deployed to production, and to the develop branch, to pull all the bug fixes that were implemented during quality assurance.

I recently wrote an article with the git commands to create feature, hotfix and release candidate branches.

Illustration of main and supporting branches in Git