3
Jun
2008
 

Version Control Makes You A Better Programmer

by Matt Long

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 experimental

That’s all there is to it. You now have a nice shiny clean slate to experiment with abandon. You simply type:

bash$ git checkout experimental

and 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 master

and 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 experimental

The 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.

Collaboration

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.

  1. Sign up and install Dropbox from http://www.getdropbox.com.

    This will create a folder in your home directory under ~/Dropbox.

  2. 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.
  3. 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.

    bash$ git init
    

    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.

  4. Create a remote (alias) for the newly cloned project by typing:
    bash$ git remote add sharedproject ~/Dropbox/Shared/MySharedProject.git
    
  5. 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 master
    

    This 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.

  1. 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.git
    

    Notice 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.

  2. 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.

  3. Now you can pull the code at any time with the following command.
    bash$ git pull sharedproject master
    

    You 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.

Conclusion

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.

Comments

Marcus Zarra says:

sdfisher,

The point of git is not that it is distributed. That is a given and works great for the situation it was written for. Git can easily be used in a central repository configuration.

The point of git is that it does not suck when it comes to merging and handling the code. Subversion is absolutely terrible with merging and even worse with managing code. I ran into some of its amazingly poor design just this morning. Imagine this situation and it is only one example of many: Move a directory from one place to another (under a different parent) and then delete the parent. Then commit. Guess what, subversion blows chunks. You have to move, commit, delete, commit.

sdfisher says:

Hey, for the record, I totally agree that Subversion’s merging blows chunks. I’m just not sure why so many have approached it as a fundamental design flaw that needs an entirely new source control system rather than something to be fixed.

I guess I’d much rather hear about why I’d be happier with something else than why I’m an idiot for using what already works for me. :)

Marcus Zarra says:

sdfisher,

Simple:
—Local/Offline version control
—Local/Offline branching and merging
—FAST No network access means no network overhead so faster
—Not dirty when switching to a branch. One workspace no matter what branch you are on
—Directories are not covered with .svn or CVS directories
—Merging that actually WORKS. This is a VERY big deal when you actually start branching and merging.

But here is a thought. TRY IT. Play with it. If you don’t like it then fine go off and be happy. It seems you would rather have someone convince you (or argue with you) instead of spending the time deciding for yourself if git is for you.

And btw, the BS about SVN merging being a feature that needs to be fixed? Give me a break! It has never worked worth a damn in CVS and SVN is just as bad. It does require a whole new system because SVN’s design is flawed. Did you watch the Torvalds video? Do any research into the difference in how files/changes are handled between SVN, HG, BZR and GIT? Probably not. It is a design flaw and it can be fixed by not using subversion.

whomwah says:

In refererence to git, may I recommend http://github.com.

bo says:

Github looks pretty slick, but, if you have a decent webhost (i.e. VPS or better) already and you only need an online repository, gitosis is a super-simple, no frills option.

It took me literally 5 minutes to get a git repository online using these instructions. The coolest part is that gitosis stores its configuration files in a git repository that it manages. So to change its configuration, you just edit your local git clone of the admin files, ‘git push’ them back to the server and they instantly take effect.

[…] Cocoa Is My Girlfriend » Version Control Makes You A Better Programmer (tags: git versioncontrol programming cocoa tutorial version) […]

jdickey says:

I used SourceSafe back before MS got their filthy mitts all over it and completely desecrated it; at the time, I was working in a mixed Mac/Windows/OS2 shop, with a lowly 16 MHz 386 running OS/2 being our server. Naturally, the first thing that happened under the new owners was to kill the OS/2 version. So we downgraded to PVCS.

I learned decades ago that version control means never having to say you’re sorry. It’s obvious in a team environment, but absolutely critical when you’re flying solo…. your buddy in the next cube does NOT have the file you just barfed all over. If I had a grand for every time VCS (of whatever incarnation) saved my gluteus/project/job, I might not be able to retire, but I could definitely afford that chalet in Innsbruck.

If you’re not using version control, preferably not running on your dev machine, you’re a dilettante, a dabbler causing yourself more unknown pain than you imagine. Wake up!

[…] you’re no doubt aware, a lot of talented, high profile programmers have announced that they’re moving to git for version control. Many of these programmers (for […]

I can see the advantage of using the “shared folder” feature in a team environment. My question would be, if you are working by yourself would you:

a) Just create the projects in dropbox and create the repo an let dropbox do the sync

b) you need to do the whole “clone, push, pull” operation because git will get all screwy otherwise?

Please advise. And thanks for writing the article, very useful

Matt Long says:

@emailtoid.net/i/70af74a2/54caacf6/

Even when I’m the only one working on a project, I set it up in git. So any time I set up a new project, in my new project directory, I do this:

  1. git init
  2. Edit the file ./.git/info/exclude and add the following lines:
    build
    .xcodeproj/.mode*
    .xcodeproj/.pbxuser
    .DS_Store
  3. git add .
  4. git commit -a -m “Added project to repository.”
  5. git clone ~/Dropbox/Shared/MySharedProject.git

Now, whenever you edit a file in your project,

  1. git status
  2. git commit -a -m “Comment for changes.”
  3. git push

You’ll never need to do a pull if you’re the only one working on the project.

Dropbox will automatically upload the changes to your remote folder.

Let me know if you need further clarification.

-Matt

[…] Git repository — intranation.com another article on GIT and Dropbox (tags: git drobox tutorial) Using Git with Dropbox Description of how to use Dropbox to host git –bare repositories (tags: git versioncontrol […]