Git Flow

 

This page summarizes the gitflow source control process loosely based on the work of Vincent Driessen. The summary is intended as a reminder of how this process is applied on a day-to-day basis.

Model

This model employs the following types of branches:

  • master: Production ready and released (there is only one master branch, which is also permanent);

  • develop: Centralized repo for integrating current feature development – when ready for release, it will be merged to master (there is only one develop branch, which is also permanent);

  • feature: there are multiple branches under feature at any given time (e.g., /feature/GP1-403-2 and /feature/GP1-407-9); these branches are removed once merged to develop;

  • release: there is one release branch for each release; it is used to isolate the development and master branches from the activities necessary to prepare a release (release version meta data and last minute bug fixes); these branches are removed once merged to master and develop;

  • hotfix: like a release branch, but unplanned: the intention is to make only the bare minimum change(s) to fix an issue found with a released version, and to merge those changes back to master and develop.

From a GIT point of view, there is no technical difference between these branch types. Maintaining the branch structure and the flow between branches is a discipline that is enforced by the development team.

Roles & Responsibilities

Role

Responsibilities

GOBii Personnel

Testing Environment

Role

Responsibilities

GOBii Personnel

Testing Environment

Process owner

  • determines official start of release cycle

  • determines and informs [process admin] when release tag should be created

  • determine code-freeze for release/x.x

@Yaw Nti-Addae

@Vishnu Govindaraj

N/A

Process admin

  • maintain master

  • ensure hotfixes are synced with master and develop

  • ensure [repo owners] create their release/x.x

  • create tag and realease/x.x

@Roy Petrie

@Joshua Lamos-Sweeney

N/A

CI owner

  • create Bamboo plan branch for release/x.x

  • Ensures all tests are passing and inform process owner if otherwise

@KevinPalis

N/A

CD owner

  • deploy and test release/x.x

@Roy Petrie

CG_Test VMs

QA

  • test release/x.x

  • determine if release/x.x is good to release

  • determine build number to be deployed

@Elizabeth Jones

@Yaw Nti-Addae

QA_test

App_test

Repo owner(s)

  • create release/x.x branch from develop

  • ensure all feature branches slated for a release are merged to develop

  • enforce code-freeze

  • ensure pruning of feature branches

Gobiiproject - @Joshua Lamos-Sweeney

DataWarehouse - @KevinPalis

Loader UI - @Angel Manica Raquel

Web loader UI - @Vishnu Govindaraj

Pedver - @Vishnu Govindaraj

Timescope - @Angel Manica Raquel

Marker Portal - @Roy Petrie

KDC - @KevinPalis

 

Developer

  • create feature/GDM-XYZ

  • ensure feature/GDM-XYZ is up-to-date with develop

  • assign code reviews

  • deploy and test feature/GDM-XYZ

  • pull request to merge feature/GDM-XYZ to develop

  • deploy and test bugfix/x.x.y

  • pull request to merge bugfix/x.x.y to master and develop

 

FXN_test

CBSUGOBiiXVM[X]

Release Cycle

Process

Type

Branch From

Merges To

Lifecycle

Naming Convention

Definition

Type

Branch From

Merges To

Lifecycle

Naming Convention

Definition

master

n/a

n/a

one permanent branch

master

  • Always production-ready;

  • Tagged per each release.

develop

master

n/a

one permanent branch

develop

  • Latest development changes for next release;

  • Source for nightly builds;

  • Must pass regression tests

feature

develop

develop

multiple branches that are deleted after merge

feature/<jira_id>

ex:

feature/GDM-487

feature/GDM-660

OR feature/<jira_id>-<num or label>

ex:

feature/GDM-588-1

feature/GDM-588-normalize_names

  • The purpose is to develop a new feature;

  • Named per user story task ID (e.g., feature/GP1-487) to avoid name clutter;

  • Merged to develop when ready, where "ready" means:

    • The branch does not break develop:

    • Therefore, the developer has merged develop into the branch and bench-tested it for compilation and general functionality;

    • Another developer has:

      • Code-reviewed the new code;

      • Verified that the new code does what it is supposed to do according to the user story's acceptance criteria;

bugfix

release

develop

multiple branches that are deleted after merge

bugfix/<jira_id>

ex:

bugfix/GSD-487

bugfix/GSD-660-2

bugfix/GSD-588-normalize_names

  • The purpose is to develop a significant bugfix;

  • Named per user story task ID (e.g., bugfix/GSD-487)

  • Merged to develop when ready, where "ready" means:

    • The branch does not break develop:

    • Another developer has:

      • Code-reviewed the new code;

      • Verified that the new code does what it is supposed to do

release

develop

develop and master

multiple branches that are deleted after merge

release/GDM_<release_number>

ex:

release/1.0-Cascadilla

 



  • The purpose is to prepare for merge to master and for release:

    • Update release-related metadata (e.g., project version files, release tracking tables, etc.);

    • Last-minute bug fixes;

  • This frees up the develop branch for work that continues beyond the current release;

  • Merged to master and develop when the branch has been tested.

hotfix

master

develop and master

multiple branches that are deleted after merge

hotfix/<major.minor_version>-<jira_id_for_bug>

ex:

hotfix/1.0.1-GP1-832

  • Similar to a release branch except that:

    • It is branched from master;

    • It is unplanned;

    • It is intended to fix one or more specific issues.

Procedures

