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.
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.
git checkout dev git checkout -b feature_branch
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
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.
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?
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
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