Skip to content

Branching

John Pocock edited this page May 30, 2022 · 8 revisions

Branch Naming

Main Branches

The main master and develop branches names will not change and these branches will not be deleted.

Supporting Branches

Supporting branches should have a prefix so that they can be easily identified or searched for.

Branch Type Prefix Example Used for
Feature feature- feature-shiny-new Working on a new feature. General use branch for working on a feature.
Hotfix hotfix- hotfix-crash-on-import Fixing a critical bug.
Release release- release-v1.0.0 Preparing a release.
Examples example- example-slide-info Adding example code / notebooks.
Bugfix bug- bug-slide-info-format Working on a bug fix.
Dev-Ops dev- dev-code-coverage Working on a developer tools, operations tools or utility e.g. Travis or code coverage configurations.
Tests test- test-slide-info Addition or modification of tests. If adding code and test prefer feature.
Documentation doc- doc-advanced-usage Adding to or editing documentation or docstrings. If adding code and docs prefer feature.
Enhancement enhance- enhance-wsireader-inherit Enhancement of existing code.

Creating A Branch

git checkout -b feature-shiny-new

This will create a new branch off of the current branch.

Branching

Flow

This repo follows Vincent Driessen's wildly popular git flow model of branching. Please do read his blog post for the full rundown at https://nvie.com/posts/a-successful-git-branching-model/. Below is just a condensed version.

Main Branches

Two main branches are active indefinitely for the lifetime of the repo: master and develop. Master is the default branch created by git. This branch contains a tagged commit for each release of the package. The develop branch is considered to be the main branch where HEAD points to the current working state of the repo. This is also called the "integration branch". When the develop branch is ready to be released as a new version, it is merged into master and tagged. A tag on a commit triggers the Travis continuous integration system to automatically build and release the package on PyPi as well as it's documentation on ReadTheDocs.

             develop        main

                │             │
                                   ╭╌╌╌╌╌╌╌╌╌╌╮
                │           ╭─┴─╮  ╎ Initial  ╎
              ╭───╮    ┌────│   │◀─╎production╎
              │   │◀───┘    ╰─┬─╯  ╎ version  ╎
              ╰───╯           │    ╰╌╌╌╌╌╌╌╌╌╌╯
                │             │
                ▼             │
              ╭─┴─╮           │
              │   │           │
              ╰─┬─╯           │
                │             │
                ▼             │
              ╭───╮           ▼
              │   │────┐    ╭─┴─╮
              ╰───╯    └───▶│   │
                │           ╰─┬─╯
                ▼             │
              ╭─┴─╮           │
              │   │           │
              ╰─┬─╯           │
                │             │
                ▼             │
              ╭───╮           ▼    ╭╌╌╌╌╌╌╌╌╌╌╮
              │   │────┐    ╭─┴─╮  ╎   Next   ╎
              ╰───╯    └───▶│   │◀─╎production╎
                │           ╰─┬─╯  ╎ release  ╎
                ▼             │    ╰╌╌╌╌╌╌╌╌╌╌╯
              ╭─┴─╮           │
              │   │           │
              ╰─┬─╯           │
                │             │
                ▼             │
              ╭───╮           ▼    ╭╌╌╌╌╌╌╌╌╌╌╮
              │   │────┐    ╭─┴─╮  ╎   Next   ╎
              ╰───╯    └───▶│   │◀─╎production╎
╭╌╌╌╌╌╌╌╌╌╌╮    │           ╰─┬─╯  ╎ release  ╎
╎ Work in  ╎    ▼                  ╰╌╌╌╌╌╌╌╌╌╌╯
╎ progress ╎  ╭─┴─╮           │
╎ on "next ╎─▶│   │
╎ release" ╎  ╰─┬─╯           │
╰╌╌╌╌╌╌╌╌╌╌╯
                │             │

Supporting Branches

Some supporting branches may also be used to allow parallel development. These are typically: hotfixes, feature branches, release preparation. These branches are removed when no longer needed.

