I’m doing a bit of web development work, for myself and for my clients, and realised that having some form of source control will be quite useful.
I initially looked at Subversion which has a lot going for it.
- It’s built in to Mac OS X and Mac OS X Server.
- There is a large variety of GUI clients for it.
- It’s built into Dreamweaver, Coda, Textmate and quite a few other pieces of software.
The downside that I didn’t like is that it’s quite rigid with it’s management of files. If I’m collaborating with someone else on a project and they, for example, send me a new folder of images for a project, I can’t just delete the old folder of images and put the new one in it’s place. There’s a hidden .svn folder in each folder that holds important information and if you delete this, Subversion gets a bit annoyed. If you’re working with someone on a project and they don’t have access to your repository (for example if it’s on an internally accessible server that’s not published to the Internet) then it’s a lot tricker to merge changes back and forth.
Really though, it was the lack of being able to manage my files and folders easily in the Finder without worrying about not being able to check it back in again that put me off it.
My next choice then was Git. This is a more distributed version control system, not only does it not need a server but there’s no one standard type of server software to run either. I can grab a folder that’s managed by git, email it to a colleague and they can merge it into their git repository quite easily. They can also export their copy and it’s quite easy for me to merge it back into my version.
There are some good Git clients for Mac OS X, such as Tower. Tower is in public beta at the moment, but is quite stable and usable. Git is also baked into Textmate as well which is my editor of choice.
As I’d decided that I wanted a Git repository, I then wanted to set up a proper Git server on my Mac mini Server. Well, this is easier said than done.
I initially wanted a Git server that used the git protocol (git://server…) running on port 9418, but this is definitely not easy to achieve. The options seem to be limited to the git-daemon which by default only has anonymous read-only access to the projects (or, if you enable write to the projects, it’s anonymous write access only) and running a private version of GitHub, known as GitHub:fi. I’m sure GitHub:fi is quite good and at $2500 it’d want to be, but I’m not shelling out that kind of money for a side project.
As an aside, there are a large number of publicly hosted git servers, but I want to keep this work inhouse at the moment.
The short answer however is that it’s not at all easy to host a “proper” git server, one that’s accessible via the git:// protocol. It seems that the next most popular option (and one that’s also nice and secure by default) is hosting a git repo over ssh and there’s also options for hosting git repos over http (or WebDAV)
After looking at the other options, I’ve had a go with Gitolite which is a relatively easy way to set up the environment you need on the server to host git repos via ssh.
Gitolite is an open-source project, hosted on GitHub. It’s pretty easy, if you have even a working command-line git client, to download the source and set things up. It’s based on a very similar project called Gitosis, but Gitolite seems to be under active development whereas Gitosis seems to have been left alone for a while.
Installation on Mac OS X Server
Create a user to host the repos.
Using your tool of choice, either Server Preferences or Workgroup Manager (or, if you’re hardcore, the command-line) create a user for the git service. In order to keep things straightforward, I called this user git. This user can either be created as a local user or in the directory, it doesn’t really matter. I set their home to be /Users/git and told Workgroup Manager to create their home directory. I initially made the user an Administrator as this made the install process easier (I had access to sudo as the git user for example) and then once it was all set up, I turned off administrator permissions for this user.
sudo port install git
As I didn’t have all of this installed on my Server, I took the easy path of installing git as an OS X package.
Once git was installed and working, I could then check out the source tree for Gitosis.
Set up Passwordless ssh
You’ll will need to set up public key authentication for ssh. Copy your ~/.ssh/id_dsa.pub or id_rsa.pub file to the server in the git user’s .ssh directory as authorized_keys, or use the
Clone the source of Gitolite
This is pretty easy to do:
cd ~/Source git clone https://github.com/sitaramc/gitolite.git
Installing gitolite was pretty straightforward – simply following the instructions in the download. You don’t need the developer tools or anything like that installed. Gitolite is a bunch of scripts that sets things up for you, not some code that needs to be compiled to run.
cd gitolite sudo src/gl-setup
on the server and you’re on your way. Alternatively, on your workstation, you can clone the repo and run
and this will set things up on the server for you.
Set up the user’s environment
One thing I found with the base install on Mac OS X was that the $PATH environment variable wasn’t set correctly for non-login shells. You can easily check what the default path is on the server by entering the following on your workstation
ssh [email protected] echo $PATH
On my server, this was returning a path that didn’t have the git binaries in it, so I couldn’t check out or do anything else.
Simply by editing .bashrc for the git user on the server and adding in the following;
This was enough to fix this simple problem. If you don’t want to edit the .bashrc file, you can specify the git binary directory in the command line invocation, but I’m not sure this’ll work with a GUI client:
git clone -u /usr/local/git/bin/git-upload-pack [email protected]:code
There’s a really good writeup on 8 different ways to share your git repo from Patrick Debois that has a quick overview of the pros and cons of a heap of different ways to share your repository.