18
Mar
2008
 

Git and .mac: A Match Made In Purgatory

by Marcus Zarra

Last year, I made the switch from subversion to Git. After 9+ months of using Git, I can comfortably say that it was a very good choice. While branching is easy in subversion, merging is just as bad as it was in cvs. Git is a significant improvement over that. In addition, since Git is a true distributed source control system, I can easily do branches and merges on my local machine without an internet connection and just “push” my changes to my off-site server when it is convenient.

I am also a user of .mac. I like the service and the iDisk is probably my favorite feature. Therefore, I wondered, like chocolate and peanut butter, could I put these two together and come up with something better than the individual parts?

The answer is yes. They work amazingly well together and make it very easy for me to push my code changes off-site even when I am not actually connected to the net. The basic configuration is fairly simple. I created a private directory on .mac, set up a bare repository in that directory and defined that directory as a remote location for my Git workspace. Below are the details on how to accomplish this.

Install Git on OS X

First, you need to have Git. The easiest way that I have found to get it is to use the MacPorts and do a ‘sudo port install git-core +svn’. I add svn because once you get used to Git you will want to put it in front of all your svn repositories that all those stone age developers still use.

Note: After installing MacPorts, you may need to add /opt/local/bin to your PATH in order for the port command to be found from the command line. Edit your .bash_profile file in your home directory (assuming you use bash) in Terminal and add the following line to the bottom of the file: export PATH=/opt/local/bin:$PATH .

Create your working repository

Once you have Git installed, you will want to create a repository. That is accomplished with a single call:

mkdir TempProject
cd TempProject
git init

What that does is create a single directory called .git in the TempProject directory. All of the version information for that workspace is stored in that single .git directory (hello Subversion guys, your .svn directories suck).

Set up the bare clone

Now that your repository is created, you want to create a remote copy of it in case your harddrive eats itself or gets stolen (BTW Wil, sorry to hear about your MBA, that thief should burn). To do that, you want to have iDisk local syncing turned on. When it is, you will have a directory under /Volumes with your .mac username. For instance, mine is at /Volumes/mzarra. In this directory you want to create a new directory (I called mine git). Make sure that directory can only be accessed by you.

Now that it is created, you want to build the bare clone of your workspace. To accomplish this, execute the following:

cd TempProject
git clone --bare . /Volumes/${USERNAME}/git/TempProject.git

After a few moments your new bare clone is ready.

Linking the remote clone

The final step is to tell your local repository where that remote repository is:

cd TempProject
git remote add origin /Volumes/${USERNAME}/git/TempProject.git

Note that I used origin as this is the default repository name for push and pull. If you want your origin to be somewhere else then change this name.

Performing a push

Now that everything is set up all you need to do to sync your repositories is:

git push

And Git will update the bare clone.

Sync multiple working copies

But wait — there is more. If you have more than one Mac, you can use this bare clone to keep your two workspaces in sync! On the other Mac, once Git is installed, you can grab a working copy as follows:

git clone /Volumes/${USERNAME}/git/TempProject.git

And you will now have another working copy! If you need to update your second Mac at a later point just:

git pull

And Git will do all the work for you.

Conclusion

There are a couple things to note.

  • The initial sync back to .mac can be slow if your workspace is large. However, as long as you ‘push’ often enough, your subsequent syncs should be very quick. Therefore, get in the habit of pushing often.

  • Only one Mac can sync with .mac at a time. Therefore it is possible to get a sync failure if the n Macs try to sync at the same time. Therefore if you are going to do a pull and you just pushed to .mac, make sure that both syncs succeeded.

Marcus Zarra

Marcus S. Zarra is a founding partner of MartianCraft, LLC. He has been developing Cocoa software since 2003, Java software since 1996, and has been in the industry since 1985. Currently Marcus is producing software for iOS and OS X. In addition to writing software, he assists other developers by blogging about development and supplying code samples on Cocoa Is My Girlfriend. Marcus is also the author of Core Data (2nd edition): Data Storage and Management for iOS, OS X, and iCloud and Co-Author of Core Animation: Simplified Animation Techniques for Mac and iPhone Development. You can find Marcus on Twitter, on App.net and on StackOverflow.

More Posts - Website

Follow Me:
Twitter

Comments

Your setup sounds great, but I just wonder how good .mac syncing is. I also use it and I’m having troubles every single week with the complete synchronization process. It’s not only terribly slow, but also unreliable. The concept is so great, but I wish Apple would do something to improve the web service.

Marcus Zarra says:

I have heard a few people complain about these sync issues but honestly I have not run into them.

I also do not try and sync gigs of changes every day. Since iDisk basically performs an rsync, as long as your changes are small (which git changes would be) the sync is a non-issue.

daniellord says:

Just curious, why did you not make the .Mac volume your main repository? I am assuming you considered that approach and rejected for some reason. Perhaps performance?

Marcus Zarra says:

It would make the syncs slower since there would be more files changed (the actual files and the .git ‘database’). When you are syncing a lot of changes constantly to dotMac it has a higher risk of failure due to the other machines trying to sync. This way the changes are relatively small and easier to sync thereby decreasing the chance of a collision.

bbatsell says:

You also might consider creating a repository on .Mac first and then cloning it to your local hard drive. Not a huge difference, but it’ll automatically set the .Mac repository as the origin for pushing and pulling, so it’ll save you that step (helpful if you are going to clone off .Mac on multiple computers).

drew says:

I wonder if this could be done without the local iDisk copy? Either by using webdav (can they be added as remotes for GIT?) or via SFTP/ SSH (can the iDisk be accessed via SSH?).

This makes for a nice offsite backup of projects. I guess a daily git push script could even push changes out automatically and run git gc once a month.

Thanks your post saved my day!

Until now I used bzr which handle really badly the iDisk. I use a Mac and a Linux Desktop. I could now synchronize all my work in the same place.