This is kind of a follow-on to the WordPress series of posts. It’s using the same server as what’s serving up this page, but it’s also being repurposed to be a git server as well.

Why git? Hell, what is git?

Git is a distributed source control system. If you’ve heard of things like SourceSafe (ack!), Subversion, Perforce, CVS or even RCS you’ve used a version control system. If you’ve never heard of any of these, don’t worry, it has nothing to do with blogging. It has everything to do with software development. Git is another take on how to manage source code. It has some compelling attributes which is why I’m forcing myself to get with the program and use it.

If you have an EC2 instance and want to set up a quick and dirty git server you can do it in a few minutes. This isn’t intended to support an enterprise-scale rollout. This is for a few developers working on some common code.

First off, on your local machine create a public/private key pair:

$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/gburgyan/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/gburgyan/.ssh/id_rsa.
Your public key has been saved in /Users/gburgyan/.ssh/id_rsa.pub.
The key fingerprint is: ...stuff...
$ cat ~/.ssh/id_rsa.pub
ssh-rsa ...long, several line string of gibberish...

You’ll need the contents of that file in a moment.

SSH into your server and get git:

$ sudo yum install git

Next, you want to create a user that git will run as:

$ sudo adduser git

Next, let’s let our user log in.

$ sudo -u git bash
$ cd
$ mkdir .ssh
$ cd .ssh
$ cat >authorized_keys
[paste in the several line string from before]
[press control-d to end input]
$ chmod 600 authorized_keys
$ chmod 700 .
$ exit

What we did there was set up SSH (more on that in a moment) to allow our private key to log into this new account we made. We’ll actually turn off the logging in part in a moment, but git will communicate from your machine to the server over SSH making things nice and secure. The cat (short for concatenate) command in this case will take what we paste and copy it to the authorized_keys file. As you might guess, the authorized keys can talk to ssh.

Next we CHange MODe of the file and directory to allow only the git user to read them. If you skip this step you’ll get a strange error later on when trying to connect to the server.

At this point you can verify that you can log in and SSH is set up correctly by logging in from your desktop.

$ ssh [email protected]

Obviously, use your server’s name. :-)

Ok, back on the server let’s create a repository.

$ sudo bash
# cd /var
# mkdir git
# cd git
# mkdir project.git
# cd project.git
# git --bare init
# chown -R git /var/git
# exit

Now we’ve created a new directory for our repository in /var/git called “project.git”. You should use whatever project you want to for this. We’ve also CHanged OWNership of that directory to the git user we created up top.

At this point you should be able to do something like:

$ git clone [email protected]:/var/git/project.git

from your desktop!

Lastly, we want to lock things down a bit on the server:

$ sudo nano /etc/passwd

You should see a line that looks vaguely like this:

git:x:501:501::/home/git:/bin/bash

You want to change that to read:

git:x:501:501::/home/git:/usr/bin/git-shell

This will prevent someone from actually logging on as the git user. You can check this by trying to SSH into the machine again:

$ ssh [email protected]
$ ssh [email protected]
Last login: Mon Apr 28 02:19:02 2014 from c-24-18-225-152.hsd1.wa.comcast.net

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2014.03-release-notes/
fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.

At this point you’re all set. If you want to create new repositories, just create and init a new directory under /var/git and make sure you chown it to git like before.