No excuse not to have your branching strategy taken care of, because: git-flow

First, get it installed. This takes less than a minute, at least on a *nix based machine. I’ve no idea what it takes on Windows, but hey, at least it’s available there too! I did a clean curl and install as shown. It took about 14 seconds solely because I wasn’t typing very fast today.

12:28 $ curl -L -O https://raw.github.com/nvie/gitflow/develop/contrib/gitflow-installer.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  2145  100  2145    0     0   1732      0  0:00:01  0:00:01 --:--:--  1732
~
12:28 $ sudo bash gitflow-installer.sh
Password:
### gitflow no-make installer ###
Installing git-flow to /usr/local/bin
Cloning repo from GitHub to gitflow
Cloning into 'gitflow'...
remote: Counting objects: 1407, done.
remote: Total 1407 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1407/1407), 623.29 KiB | 428.00 KiB/s, done.
Resolving deltas: 100% (689/689), done.
Checking connectivity... done.
Updating submodules
Submodule 'shFlags' (git://github.com/nvie/shFlags.git) registered for path 'shFlags'
Cloning into 'shFlags'...
remote: Counting objects: 454, done.
remote: Total 454 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (454/454), 130.91 KiB | 0 bytes/s, done.
Resolving deltas: 100% (337/337), done.
Checking connectivity... done.
Submodule path 'shFlags': checked out '2fb06af13de884e9680f14a00c82e52a67c867f1'
install: gitflow/git-flow -> /usr/local/bin/git-flow
install: gitflow/git-flow-init -> /usr/local/bin/git-flow-init
install: gitflow/git-flow-feature -> /usr/local/bin/git-flow-feature
install: gitflow/git-flow-hotfix -> /usr/local/bin/git-flow-hotfix
install: gitflow/git-flow-release -> /usr/local/bin/git-flow-release
install: gitflow/git-flow-support -> /usr/local/bin/git-flow-support
install: gitflow/git-flow-version -> /usr/local/bin/git-flow-version
install: gitflow/gitflow-common -> /usr/local/bin/gitflow-common
install: gitflow/gitflow-shFlags -> /usr/local/bin/gitflow-shFlags
~

For installation instructions check out the link here: https://github.com/nvie/gitflow/wiki/Installation

Now that everything is setup. Here’s the quick getting started of creating a repo, linking it up to a remote and working in a repository. The first step is to initialize a new repo.

$ git flow init
Initialized empty Git repository in /Users/adronhall/Coderz/gitflowing/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]

How to name your supporting branch prefixes?
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []

To note, if I added the -d switch to the command all of the defaults would have been accepted. Since I just created this repository out of the blue, it doesn’t have a remote setup yet. So I’ll add that next.

git remote add origin git@github.com:Adron/git-flow-example.git

When I run a git status I can see that I’m currently on the develop branch of the repo.

$ git status
On branch develop
nothing to commit, working directory clean

From here, I needed to start a feature. I started this with the following command and then created a new Strongloop Loopback API Server Application with the following commands.

Starting a new feature.

$ git flow feature start create_base_app
Switched to a new branch 'feature/create_base_app'

Summary of actions:
- A new branch 'feature/create_base_app' was created, based on 'develop'
- You are now on branch 'feature/create_base_app'

Now, start committing on your feature. When done, use:

     git flow feature finish create_base_app

Creating a new Loopback API Server App. For more on setting up a Strongloop Loopback API Server App check out the review I wrote “Framework: Strongloop’s Loopback“.

slc loopback

Now just to make sure everything ran right I ran the server app.

slc run .

With everything running ok I’m going to wrap up the feature with git-flow.

