Private Git repo

I've decided to migrate this blog to Pelican. I've been playing around with it over the week-end, and it turns out to be way easier to manage than Jekyll. Themes are much easier to install and configure, so it ends up looking better as well !

Since I'm basically recreating this blog from scratch, I've decided to delete the old git repo that was hosting it and to create a new one.

Setting up your own private git repo is pretty easy to achieve and is already well-documented on the Git website.

Every time I want to create a new repo, I've had time to forget how to do it and I end up looking for that page, so I figured I'd write a few lines on the subject.

In this tutorial, I'll configure a git repo on a distant server running Debian 8 (Jessie). This repo will be remotely accessible using SSH. Two users will be able to connect to it : me and the www-data user on my webserver.

SSH Keys

If you don't have one already, you'll need a ssh-key to connect to the git repo.

On your computer, in a shell, as your usual user :

ssh-keygen -t rsa -b 3072
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/id_rsa.pub.
The key fingerprint is:
[Redacted]

For security reasons, configuring a passphrase is recommended. On Mac OS X and most desktop environnements on Linux, you can store this passphrase for the duration of your session using the ssh-add command, so you won't have to type it every time you want to connect to a host.

On the server, we also have to create a ssh-key for the user that is running our webserver (you'll need to have sudo installed) :

sudo -H -u www-data ssh-keygen -t rsa -b 3072
Generating public/private rsa key pair.
Enter file in which to save the key (/var/www/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /var/www/.ssh/id_rsa.
Your public key has been saved in /var/www/.ssh/id_rsa.pub.
The key fingerprint is:
[Redacted]

If you decide to configure a passphrase for that ssh-key, you'll have to type it every time you'll want to pull from your repo.

Server management

All of the commands in this section have to be run as root.

First thing first, we have to install the git package on the server that will be hosting our git repos :

apt update && apt install git -y

Then, we have to create a user named git :

useradd -s /usr/bin/git-shell -m -r git

This will create a system user (UID < 1000) with a /home/git home directory. If you want to host your git repos somewhere else on your filesystem, you should add a -d /home/directory/for/git in the previous command.

This user will use the git-shell shell. This limits remote connection to that user to git commands (like the rssh shell can limit remote connection to a user to scp or rsync commands).

We have to configure our system to allow the use of this shell :

echo '/usr/bin/git-shell' >> /etc/shells

From this point, you should have to following output if you try to SSH to your server with that user :

ssh git@git.captainark.net
fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.
Connection to git@git.captainark.net closed.

We now need to create the .ssh/authorized_keys file for the git user with the correct permissions :

sudo -H -u git mkdir /home/git/.ssh && chmod 700 /home/git/.ssh
sudo -H -u git touch /home/git/.ssh/authorized_keys && chmod 600 /home/git/.ssh/authorized_keys

You can now copy/paste the content of the two $HOME/.ssh/id_rsa.pub files we've created earlier using the ssh-keygen command in /home/git/.ssh/authorized_keys.

The last thing we have to do is to create our first git repo. In this example, my project will be called 'captainarkdotnet' as it will be hosting this blog :

sudo -H -u git mkdir /home/git/captainarkdotnet.git
cd /home/git/captainarkdotnet.git
sudo -H -u git git init --bare

The last command should give you the following output :

Initialized empty Git repository in /home/git/captainarkdotnet.git/.git/

We're done with the server configuration. Let's now actually push stuff to our repo !

Initial push

The files for my blog are store in the ~/Documents/projects/captainarkdotnet on my computer. Before doing anything else, we first have to make sure that we currently are in that folder :

cd ~/Documents/projects/captainarkdotnet

Let's now push the content of that folder to our repo :

git init
git add .
git commit -m 'initial commit'
git remote add origin git@git.captainark.net:captainarkdotnet.git
git push origin master

Please note that you'll need to edit git.captainark.net to the FQDN or IP of your git server, and captainarkdotnet.git to the name of the git project on your server.

If everything went well, the last command should give you the following output :

Counting objects: 69, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (64/64), done.
Writing objects: 100% (69/69), 1.01 MiB | 0 bytes/s, done.
Total 69 (delta 15), reused 0 (delta 0)
To git@git.captainark.net:captainarkdotnet.git
 * [new branch]      master -> master

That's it, we've now pushed our first commit to our server !

First pull

Alright, time to pull the files we've just pushed on our webserver. I personally store my web content in /var/www ; if you don't, you'll have to adjust the path accordingly :

cd /var/www
sudo -H -u www-data git clone git@git.captainark.net:captainarkdotnet.git

SSH will ask you to type 'yes' since it's the first time the www-data user connects to the server. If everything goes well, you should have the following output :

Cloning into 'captainarkdotnet'...
remote: Counting objects: 70, done.
remote: Compressing objects: 100% (65/65), done.
remote: Total 70 (delta 16), reused 0 (delta 0)
Receiving objects: 100% (70/70), 1.01 MiB | 0 bytes/s, done.
Resolving deltas: 100% (16/16), done.
Checking connectivity... done.

Conclusion

That's it ! We now have a working private git repo ! I won't go into details into the git commands in this tutorial, but here's a quick overwiew of the ones I use the most :

  • git add . recursively adds all files from the directory to the repo ;
  • git commit -a -m 'This is a comment' commits the current state of your local repo with the 'This is a comment' comment ;
  • git push pushes your commits to the distant repo ;
  • git pull pulls the latest version of the distant repo locally ;
  • git branch -av shows all available branches for the repo ;
  • git checkout -b testing remotes/origin/testing create a local 'testing' branch based on the remote 'remotes/origin/testing' branch ;
  • once a branch has been copied locally, you can switch to it with the git checkout {branch} command.

For more information on git a command, use man git-{command} !

If you've found this tutorial in any way helpful, please feel free to leave a comment !