Firehed's Blog

Free Private Git Hosting

It's actually not that hard to skip paying GitHub a minimum of $7 a month for your private Git needs. Not that I have anything against GitHub - it's awesome. But I'm already spending plenty of money a month on servers that I control fully, so I'd rather put them to better use.

This guide assumes you have a reasonable knowledge of Linux, and a basic knowledge of Git (at the command line). If you're looking to set this up, you already have enough Git knowledge, and it's very likely you know enough about Unix-based systems too.

So, let's get started.

Step 1: Set up your server

This server will be a "remote" repository for Git. As far as I'm concerned with my own limited Git knowledge, it's more or less equivalent to a canonical SVN repository.

Log in to your server via SSH

local ~$ ssh you@example.com

The next step is optional, but it seems like a good idea: creating a dedicated Git user, and setting up SSH keys

you@example.com ~$ /usr/sbin/adduser git
you@example.com ~$ sudo su git
git@example.com /home/you$ cd
git@example.com ~$ mkdir .ssh

At this point, you want to put the public SSH key from your local system on the remote server. Nothing too special here - SCP it across, use the clipboard, whatever. Just make sure it's appended to ~git/.ssh/authorized_keys.

Make sure everything worked:

local$ ssh git@example.com

If you were able to connect, great! If not, make sure your public key copied across correctly and that permissions for ~git/.ssh aren't screwed up. There are plenty of guides out there about getting SSH public keys set up correctly if you need more help.

Step 2: Create the remote repository

Log back in to your server with the git user, make a directory for your repository, and git init it.

local ~$ ssh git@example.com
git@example.com ~$ mkdir myproject.git
git@example.com ~$ cd myproject.git
git@example.com ~/myproject.git$ git init

And that's it.

Step 3: Add the remote target to your local copy

You really just need to follow Github's instructions at this point, but substitute in your own server's URL.

local ~/myproject$ git remote add origin git@example.com:myproject.git

That's all it should take. Try it out:

local ~/myproject$ git push origin master

> Counting objects: 7, done.
> Delta compression using up to 2 threads.
> Compressing objects: 100% (4/4), done.
> Writing objects: 100% (4/4), 654 bytes, done.
> Total 4 (delta 2), reused 0 (delta 0)
> To git@example.com:myproject.git
>    152f26a..ffeedcb  master -> master

If you would like to skip git push origin master in favor of git push, run the following:

local ~$ git config --global branch.master.remote=origin
local ~$ git config --global branch.master.merge=refs/heads/master

In layman's terms, this means that the default "remote" repository to use when on the master branch is origin, which we set up a few lines above. I don't honestly know exactly what the merge configuration corresponds to, as I'm still somewhat retarded when it comes to Git branching.

Hopefully you find this helpful. Any comments, questions, or suggestions should be directed at me via email (firehed _at_ gmail [.] com) or twitter (@firehed), as I haven't bothered building a comment feature on the blog at this time.