Setting up a GIT server on OSX using the Command Line

I do a lot of my development these days in VMs (various OSes), one for each project. I have two different physical machines I work on, my iMac and my MacBook. Today I finally got around to setting up a git server on the iMac (its backed up with Timemachine) to make code sharing across machines, virtual and real, easier. Since I’m in the office at work I did it all remotely on the command line over ssh.Generally the process I am going to describe is little different to the one described in the GIT documentation except OSX isn’t Linux. Being BSD based there are differences.

On the server

Creating a “git” user

Firstly we need to create a “git” user. On Linux you would use useradd on OSX the tool dscl (See man dscl) is used to create new users as one of a many number of things it can do. Below are the steps to create a new user.

$ sudo dscl . -create /Users/git
$ sudo dscl . -create /Users/git UserShell /bin/bash
$ sudo dscl . -create /Users/git RealName "Git server"
$ sudo dscl . -create /Users/git UniqueID 504
$ sudo dscl . -create /Users/git PrimaryGroupID 20
$ sudo dscl . -create /Users/git NFSHomeDirectory /Users/git
$ sudo dscl . -passwd /Users/git ******
$ sudo mkdir -p /Users/git
$ sudo chown -R git:staff /Users/git

The ****** represents what ever password you want to set. The UniqueID is the user ID and must be unique. I picked the next free ID in the same range as the other users on my system. You can list all the user information as follows:

dscacheutil -q user

I got a list of sorted UIDs with a bit of shell magic.

dscacheutil -q user | grep ^uid: | cut -d\  -f2 | sort -n

The PrimaryGroupID must be a suitable existing group. I picked 20 as that’s “staff” on my system. On an Ubuntu Linux system it would be “users”. Again you can get a list of group information using dscacheutil like so:

dscacheutil -q group

You could create a new group with the dscl command. I leave that as an exercise for the reader.

Creating a git repo

Now we have the git user we can set up the server. A git server isn’t really a server in so much as it doesn’t have a daemon process. Its just another SSH user. Setting it up is no different on OSX to any other *NIX system so I just followed the instructions from the GIT site. But I’ve put them below for completeness.

$ su - git
$ mkdir -p repo/project
$ cd repo/project
$ git --bare init

Basically login as the git user. Create a “repo” directory to contain all your git projects and a project directory called what ever your project is called. Then initialise it.

On the client

Now switch the client.

Generating SSH keys

As I said above a git server is just another SSH user. The recommended way of using git is via secure keys. The commands to create keys are as show below:

$ mkdir .ssh
$ chmod 700 .ssh
$ cd .ssh
$ ssh-keygen -f my_key_name -t rsa -q
$ ssh-add my_key_name
$ cp my_key_name.pub ~/Desktop

Firstly create a “.ssh” directory if you don’t already have one. It must have only user read, write and execute privileges. In that directory create the keys. The “my_key_name” can be substituted for any name you wish to use. Finally copy out the public key to somewhere easily accessible. Finally you can copy the key to the git server using the command:

$ scp ~/Desktop/my_key_name.pub git@git.some.domain:/Users/git

Repeat this step for all clients which wish to use the server.

On the server

Back on the server.

Adding a client’s SSH key

Now we need to add the client public keys to the server. As the git user create an “.ssh” directory, if one does not exist, and then just append the client public key(s) to the “authorized_keys” file.

$ mkdir .ssh
$ chmod 700 .ssh
$ cat my_key_name.pub >> .ssh/authorized_keys

On the client

Back to the client again.

Setting the git server SSH port (optional)

SSH on my server is accessed via a non standard port because there’s another machine behind the firewall on port 22. So I have to tell git which port to use. To do this I have created a “config” file within the “.ssh” the follow contents:

Host git@git.some.domain
	Port 1234

Creating the local repository

Finally we need to create the local git repo.

$ mkdir project
$ cd project
$ git init
$ git add .
$ git commit -m "Initial commit"
$ git remote add origin git@git.some.domain:/Users/git/repo/project
$ git push origin master

Create the local project repo directory. Add any contents and commit them. Finally we set the remote git server to be the ‘master’ and push up all the content. Note that on Linux the remote path would be “git@git.some.domain:/home/git/repo/project”.

Cloning a repository

Now the repo is on the server further clients can clone and update it like so.

$ git clone git@git.some.domain:/Users/git/repo/project
$ # Modify, add and remove files.
$ git commit -m "Commit comment"
$ git push origin master

On the server

Disable shell access to git (optional)

Finally you can replace bash as the git shell with git-shell. On OSX use the command below. On Linux it is simplest just to edit the git line “/etc/passwd” file.

$ sudo dscl . -create /Users/git UserShell /usr/bin/git-shell

This will disable shell access. If you try and use it you’ll get the following message:

$ ssh git@git.some.domain
fatal: What do you think I am? A shell?
Connection to gitserver closed.

And that’s it!

Tags: , ,

Leave a Reply