In all cases, when merging use the --no-ff flag. Doing so 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

Feature Branch

Create the branch:

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

 

Merge the branch back to develop:

 

--no-commit

'–no-commit' added because of an issue with merging old changes overwriting new changes. Once you've done a --no-commit merge, check your files for differences, then commit, then merge. If you see a file that's not yours in the merge, something is likely wrong. Talk to the owner of the file!

JDLS-Note: This is superstitious cargo-culting, but still good practice to check differences before pushing, either through recommitting yourself, or just a git log -N.

$ git checkout develop Switched to branch 'develop' $ git merge --no-ff --no-commit myfeature Updating ea1b82a..05e9557 (Summary of changes) $ git commit On branch develop (Summary of changes) $ git branch -d myfeature Deleted branch myfeature (was 05e9557). $ git push origin develop

Release Branch

Create the release branch:

$ git checkout -b release-1.2 develop Switched to a new branch "release-1.2" $ ./bump-version.sh 1.2 Files modified successfully, version bumped to 1.2. $ git commit -a -m "Bumped version number to 1.2" [release-1.2 74d9424] Bumped version number to 1.2 1 files changed, 1 insertions(+), 1 deletions(-)

 

Merge the release branch to master and tag:

 

Merge the release to develop:

JDLS-Note: --no-ff is also cargo-culting.

Remove the release branch:

Hotfixes

Create the hotfix branch:

 

Merge to master:

 

Typically, you would merge the hotfix to develop:

 

However, if a release branch currently exists, the hotfix changes need to be merged into that release branch, instead of to develop. When the release branch is merged to develop, the hotfix will be back-merged along with it.

 

Remove the hotfix:

Useful Git Commands

Tagging

Oddly, tags don't get pushed to the server automatically along with your other commits. In order to push your tags, execute

 

To show a list of tags in the current branch:

Repo Status

View uncommitted changes

 

 

Show which branch your local repo is tracking

 

 

Show the last N commits

And there are loads of options for the log command.

Diff Commits

 

 

Branch Management

Create A New Branch

 

Switch To A Different Branch

Say you cloned a repo from master. By default, your local repository is tracking master. We don't commit working code directory to master. Therefore, you will want to switch to a feature branch to do your develop. To switch to a branch that has already been created:

JDLS Note - Don’t do this without a fetch! You’ll get the old version, and then have a sad.

Create a branch from a specific commit

Typically, you want to want to branch from the HEAD of the current branch (i.e., from the latest commit). However, there may be cases that you want to make a branch from an earlier point.

 

That is, create a branch called "test" from the branch "dev" as of the commit referenced by the specified UUID.

JDLS Note - if you are doing this, you will very shortly be having a bad day.

Merge Specific Files from A Branch

Suppose you created a branch in which you unintentionally made changes that should thematically have been in another branch. You now want to bring those changes into the branch they were intended for.

 

The key thing to notice is that the second checkout command specifies the branch from which you want to get the modified files, which is followed by a space-separated list of the files. Doing so does not change the current branch. But it does stage the files you want in the current branch.

 

JDLS Note:

is the same as ‘remove all my changes from branch head to this file’

Whoops -- I Made Changes On the Wrong Branch (but didn't commit yet)

Example: You created a new branch for a user story in bitbucket, and began to modify code without realising that you had not checked out the new branch locally. You will:

  1. Stage your current changes (git add.);

  2. Stash your current changes (git stash);
    This records the current state of your working directory and then resets the working directory to the most recent commit in the repo being tracked by your working directory;

  3. Check out the branch on which you had intended to make the changes;

  4. Unstash the changes to working directory (git stash apply)
    This effectively takes the changes you recorded with git stash and applies them to the working directory.

 

JDLS - git stash, git checkout <right branch>, git stash pop.

Whoops – I didn't mean to commit that

https://sethrobertson.github.io/GitFixUm/fixup.html.

JDLS Note- Or, you know, git revert.

Whoops - Not only did I commit, but I also pushed

In other words, we need to revert HEAD to a previous version and blow out all history after that point. Changes like this can only be done with the full consent of the senior devs.

Don't do this:

http://stackoverflow.com/questions/5816688/resetting-remote-to-a-certain-commit

JDLS Note: Doesn’t actually remove info from the chain. If you pushed passwords, look up BFG Cleaner or some other repo cleaner. You’re in for a loong day.

Rename a branch

Apparently you cannot do this in bit bucket. [JDLS Note - clone it to the new name, then delete the old one.] So go to your GIT bash and:

 

More Information

Atlassian Gitflow - https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow

Caveat Emport - http://stevelosh.com/blog/2013/04/git-koans/

 

JDLS - Even invoking the help menu teaches you how to use git!

 

The novice, wanting to partake of Master Git’s vast knowledge, said: “git branch --help”.

Master Git sat down and lectured her on the seven forms of git branch, and their many options.

They resumed walking. A few minutes later they encountered an experienced developer traveling in the opposite direction. He bowed to Master Git and said “git branch -h”. Master Git tersely informed him of the most common git branch options. The developer thanked him and continued on his way.

“Master,” said the novice, “what is the nature of long and short options for commands? I thought they were equivalent, but when that developer used -h you said something different than when I said --help.”

“Perspective is everything,” answered the Master.

The novice was puzzled. She decided to experiment and said “git -h branch”.

Master Git turned and threw himself off the railing, falling to his death on the rocks below.