Branch Management

Hero image for Branch Management

Our methodology is mostly inspired by git-flow which basically allows separating works by branch types: feature/bug/chore (user story types) and release type.

Formatting

  • Use lowercase and kebab-case for branches names.

    feature/list_job_positions
    Bug/userResetPassword
    
    feature/list-job-positions
    bug/user-reset-password
    
  • Use the forward slash / to separate the branch type from the branch title.

    feature-list-job-positions
    bug_user-reset-password
    
    feature/list-job-positions
    bug/user-reset-password
    

Naming

  • Find a balance between conciseness and descriptiveness for branch titles.

    feature/as-a-user-i-can-logout
    bug/as-an-admin-when-i-select-a-menu-item-i-see-a-highlight
    
    feature/user-logout
    bug/admin-menu-item-highlight
    

    This helps developers distinguish each branch easily.

  • Prefix the branch title with the Areas of Implementation.

    ui/feature/add-cart-item
    integrate/feature/add-cart-item
    
    feature/ui-add-cart-item
    feature/integrate-add-cart-item
    

    This allows recognizing right away the specific work area of a given feature or bug via the branch. It is beneficial when stories of a single feature are divided into multiple areas of implementation and developers need to create separate branches per story.

  • Prefix the branch title with the backlog item ID when using project management tools such as Shortcut and JIRA.

    sc-6862/ui/feature/list-job-positions
    939/feature/improve-multiple-dependent-branches-management-guideline
    
    feature/sc-6862-ui-list-job-positions
    feature/939-improve-multiple-dependent-branches-management-guideline
    

    The aforementioned tools require it for their Git integration to function. While other tools, such as Pivotal Tracker, rely on the commit message content to include the backlog item ID. When having both an areas-of-implementation prefix and a backlog item ID prefix in the branch title, the ID prefix must be added before the areas-of-implementation one. Having a standard branch prefix convention will be quite beneficial, especially when DevOps engineers want to set up some triggers for the CI pipeline using the branch title format.

All Branches Gitflow

Here is a diagram that represents the standard Gitflow for all branch types, which developers ought to follow:

All Branches Gitflow

Default Branches

  • By default, there must be 2 branches: main and develop. Both branches must be created when setting up the code repository.

  • The main branch is the version in production.

  • The develop branch is the version currently in the staging environment.

  • No one should commit directly to either the main or develop branches.

  • Avoid committing history rewrites on either the main or develop branch at all costs as it could leave the project in a dire state.

Working Branches

  • Unless in very specific cases, all feature, bug, and chore branches are preferred to be checked out locally from develop. By avoiding branching more than one node away from the main branch, we can easily avoid complex conflicts and rebasing which can take hours or days to solve.

  • The definition of what constitutes a feature, bug, or chore depends on the user story types. No code should be committed if there is not a user story for the tasks at hand.

  • Once merged, feature, bug, and chore branches should be deleted to keep only the default and active branches.

Releases Branches

  • Release branches must be checked out locally from the develop branch.

  • Release branches are required when opening a pull request to merge code to the main branch. Working branches are not allowed to be merged directly into the main branch.

  • The name for release branches must contain the corresponding semantic version number.

    release/1.0
    release/v1.0
    
    release/1.0.0
    

Hotfix Branches

  • Hotfix branches must be checked out locally from the main branch (or the current release branch). This is the only type of branch that is allowed to fork directly off of the main branch.

  • As soon as the fix is completed, it has to be merged into the main branch (or the current release branch), and the main branch needs to be tagged with an updated version number (e.g. update from 1.0.1 to 1.0.2).

  • Once the fix is applied on the main branch, the fix can be merged back to the develop branch by opening a pull request from the latest main branch.

Branches Dependencies

During the development process, there are plenty of occasions that developers need to get some or all the changes from under-reviewing or working branches for a completely new branch. Here is the guide for handling some common situations that arise from this requirement.

Get specific commits from an existing branch

  • Make sure the existing branch has its individual commits functional and buildable before getting them. There can be situations where the entire branch can be built successfully and the branch implementation is functional as expected, but its individual commit isn’t implemented properly. For example, a commit A contains a build fail issue (i.e. layout linking problems, a small typo, etc.) and it is fixed in subsequent commit B but only commit A is needed in the new branch.

  • Coordinate with the owner of the existing branch about ensuring proper commits if you are not the author.

  • Create the new branch from the develop branch.

  • Apply the cherry-pick command for the commits from the existing branch that need to be included in the new branch.

    Get some commits

    This is an example of getting a single commit B from an existing branch that is still under review for a new branch. If more individual commits are needed, simply repeat the cherry-pick command per each commit. In case the needed commits are in a sequence, cherry-picking a chain of commits is also feasible with a single command (e.g. when we want to get both A and B, simply run git cherry-pick A^..B).

Get all changes from an existing branch

  • Make sure the existing branch is functional and runnable before getting all changes.

  • Coordinate with the owner of the existing branch about its readiness if you are not the author.

  • Create the new branch from the top commit of the existing branch (chain the new branch).

  • Working on the new branch and performing frequent checks on the existing branch for new updates.

  • Perform rebasing on top of the existing branch if it introduces new changes.

    Get all commits

    This is an example for getting all commits from an existing branch that is still under review for a new branch. Pull requests on source control platforms can automatically update the base branch of the new branch if the existing branch is merged at a later time.

Get changes from multiple existing branches

  • First and foremost, consider merging some of these existing branches into develop before working on your next branch. Working with teammates to review and merge the dependent code is often the most effective and efficient way to move forward in such a situation. In some rare cases, this will not be possible (e.g. external blockers), only then shall the below recommendations be considered.

  • Depending on how existing branches are organized, there could be different approaches formulated. In the end, the main idea is to keep a consistent behavior with the single-existing-branch cases from above.

  • Apply branch chaining for getting all the changes and apply cherry-picking for just getting some particular commits from existing branches when applicable.

  • In case using branch chaining is not feasible (e.g. existing branches are not stacking on top of each other, need commits from different branches, etc.), cherry-picking is the preferable option to go with.

  • Limit the amount the existing branches to be included in the new branch to a maximum of 3.

  • Prefer to limit the number of maximum commits per branch to 10. Getting the changes and handling them from more than 3 branches and 10 commits per branch can introduce a lot of overheads and increase the occurrence chance of complex conflicts. Regarding what a standard commit must be like, developers can refer to the Committing Code section.