Glenn Stovall


Metrics-Driven Business and Software Design

How I Use Git

git is a very powerful and flexible tool. With this power and flexibility comes a daunting amount of choices to make in how to manage your code with it. Here is the current setup I’ve used on both personal solo projects and professional jobs with other developers that has worked for me and saved me a lot of headaches.

Setting Up

Set up the Initial Repository

git init
git commit -am 'initial commit'
git tag -a '0.0'

Simple enough, right? I usually do this once I’ve installed whatever framework I am using for a project and done whatever configurations are necessary. At this point I’ll go ahead and set up the .gitignore file based on whatever kind of project I am working on. You’ll notice I also use tags for keeping track of the version number of the project.

Create a dev branch

git checkout -b dev

Next, I will create the ‘dev’ branch. I will treat master as the ‘production’ branch. All code will be tested integrated in the dev branch, and only merged with master when the code is ready to be shipped. If you are following and agile development pattern, this will usually be at the end of each sprint. Otherwise, it could once a predetermined set of features has been completed.

Set up Bitbucket and Heroku Staging Environment

git remote add origin [Bitbucket repository URL]
git push origin master
git push origin dev
git remote add staging [Heroku repository URL]
git push staging dev:master

I use Bitbucket for most private projects. Github has a lot of nice features, and could work just as well here but it’s hard to compete with the free cost of private repositories over at Bitbucket. Regardless of which service you prefer, the important reason for doing this is that now you have a remote backup of your work if anything happens to your computer. Now I have a backup of my code online that it easily manageable, that comes along with a wiki for documentation and simplistic bug tracking. If I am working with other people, we now have a central point of communication as well. I usually set up a Heroku project for a staging server as well. This way I have a way of demoing functionality before it is ready to be shipped. If Heroku doesn’t work for you (i.e. a PHP project) this can be any server you would like to use to host your code for staging / testing.

At this point, we should have everything we need to get started on a project.

Developing

New Features

git checkout dev
git checkout -b feature_branch

_Note: git checkout -b feature_branch is shorthand for git branch feature_branch; git checkout feature_branch

How you define a feature is completely up to you and your development practices. It could be a user story, or an issue ticket for example. When possible, I like to keep feature branches small. The reason for feature branches is that this way no feature is dependent on another when merging and deploying code. If you are working on two separate features, and another developer is working on two more, and you were all on the development branch, you would be unable to push parts of it to staging or master without pushing all of it. In git, branching is cheap, and merging is easy. This is one situation where using a lot of smaller branches can be very advantageous.

If you are using a staging server, you can also use it to demo one particular feature:

git push staging feature_branch:master

Integrating Features

git checkout dev
git merge feature_branch 
git branch -d feature_branch

Once the feature is completed and tested, it is ready to be merged back into the dev branch. At this point, you fix any conflicts that arise, and run any tests you have to make sure that the integration was successful.

Maintaining

Regular Bug Fixes

I treat bug fixes just like a feature branch. Any bug gets its own branch, and once it is fixed, it is merged back into dev. However. sometimes you may have a bug that is an emergency, and it needs to be fixed on production instantly without going through all the code in the dev branch. What then?

Hot Fixes

git checkout master
git checkout -b hotfix_branch

This is the only time I’ll branch off of master besides dev, and this should only be reserved for emergencies. Once the fix is put in, the hot fix is merged into both the master and dev branches. This way dev will have the fix and not accidentally introduce it later, and the live code can be fixed quickly.

git checkout master
git merge hotfix_branch
git tag -a '1.0.1'
git checkout dev
git merge hotfix_branch 
git branch -d hotfix_branch
git push origin dev
git push origin master

Shipping

Releasing and Update

git remote add production [production_url]
git checkout master
git merge dev
git tag -a '1.1'
git push production master

Once you are satisfied with the state of dev and are ready to push it live, dev gets merged into master. Every time code is merged into master, it gets tagged with a version number. I prefer to follow the semantic versioning guidelines If a production remote is not added, usually one gets added here, and code is pushed there.

This setup allows you to keep you to work effortlessly in development without interfering with production, and keeps new features and fixes in development decoupled from one another, allowing for efficient development and simple collaboration with other developers.

How do you use git in your work flow? Discuss on Reddit