Imagine you develop a website on your development server, store the source code in a remote repository and deploy to a production site. Let’s assume you just finished a new feature. You commit and push the changes to the remote repo. But the glorious days of FTP are long over — how would you utilize git to do the heavy lifting?

We can use git’s hook to automatically deploy changes to the live site, without manually transferring files. Here’s how:

Set up your DEV server

First, let’s take a look at our environment: there’s our development server (DEV), the production server (LIVE) and the remote repository like gitorious, github, bitbucket or something similar.

picture 1 – the server environment

On DEV we create our project folder and cd into it (line 1). Then we initialize an empty git repository (line 2) and create our first project file, index.html (line 3). We add a new file to git (line 4) and finally commit the changes.

dev$ mkdir mywebsite && cd mywebsite dev$ git init dev$ cat 'hello world!' > index.html dev$ git add index.html dev$ git commit -m "initial commit of my web site."

Now that our local repo is set up, we need to add the remote repo where we want to store the code centrally. I’ll use bitbucket and a bogus URL (line 1). If you haven’t created ssh keys yet, check out this tutorial about generating ssh keys. NOTE: this manual is for github but it basically applies to other git version control systems. Now we are ready to check in the code to bitbucket (line 2).

dev$ git remote add origin ssh://[email protected]/myweb.git dev$ git push -u origin --all

Push to central repository

From now on you should commit all further changes (to your central repository) with (line 1)

dev$ git push origin master

picture 2 – push to central repo

Set up bare git repository on your production server

Now ssh to your production server and make sure that things are set up so that you can ssh to it without having to type a password (ie, your public key is in ~/.ssh/authorized_keys). On production we create a new (bare) repository to mirror the local one. Also, create a folder where you want to host the repo and cd into it (line 1), eg. in your testuser’s home folder /home/tesuser/ . Next, create the bare repository (line 2).

live$ mkdir mywebsite.git && cd mywebsite.git live$ git init --bare Initialized empty Git repository in /home/testuser/mywebsite.git/

Then we define (and enable) a post-receive hook that takes your latest commit and copies it into another folder (this folder should be your web server’s DocumentRoot or at least a virtual host) Note: this directory must exist – git will not create it for you!

So create the webfolder (line 1) or just skip this step if you already did. Still in the directory where you host the bare repository, create the post-receive hook (line 2). Of course you can use your favorite editor to paste the two lines into the file.

live$ mkdir /var/www/www.mywebsite.org live$ cat > hooks/post-receive << EOL #!/bin/sh GIT_WORK_TREE=/var/www/www.mywebsite.org git checkout -f EOL

Don’t forget to make the file executable (line 1).

live$ chmod +x hooks/post-receive

Let’s go back to the DEV server and define a catching name for the remote mirror (I picked live for this example), and then mirror to it, creating a new “master” branch there (lines 1 and 2).

dev$ git remote add live ssh://www.mywebsite.org/home/testuser/mywebsite.git dev$ git push live +master:refs/heads/master

The production server should now contain all your files (in /var/www/www.mywebsite.org ), independent of any .git metadata.

Deploy to LIVE

Whenever you make changes to your project sandbox on DEV you would commit the files and push them to remote central repo as described in picture 2. If you are ready to do a roll-out, deploying all the changes to your production, run (line 1) from your local repo on DEV.

dev$ git push live

This will transfer any new commits to the bare repository on production, where the post-receive hook will immediately update the webfolder for you.