$ git flow feature finish create_base_app
Switched to branch 'develop'
Updating 128accf..18ea6b9
Fast-forward
 .editorconfig                 | 13 +++++++++++++
 .jshintignore                 |  2 ++
 .jshintrc                     | 21 +++++++++++++++++++++
 .npmignore                    | 16 ++++++++++++++++
 client/README.md              |  3 +++
 package.json                  | 22 ++++++++++++++++++++++
 server/boot/authentication.js |  4 ++++
 server/boot/explorer.js       | 23 +++++++++++++++++++++++
 server/boot/rest-api.js       |  4 ++++
 server/boot/root.js           |  6 ++++++
 server/config.json            |  5 +++++
 server/datasources.json       |  6 ++++++
 server/model-config.json      | 29 +++++++++++++++++++++++++++++
 server/server.js              | 43 +++++++++++++++++++++++++++++++++++++++++++
 14 files changed, 197 insertions(+)
 create mode 100644 .editorconfig
 create mode 100644 .jshintignore
 create mode 100644 .jshintrc
 create mode 100644 .npmignore
 create mode 100644 client/README.md
 create mode 100644 package.json
 create mode 100644 server/boot/authentication.js
 create mode 100644 server/boot/explorer.js
 create mode 100644 server/boot/rest-api.js
 create mode 100644 server/boot/root.js
 create mode 100644 server/config.json
 create mode 100644 server/datasources.json
 create mode 100644 server/model-config.json
 create mode 100644 server/server.js
Deleted branch feature/create_base_app (was 18ea6b9).

Summary of actions:
- The feature branch 'feature/create_base_app' was merged into 'develop'
- Feature branch 'feature/create_base_app' has been removed
- You are now on branch 'develop'

That wraps up the first feature. To push this work out to the remote now, I’ll start a release.

$ git flow release start base_app
Switched to a new branch 'release/base_app'

Summary of actions:
- A new branch 'release/base_app' was created, based on 'develop'
- You are now on branch 'release/base_app'

Follow-up actions:
- Bump the version number now!
- Start committing last-minute fixes in preparing your release
- When done, run:

     git flow release finish 'base_app'

At this point I’ll also give the packages.json file an actual version number bump from 0.0.0 to 0.0.1. Now I wrap up the release and push the code to remote. First by pushing the code to the remote.

$ git flow release publish base_app
Counting objects: 30, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (25/25), done.
Writing objects: 100% (28/28), 4.05 KiB | 0 bytes/s, done.
Total 28 (delta 4), reused 0 (delta 0)
To git@github.com:Adron/git-flow-example.git
 * [new branch]      release/base_app -> release/base_app
Already on 'release/base_app'
Your branch is up-to-date with 'origin/release/base_app'.

Summary of actions:
- A new remote branch 'release/base_app' was created
- The local branch 'release/base_app' was configured to track the remote branch
- You are now on branch 'release/base_app'

Then I wrap up the release. When issuing the command, toward the end VI will launch to provide tag details and commit messages, enter these and save (Enter the message by hitting the i key, then Esc and :w to write the file within VI and :q! to escape after) the files for the release to finish.

$ git flow release finish base_app
Switched to branch 'master'
Merge made by the 'recursive' strategy.
 .editorconfig                 | 13 +++++++++++++
 .gitignore                    |  3 +++
 .jshintignore                 |  2 ++
 .jshintrc                     | 21 +++++++++++++++++++++
 .npmignore                    | 16 ++++++++++++++++
 client/README.md              |  3 +++
 package.json                  | 22 ++++++++++++++++++++++
 server/boot/authentication.js |  4 ++++
 server/boot/explorer.js       | 23 +++++++++++++++++++++++
 server/boot/rest-api.js       |  4 ++++
 server/boot/root.js           |  6 ++++++
 server/config.json            |  5 +++++
 server/datasources.json       |  6 ++++++
 server/model-config.json      | 29 +++++++++++++++++++++++++++++
 server/server.js              | 43 +++++++++++++++++++++++++++++++++++++++++++
 15 files changed, 200 insertions(+)
 create mode 100644 .editorconfig
 create mode 100644 .jshintignore
 create mode 100644 .jshintrc
 create mode 100644 .npmignore
 create mode 100644 client/README.md
 create mode 100644 package.json
 create mode 100644 server/boot/authentication.js
 create mode 100644 server/boot/explorer.js
 create mode 100644 server/boot/rest-api.js
 create mode 100644 server/boot/root.js
 create mode 100644 server/config.json
 create mode 100644 server/datasources.json
 create mode 100644 server/model-config.json
 create mode 100644 server/server.js
