A couple of years ago, a buddy of mine, Jerrod Blavos, turned me onto using Subversion (svn) for our projects that we would work on together. At the time, I was eating up any new technology I came across, wanting to learn more and try to become somewhat knowledgeable about the subject. Svn was a great tool to use, I still use it on some projects, but for some reason I never got the urge to want to dive into it. This may partly be due to the developers I worked with took the harder tasks of branching and merging out of my hands which allowed me to focus on my code knowing whole heatedly, my code was backed up.
As I mentioned, any developer I worked with on projects usually took the reins and created branches and fixed any merge conflicts that arose, leaving me out of the process. About a couple of months ago, I mentioned to Paul Hepworth at Real Travel that I did not think svn was working well for our workflow.
Like most development cycles, we had two branches in svn: trunk and development. This is where the complexity came in. Some of us would develop on development and while others would develop on trunk. When it came time to merge our code, Paul would take on the daunting task to get everything synced up. Just about every time, Paul would run into merge conflicts and sometimes we would end up with a regression of our code base. To add to the brokenness of this workflow, half the time we would dump one of the branches that we merged out of and then create/merge back into the fresh branch. We had to try something different so we could put the ownership of the merges and branching into every developer on the team hands. Git was going to allow us to do just that.
When I first brought up the subject about using Git to the Real Travel team, I wanted to make sure that I could be an valuable resource. I wanted to learn the ins and outs of Git (still learning as I write) so that the team could come to me with questions and I could answer them. This would also help alleviate Paul as the only go to person with the answers. So I purchased a book and started creating, branching, committing, pushing, pulling, etc until I understood the new workflow process we were about to take on.
For those not familiar with Git commands, I suggest going here to get a brief overview to understand what I will be talking about.
Git goes one step further than svn and offers a “local” repository directly on your working machine. I know some may clamor that Git and svn can not be compared because of their mechanics, but truly this is one of the greatest things that comes with Git. Not to mention that it also only tracks changes within a file, not the whole file itself.
Having this local repository allows for you to do all your branching, commits and merging directly on your machine without affecting the remote. Using this to your advantage is key when dealing with your own branching strategy.
The rule of thumb when doing a branching strategy is never work directly on the remote branch on your local. When ever you have a certain task on a project, always create a local branch off of the remote branch. This will aid in keeping merge conflicts out of the master code. Another good rule of thumb is to agree on what remote branch everyone should be working on. An example workflow below, assuming you are developing on the “master” branch:
$ > git checkout -b foo_from_master
...Do some coding...
$ > git commit -a -m "Some message here"
... Do some more coding...
$ > git commit -a --amend
Now we have a local branch that has strayed from the head of the master branch. It is important to note in your branch what you branched from, hence “_from_master” in the branch name. We now want to update our new local branch with the remote, because we know there is new code we need to use from it.
$ > git checkout master
$ > git pull
$ > git checkout foo_from_master
$ > git rebase master
...Resolve any conflicts...
Rebase is the key term here. What that does is fast-forward and merge your local branch with the new code from the remote master you pulled while preserving all your history in both branches. Of course you can do a “git fetch” too, but that doesn’t actually merge the code or history, just makes it “available.”
Once all conflicts have been resolved and you are done with your coding on your local branch, it is time to merge it into your master. If you did this workflow properly, you should not have any trouble merging code upstream.
$ > git checkout master
$ > git pull # just in case there might be new code, then you would need to repeat steps above
$ > git merge foo_from_master
$ > git push
If all goes well, then you have successfully managed your own branches and merging without having to look to help from another developer.
Of course there are plenty of other great things that can be done with Git, including creating remote branches directly from local branches and tagging releases, but that shall be saved for a later post.