Some time back, I wanted to setup my server so I could push code to my repositories, and have it automatically deployed to a website root directory after doing a git push from my local machine.
I can’t remember where I found the instructions so I can’t give credit to whom I got it from, but here’s how I did it.

This is followed by a tutorial on how to extend this setup to multiple branches and work-trees for “live” and “development” versions of a website.I use this method for small personal projects where I really only need one branch to be automatically deployed. I will assume you already have a local git repository (Head here for instructions how to, this is still somewhat valid!) with some code in it under a branch called ‘master’, and that you will push code to a remote server holding both your repository and your web server.

Create the remote repository (basic git setup)

On server:

mkdir /path/to/repo/project.git
cd /path/to/repo/project.git
git init --bare

On local machine:

cd /path/to/mycode
git init
git remote add origin git@yourserver:project.git

At this point (providing you have setup git on your server correctly, which I’m not going to cover here! This how-to is still valid) you should be able to simply push your code to your server with the usual command

git push origin master

Adding single branch automatic deployment

First, you’ll need a place to deploy your code to, that’s call the detached work tree from Git’s point of view because it’s a copy of the code without the history or references. I have both my repositories and webserver on the same machine so these instructions are for this configuration only. This detached work tree needs to be under your webserver’s root directory if you’re deploying a web site, but you could deploy that whatever place you want.

On server:

Create the work-tree directory and make make sure the git user (or the one you use for git repositories) has permissions to write to this directory:

mkdir /path/under/root/dir/project
chown git:git /path/under/root/dir/project

Then, you need to add a bit of configuration to your repository (created above):

cd /path/to/repo/project.git
git config core.worktree /path/under/root/dir/project
git config core.bare false
git config receive.denycurrentbranch ignore

Finally, all you have to do is create and make executable a “post-receive” hook in your repository’s hooks folder:

cd /path/to/repo/project.git/hooks/
touch post-receive
chmod +x post-receive
vi post-receive

And paste this code into this file:

#!/bin/sh git checkout -f

And voilà! Next time you push new changes from your local machine to the main server, the default (master) branch will be automatically checked out from your repository into the detached working tree.

EDIT: Following Luca’s comments below, it’s worth noting that if you have no local changes, nothing will get pushed, and the hook will not be fired! So when you do your next push (after all the setup), remember to edit a file to somewhat “force” a push. Then your content will be checked out by the hook. No update, no deployment