Deleted branch release/base_app (was a086c58).

Summary of actions:
- Latest objects have been fetched from 'origin'
- Release branch has been merged into 'master'
- The release was tagged 'base_app'
- Release branch has been back-merged into 'develop'
- Release branch 'release/base_app' has been deleted

At this point I’ve created a feature and a release for version 0.0.1 of the application I’ve just created. If the application is run the default Strongloop API Loopback Server is viewable, albeit there is nothing being served at the moment. So next I’ll add some models and related items to the server. First, start a new feature.

git flow feature start add_model_flight

Now I’ll add a Loopback model that I’ll call flight. Below that I’ve added several properties to the model including a geopoint, date and several properties that are strings.

$ slc loopback:model
[?] Enter the model name: flight
[?] Select the data-source to attach flight to: db (memory)
[?] Select model's base class: PersistedModel
[?] Expose flight via the REST API? Yes
[?] Custom plural form (used to build REST URL): flights
Let's add some flight properties now.

Enter an empty property name when done.
[?] Property name: name
   invoke   loopback:property
[?] Property type: string
[?] Required? Yes

Let's add another flight property.
Enter an empty property name when done.
[?] Property name: flightId
   invoke   loopback:property
[?] Property type: string
[?] Required? Yes

Let's add another flight property.
Enter an empty property name when done.
[?] Property name: notes
   invoke   loopback:property
[?] Property type: string
[?] Required? No

Let's add another flight property.
Enter an empty property name when done.
[?] Property name: takeoff
   invoke   loopback:property
[?] Property type: date
[?] Required? Yes

Let's add another flight property.
Enter an empty property name when done.
[?] Property name: from
   invoke   loopback:property
[?] Property type: geopoint
[?] Required? Yes

Let's add another flight property.
Enter an empty property name when done.

Now I’ll wrap up the feature and move to another feature.

git add -A
git commit -m 'Added the flight model.'
git flow feature finish add_model_flight

Then start a new model with the git-flow feature.

git flow feature start add_model_airport

I now added another model using the Loopback command as shown.

$ slc loopback:model
[?] Enter the model name: airport
[?] Select the data-source to attach airport to: db (memory)
[?] Select model's base class: PersistedModel
[?] Expose airport via the REST API? Yes
[?] Custom plural form (used to build REST URL): airports
Let's add some airport properties now.

Enter an empty property name when done.
[?] Property name: name
   invoke   loopback:property
[?] Property type: string
[?] Required? Yes

Let's add another airport property.
Enter an empty property name when done.
[?] Property name: code
   invoke   loopback:property
[?] Property type: string
[?] Required? Yes

Let's add another airport property.
Enter an empty property name when done.
[?] Property name: notes
   invoke   loopback:property
[?] Property type: string
[?] Required? No

Let's add another airport property.
Enter an empty property name when done.
[?] Property name: location
   invoke   loopback:property
[?] Property type: geopoint
[?] Required? Yes

Now I wrapped up this feature by committing the files and finishing the feature with git-flow.

git add -A
git commit -m 'Added the airport model.'
git flow feature finish add_model_airport

To finalize this and release my v1_app I’ll start a release.

git flow release start v1_release

Now I’ll publish that release and finalize it by closing the release.

git flow release publish v1_release
git flow release finish v1_release

…and that’s a wrap. For the actual repo and check out the specific git-flow branching path (with my various mistakes along the way that needed to be remerged, check out my github repo here). You can see the branch list that I’ve created here by check out this link and to see the actual branching graph. For more on git-flow be sure to check out the creator’s blog at nvie and for the block post that got this all started “A Successful Git Branching Model“.

Happy hacking, cheers!