I have been using a git-based web publishing workflow now for a few projects, and now have finally hooked it up to my personal site (automatist.org). Before you proceed reading the whole article, read process builder vs workflow first. For my own documentation, I thought I’d write down my take on what has proven to be a very useful tutorial: Joe Maller’s “A web focused git workflow“.

Basically what Maller’s setup explains is how to create git publishing relays so that pushing changes from one (local) repo gets relayed automatically to another, for instance a live online website. The trick is that you need to use a bare respository that acts as a “hub” allowing changes to be pushed from any of the satellites.

Turns out, you really need a bare repository as these are the connecting elements of git. You can’t (or at least shouldn’t) push to a repo with a working directory (ie a git repo that actually has it’s files “exposed” as a regular directory with files). Instead bare repositories are like inside out folders, where the tender files are hidden away, and whose main purpose is to push to and pull from.


Slightly different from Maller’s method, I usually start from an existing repo, that may or may not already have a remote. To start, the steps I usually follow are:

  1. Locally clone my existing repo to a bare one (using git clone –bare)
  2. Copy this bare repository (a folder called something.git) to my server with scp. This is now the “hub”.
  3. Add the hub as a remote to the starting repo.

which means something like:

cd /path/to/mygitfolder
cd ..
git clone --bare mygitfolder mygitfolder.git
scp -r mygitfolder.git me@myserver.net:git/
cd mygitfolder
git remote add myserver me@myserver.net:git/mygitfolder

Then on the server, I clone from the hub into a “live” working directory that’s publically served by my webserver. Caution: At this point the contents of the .git are publically accessible (which means that all versions and commit history could be accessed, which is not what I want). See the end about how to fix this.

ssh me@myserver.net
cd /var/www/
git clone ~/git/mygitfolder .

Finally I create a post-update hook script in the hub (triggered after things are pushed to it) that automatically steps across into the “live” repo and pulls the new changes from the hub..

cd ~/git/mygitfolder.git/hooks
cp post-update.sample post-update
emacs post-update

and edit this to:

cd /var/www/vhosts/automatist.org/httpdocs || exit
unset GIT_DIR
git pull origin	master
# though it seems wrong to me; this must come after the above
exec git update-server-info

Now, when I commit changes and push from the initial repository, I see “remote” messages that show the update propagating to the live repo.

Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 303 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: From /home/myusername/git/mygitfolder
remote:  * branch            master     -> FETCH_HEAD
remote: Updating d54b302..a3f49d3
remote: Fast-forward
remote:  index.html |    2 +-
remote:  1 file changed, 1 insertion(+), 1 deletion(-)
To me@server.net:git/mygitfolder
   d54b302..a3f49d3  master -> master

To fix the visiblity of the .git folder, there are a number of things you can do (as usual), I ended up just changing the permissions of .git:

cd /var/www/
chmod 750 .git