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

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.

[sourcecode language=”bash”]
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
~
[/sourcecode]

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.

[sourcecode language=”bash”]
$ 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? []
[/sourcecode]

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.

[sourcecode language=”bash”]
git remote add origin git@github.com:Adron/git-flow-example.git
[/sourcecode]

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

[sourcecode language=”bash”]
$ git status
On branch develop
nothing to commit, working directory clean
[/sourcecode]

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.

[sourcecode language=”bash”]
$ 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
[/sourcecode]

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“.

[sourcecode language=”bash”]
slc loopback
[/sourcecode]

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

[sourcecode language=”bash”]
slc run .
[/sourcecode]

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

[sourcecode language=”bash”]
$ 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’
[/sourcecode]

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

[sourcecode language=”bash”]
$ 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’
[/sourcecode]

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.

[sourcecode language=”bash”]
$ 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’
[/sourcecode]

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.

[sourcecode language=”bash”]
$ 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
[/sourcecode]

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.

[sourcecode language=”bash”]
git flow feature start add_model_flight
[/sourcecode]

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.

[sourcecode language=”bash”]
$ 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.
[/sourcecode]

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

[sourcecode language=”bash”]
git add -A
git commit -m ‘Added the flight model.’
git flow feature finish add_model_flight
[/sourcecode]

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

[sourcecode language=”bash”]
git flow feature start add_model_airport
[/sourcecode]

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

[sourcecode language=”bash”]
$ 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
[/sourcecode]

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

[sourcecode language=”bash”]
git add -A
git commit -m ‘Added the airport model.’
git flow feature finish add_model_airport
[/sourcecode]

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

[sourcecode language=”bash”]
git flow release start v1_release
[/sourcecode]

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

[sourcecode language=”bash”]
git flow release publish v1_release
git flow release finish v1_release
[/sourcecode]

…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!