This is something I’ve been meaning to look at ever since a conversation I had at Scotch on the Rocks 2011. Many of us – even if we use the latest and greatest in source control – still use FTP to deploy our site changes to production. This causes several headaches, among them remembering which files have changed, and getting all those files deployed simultaneously.

After looking around the web, I have found several resources that helped me set up Git to deploy my site.

Git branching model

The first thing to read, if you’ve not already done so, is A successful Git branching model. You can make this as complex as you like, but at the very least you should have a master branch and a develop branch. All your development work is done in the develop branch (or others); when you’ve finished developing a feature and are ready to release it, merge it into the master branch.

The master branch should always contain the production code – so, when we merge our code into the master branch, we then want a way to automate pushing this directly to our production server.

Set up SSH access and Git on your server

The next thing to do is set up your server to allow SSH access (if it doesn’t have it already) and install Git.

I’m running a Windows 2008 server, so decided to use Cygwin to simplify installation of both. I found excellent instructions on setting up a Git server on Windows 2008 – follow all the instructions apart from installing Python, which isn’t needed for our purposes.

Set up remote Git repository

Now that you’ve got Git and SSH installed, here comes the fun stuff.

First, we need to set up a bare Git repository on the server. This should be located somewhere completely separate from your web root. Personally, I put the Git repositories in my cygwin/home/git directory (the home directory for my “git” user).

So, having logged in via SSH as “git”:

$ mkdir mywebsite.git
$ cd mywebsite.git
$ git init --bare

This creates a “bare” Git repo, which means that it contains all the Git commit data, but no checked-out HEAD – essentially, it’s just the contents of the .git directory in a normal git repo.

Now comes the real magic. We’re going to create a Git “hook”, so that when we push the latest commits to this repository, it automatically checks it out to your webroot, with no user intervention necessary!

Create a file post-receive in the hooks directory of your repository:

#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f

Make sure the target directory exists, as Git won’t create it for you. Finally, set permissions on the file:

$ chmod +x hooks/post-receive

And that’s your server setup completed! (Thanks to this site for the help…)

Push your website

Back on your local machine, set up a remote Git repository – I call mine “production” – which points to the repo on your server:

$ git remote add production git@myserver.com:mywebsite.git
$ git push production +master:refs/heads/master

…and hey presto! Your Git repo has been pushed to the production server – and when it finished the site was automatically checked out into your webroot!

Finally, to update the site in future, simply type:

$ git push production

(Admittedly, I do all my Git committing and pushing through the excellent Tower – which makes it even easier!)

A bit of help needed, please…

I would like a little advice from someone who knows their Git, if possible.

I have files which I don’t want copied to the webserver. Some of these - for instance, user-submitted files – I will add to .gitignore, because I don’t want them subject to source control at all; those are the easy ones.

But there are others – for instance, site config files – which I do want to be under source control, but the version on my live server will be different from that on my dev server, and I don’t want them to be overwritten by the automated update procedure.

Does anyone know of a simple way to achieve this?