I’m a believer. I’ve used version control before, but Marcus has convinced me that with a little known version control system called Git, written by Linus Torvalds (the creator of Linux), version control is not just about versioning, it’s about expressing yourself with your code and collaborating with others, seamlessly.
As memory serves the only time I’ve used version control in a meaningful way the system I was using was Visual SourceSafe from Microsoft. I know. Blech! It’s awful! I’ve pulled code from many a CVS or Subversion repository, but I’ve never really used them in the way they are intended to be used. Now, thanks to Marcus, I realize that version control isn’t just about versioning any more. It’s a whole methodology/ideology that makes better programmers. Here is what I mean.
Branching Inspires Wild Experimentation
Have you ever been so far down a path in your code that you just think, though you probably should, there is no way you would take a chance to re-factor due to looming deadlines or even just a simple fear that you might mess up so badly you couldn’t recover? Well, fear no more! Git provides such a simple way to create a branch of your code in which you can experiment, you won’t even give it a second thought. I won’t go into the whole setup and how to get going with Git as this is done very well elsewhere including a previous post from Marcus. I just want to point out how easy it is to branch with a single command. In Terminal.app, cd to the directory of a project you have under Git source control and enter the following command.
bash$ git branch experimentalThat’s all there is to it. You now have a nice shiny clean slate to experiment with abandon. You simply type:
bash$ git checkout experimentaland you are now working on the experimental branch you just created. Now you can just run amok and have nothing to worry about. Make crazy experimental changes to your heart’s content and all you need to do to go back to your original code base is type:
bash$ git checkout masterand you’re back in business. If you found that your crazy coding excursion was a great success, you can merge your changes in with the following commands.
bash$ git checkout master bash$ git merge experimentalThe first command switches you back to the master branch, while the second performs the merge of the code from the experimental branch into the master branch. If there are conflicts, you will have to fix them manually, but it seems that the need to do so is pretty rare. Git does a great job at merging changes automatically.
If you found, conversely, that your ideas were purely delusional–a characteristic of your over-achieving sense of hubris–you can blow them away by simply typing:
bash$ git branch -d experimental
Now the idea is just a bad memory and not something you ever need worry about (or mention to your programming peers) again. Your code on the master branch is still as it was when you first started the branch. Hallelujah!
Note: The word ‘experimental’ I’ve used in these command line examples is simply a tag. You can call your branch whatever you like. Call it ‘hubris’ if you like. Depending on your personality, this may be more appropriate.
The chance to experiment so easily and without fear will make you a better programmer. You will venture into areas that you would have never tried before and will likely become more bold in what you’re willing to attempt. This can only be a good thing in the long run.
The Tutorial introduction to git provides a good example of how to collaborate when multiple people are working on the same computer, but where Git’s real power comes in is in its ability to enable collaboration. If you’re familiar with extreme programming or pair programming then you are already aware of how collaboration will make you a better programmer. The learning curve for developing applications for the Macintosh for me has been significantly leveled as Marcus has shown me how to do things in the context of real code. You can learn things in many different ways, but sharing code has got to be one of the strongest means of gaining deeper understanding. This can only make you a better programmer.
While not a direct feature of Git itself, you can share your repository over the many file sharing web applications out there. Marcus and I use Dropbox for our projects that we collaborate on. Here are the steps you take to collaborate remotely using Git and Dropbox.
- Sign up and install Dropbox from http://www.getdropbox.com.
This will create a folder in your home directory under ~/Dropbox.
- Have the person you want to collaborate with do the same and then create a shared folder that both of you can access through the Dropbox web interface.
- From the project directory of the project you want to share, type:
bash$ git clone --bare . ~/Dropbox/Shared/MySharedProject.git
Note: Keep in mind that I’m assuming you already have this project under Git version control. If not you first need to run init like so in the root of your project directory.The –bare keyword we used in the clone command means that we simply want to create a directory that contains the contents of the .git directory in your project directory and not the actual workspace. The .git directory contains all of your code and changes to everything you need is there–it’s just not the actual workspace where xcode works from.
bash$ git init
- Create a remote (alias) for the newly cloned project by typing:
bash$ git remote add sharedproject ~/Dropbox/Shared/MySharedProject.git
- Now you can push any code changes from your working directory to the cloned directory, which, since it is in your Dropbox will automatically be uploaded to the drop box and downloaded by any other computers you have that can access Dropbox. First you need to commit any changes in your working directory with the following command.
bash$ git commit -a -m "Commit message"Then you need to push the changes to the remote with the following.
bash$ git push sharedproject masterThis pushes your changes to the cloned repository which is in your Dropbox directory. As soon as you do this, you should see the Dropbox icon in your menu bar change to the ‘synchronizing’ icon. If your change is small, it will only change for a split second so you’ll have to watch it closely to see that happen.
Once your files are committed and have been pushed to your cloned repository, you can now pull the project from another computer. I’m assuming you have Git and Dropbox set up on the second computer. Here are the steps you take to get the code into Git.
- In Terminal.app on your other computer, create a new directory where you want your project to be stored with a working directory. Now run the following command.
bash$ git clone ~/Dropbox/Shared/MySharedProject.gitNotice that we didn’t use the –bare keyword this time. This is because we want our cloned copy to also setup a working directory since we’ll be accessing it from xcode on the second computer as well.
- Now create a remote (alias) to reference the project like you did on the other computer using the following.
bash$ git remote add sharedproject ~/Dropbox/Shared/MySharedProject.git
Note: This step is optional as your clone will do this automatically. The difference, however, is that the clone will create a remote called ‘origin’ by default where you can name it whatever you want (sharedproject in the example) if you do run it.
- Now you can pull the code at any time with the following command.
bash$ git pull sharedproject masterYou won’t need to do that at this point as your code is fresh from the clone, however, should you make any changes on the originating computer that have been pushed, you could now pull those changes from this secondary computer.
If you now make changes to the code on the second computer, you can use the exact same command you used on the first computer to push the changes. First commit the changes with:
bash$ git commit -a -m "Commit message"Then simply push the changes to the cloned repository with:
bash$ git push sharedproject master
And now you’re up to date. The changes are ready to be downloaded from the first computer.
The Urge To Merge
Nothing like sexual inuendo (urge to merge, hint hint, wink wink) on a site called ‘Cocoa is my Girlfriend’ to get a geek going, but that’s not what I mean. Settle down. Take it easy…
In the end, Git’s greatest feature is its ability to merge code changes.
There are times when you have fairly complex code merges that are necessary and systems such as CVS or SVN (Subversion) will simply choke and give up leaving the messy merging process to your weak manual merging skills. This is a shame and not necessary any more as it is rare for Git to be unable to successfully merge code. Again, this probably its biggest strength. When you don’t have to worry about merging your code, you can do whatever you like in your branch with little fear that merging in your changes are going to conflict with someone else’s. This merging power comes from Git’s unique philosophy of source code management which sees changes as individual code additions and deletions rather than complete file changes.
There will remain naysayers who have “always done it this way” and will remain in the realm of central repositories for version control. However, if you can think outside of tradition and see the power that comes from a good source control system, you will become a better programmer. I will submit that simply starting to use any version control when you haven’t before will make you a better programmer, however, using Git for your version control system, will make it infinitely easier to become so.