A few weeks ago I was introduced to the world of version control software by my employer. It was when I had to work from home for the week due to pneumonia and we were in the middle of rolling out Git for all our source code. My assignments was to read up on Git, learn the jargon, understand the inner workings, and just be fairly well versed on the topic so I can maybe help write scripts in the future. Going into it, I had a rough idea of what version control software was used for and that was to keep track of changes and be able to go back to earlier versions of the source. What I didn’t know was how this simple idea can significantly change your workflow and how you write your code. In my three weeks of learning about Git I’ve since rolled it out on my own coding projects and have developed all sorts of new coding habits. It’s a wonderful piece of software that I believe will make me grow as a programmer.
As I’ve said, version control software basically keeps track of every change you make to your source code allowing the user to revert back to any version of the code. The beauty of this is that you can easily go off and make changes to your code without fear. It gives you a sense of security in that there will always be a copy of your code that both works and compiles correctly. It’s this idea that completely changed how I write code now. I can now make sweeping changes/experiments to my source without having to manually make a backup of my code base or commenting out huge portions of my old code. I just simply delete everything I want to change and replace it with a my new broken code. Then I go on and make changes to that broken code until it hopefully works. If it turns out to be a dead end I’d just go back to my old code that did work and it was like nothing ever happened. There are other benefits to source control such as being able to track changes, but it’s that one idea that pretty much changes the game and enables all kinds of new workflows.
How this is implemented in software though is another interesting topic entirely. Version control basically comes in two different flavors: you’ve got your client-server model which has a central server where users can obtain any version of the source and you’ve got the distributed model where every user has their own copy of the entire source base. Software can opt to store only the diffs as new versions are added or they can store each and every version of the file. They all use clever compression techniques given the repetitive nature of the archived contents. Git uses the distributive model which is what I’ll be writing about. To summarize Git, it’s a very clever way of storing files as they change. A Git repository contains a directory containing each and every version of the source that has been “commited” and a working directory that contains the source code you’re currently working on. Using Git, you “check out” whichever commit you want to make changes to and this replaces your working directory. It’s a very quick and painless process and if you have work that’s not quite ready to commit, you can always “stash” a copy of your work to come back to in the future. When you start using Git with multiple users it gets even more interesting. Because it’s distributed, each user has a local copy of each version of the source. They can push/pull/fetch with a remote server when they need/want too, but for the most part development can be done completely on your own. You can even sync up with other users and collaborate with their source if needed.
With these collaborative features the entire workflow and how releases are maintained changes. In Git, this is referred to as Git flow. The key to understanding Git flow is branching and merging, or rather breaking off from a stable commit and going on to develop some new code that is to be incorporated back into the main trunk. In Git flow you have 5 types of branches you need to understand: the master branch which maintains the most stable code in a release ready state, off of the main branch you can have “hot fixes” which fix critical bugs in released software, develop is the branch that goes off the last master release and is where new code is written, new code is written within feature branches to be merged back into develop, and finally you have release branches which prepare the develop branch for a merge with master. I personally really like this workflow, because it allows changes/development to be compartmentalized. It also makes excellent use of version control’s promise of maintaining a stable code base.
In my time with Git I’ve been responsible for preparing a repository for use on a pretty large firmware project that encompasses at least 6 different hardware products. It’s a pretty tall order for me as a very new engineer and it was intimidating at first, but I was happy to take on the challenge. The difficulty in this task is mostly preparing the code base for distribution and getting it into a position where other collaborators can join the project and actually start to develop their own branches. A huge part of this is software architecture and how to even share a code base between several different products that don’t even share a common processor. I’ve been finding myself moving code around, trying new implementations, incorporating code for other products, and all sorts of things that could introduce bugs. Prior to source control this would’ve been a painful process of maintaining messy source code with huge portions of redundant commented out code. Now I just branch, replace, test, and merge. The first time I was able to do an operation like that I fell in love with source control.