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). 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:
- Locally clone my existing repo to a bare one (using git clone –bare)
- Copy this bare repository (a folder called something.git) to my server with scp. This is now the “hub”.
- 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 firstname.lastname@example.org:git/ cd mygitfolder git remote add myserver email@example.com: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 firstname.lastname@example.org 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:
#!/bin/sh 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 email@example.com: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