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 firstname.lastname@example.org:/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 email@example.com 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 firstname.lastname@example.org:/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 “email@example.com:/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 firstname.lastname@example.org:/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 email@example.com fatal: What do you think I am? A shell? Connection to gitserver closed.
And that’s it!