feature        develop

   │              │

   │              │
                ╭───╮
   │            │   │
                ╰───╯
   │              │
                  ▼
   │            ╭─┴─╮
 ╭───╮     ┌────┤   │
 │   │◀────┘    ╰─┬─╯
 ╰───╯            │
   │              ▼
   │            ╭───╮
   │            │   │
   │            ╰───╯
   │              │
   ▼              ▼
 ╭─┴─╮          ╭─┴─╮
 │   │          │   │
 ╰─┬─╯          ╰─┬─╯
   │              │
   ▼              ▼
 ╭───╮          ╭───╮
 │   │────┐     │   │
 ╰───╯    │     ╰───╯
   │      │       │
          │       ▼
   │      │     ╭─┴─╮
          └────▶│   │
   │            ╰─┬─╯

   │              │

Feature Branches

See https://nvie.com/posts/a-successful-git-branching-model/#feature-branches

Feature branches (AKA topic branches) should, in general, branch off of develop and be merged back into develop.

Creating a Feature Branch

$ git checkout -b feature-example develop
Switched to a new branch "feature-example"

Incorporating a finished feature on develop

$ git checkout develop

Switched to branch 'develop'

$ git merge --no-ff feature-example

Updating ea1b82a..05e9557
(Summary of changes)

$ git branch -d feature-example

Deleted branch feature-example (was 05e9557).

$ git push origin develop

The use of --no-ff (no fast-forward) is important here. Also note that GitHub pull requests use --no-ff by default when merging.

From Vincent's post:

The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature. Compare:

 

           feature        develop                          develop

              │              │                                │

              │              │                                │
                           ╭───╮                            ╭───╮
              │            │   │                            │   │
                           ╰───╯                            ╰───╯
              │              │                                │
        ┌──                  ▼                                ▼
        │     │            ╭─┴─╮                            ╭─┴─╮
        │   ╭───╮     ┌────┤   │                            │   │
        │   │   │◀────┘    ╰─┬─╯                            ╰─┬─╯
        │   ╰───╯            │                                │
        │     │              ▼                                ▼
        │     │            ╭───╮                            ╭───╮
        │     │            │   │                            │   │
        │     │            ╰───╯                            ╰───╯
        │     │              │                                │
        │     ▼              ▼                                ▼     ──┐
feature─┤   ╭─┴─╮          ╭─┴─╮                            ╭─┴─╮     │
        │   │   │          │   │                            │   │     │
        │   ╰─┬─╯          ╰─┬─╯                            ╰─┬─╯     │
        │     │              │                                │       │
        │     ▼              ▼                                ▼       │
        │   ╭───╮          ╭───╮                            ╭───╮     │
        │   │   │────┐     │   │                            │   │     ├──feature
        │   ╰───╯    │     ╰───╯                            ╰───╯     │
        │     │      │       │                                │       │
        │            │       ▼                                ▼       │
        └──   │      │     ╭─┴─╮                            ╭─┴─╮     │
                     └────▶│   │                            │   │     │
              │            ╰─┬─╯                            ╰─┬─╯     │
                                                                    ──┘
              │              │                                │

             git merge --no-ff                            git merge
                                                           (plain)

 

In the latter case, it is impossible to see from the Git history which of the commit objects together have implemented a feature---you would have to manually read all the log messages. Reverting a whole feature (i.e. a group of commits), is a true headache in the latter situation, whereas it is easily done if the --no-ff flag was used.

 

Yes, it will create a few more (empty) commit objects, but the gain is much bigger than the cost.

 

In short, --no-ff preserves the fact that development happened in parallel rather than sequentially. Fast forwarding, the default merge behaviour, makes the history appear as if the commits have all been applied sequential on top of the current HEAD of the develop branch. This is technically what is actually happening when merging. However, the history is usually more clear if the parallel development history is preserved.

 

Note that you don't necessarily ALWAYS want to use --no-ff. For example, if you have made a single commit feature branch then a plain merge will create a cleaner history.

  For more on this discussion see this stack overflow: <https://stackoverflow.com/questions/18126297/when-to-use-the-no-ff-merge-option-in-git

See Also

https://docs.microsoft.com/en-us/azure/devops/repos/git/git-branching-guidance?view=azure-devops