Select Page


Deployment to the live server consists of creating a bare repo in a location on the server accessible via SSH, then pushing to that. A hook script is setup inside this repo to pull any changes out into the working directory for that particular site.


You need to be able to push changes over SSH to the live server. This means your local machine’s SSH setup must contain the proper keys and an appropriate configuration.

In the case of projects that use private submodules, the server and GitHub repo will need to be set-up with the appropriate deployment keys.

Creating the Remote Repo

SSH into the live server, and under the home directory will be a folder called “Repos”. Inside here, create a folder with the name of the repo and a “.git” extension. For consistency, match the name used for the repo inside GitHub.

cd ~/Repos
mkdir how-it-works.git

Change into the newly created directory and initialise a “bare” git repository. A bare repo only has information about the various branches and commits and has no working directory. This means that there are no local changes in this repo, so changes from elsewhere can be pushed in without any conflicts (if it was not bare, a pull action would be necessary, which involves logging in to the server each time).

Pushing Changes

This repo can then be set-up as a remote to any local repo. To push changes over SSH, you just require the location of the repo on the server and the server address:

git remote add live ssh://

The current state can then be pushed to this repo’s master branch:

git push live master

The Working Directory

We can now set-up the main location for the site (i.e. where you would normally upload files to over FTP) as a working directory and pull changes from this bare repo. How this is done depends on whether it’s a new site or an existing one.

For a new site, the process is very simple. It involves changing into the directory where the new site is going to be based and cloning from our bare repo.

cd ~/www/
git clone /home/imagineftp/Repos/how-it-works.git .

For a site that already contains files, it’s a little more complicated. We need to create a git repo out of the current directory, add a remote to it under the name “origin”, fetch the branches from the origin and then checkout a branch into master.

cd ~/www/
git init
git remote add origin /home/imagineftp/Repos/how-it-works.git
git fetch
git checkout -f -b master origin/master

The “-f” flag will overwrite all files in the directory that are currently under version control. Any files in the destination directory that are not under version control will stay as they are. Running a “git status” will no show all the remaining untracked files. These should either be removed if they’re not necessary or added to the “.gitignore” file.

Receive Hooks

After pulling from the bare repo the first time, we want to automate the process of merging in new changes. The act of pushing changes to the bare repo can trigger a script called a post-receive hook. This is simply a bash or other script within the bare repo.

Here’s an example script to take changes pushed to the bare repo and merge them into the working tree where the site sits:


cd /home/imagineftp/www/
git fetch
git merge origin/master
git submodule update --init --recursive

After setting up some environment variables and changing into the working directory for the site, the script fetches all the current refs from all the remotes. It then merges the master branch from the origin remote (which should point to the bare repo). Finally, it will update all submodules within the repo.

This script would sit inside the bare repo’s “hooks” directory, named “post-receive”. Make sure that execute permissions are set properly on this file otherwise it will not be able to run:

chmod a+x post-receive

The output of this script will be echoed back to you when you push changes to the bare repo so that any problems can be addressed.