If you have a git repository that you’d like to deploy to a remote server by pushing it, there’s a few things you’ll have to watch out for.
Specifically, if you try to just push the repository and leave it at that, you’ll notice that the files never get updated. This is because the working tree is not updated when commits are pushed to the repository, unless you make special arrangements for that to happen.
To make these arrangements, you need to use hooks to provide instructions for
git as to what it should do and when. There’s a massive amount of flexibility here,
but for the simple case of updating the working tree after a push, you want the
post-receive
hook.
The hook scripts live in a hooks
directory inside the (hidden) .git
directory.
They’re simple scripts, so you can write them in any language you want that can be
called from the shell. But usually they’re just written in normal shell script: sh
,
bash
, whatever.
But the real twist in this is that you might think you could just do a git reset --hard HEAD
in the post-receive
hook and your working tree would update and everything would be kittens and daffodils. But you’d be gravely mistaken.
The problem is that when the hook is run, the GIT_DIR
and other variables are pointing
inside the .git
directory itself. This means that if you do the aforementioned
git reset
, you will pour a copy of your working tree in the wrong place,
inside the .git
directory. Even worse, if some of your files happen to overlap the
names that git
uses to track the state of the repository, you now have completely
screwed your repo’s state of mind.
So how to avoid this? Well, in short, just use this script:
#!/bin/bash
test "${PWD%/.git}" != "$PWD" && cd ..
unset GIT_DIR GIT_WORK_TREE
exec git reset --hard HEAD
This will do what you want, in the simple case of updating the working tree after a push, which is perfect for updating a website on a remote server. You could add some commands at the end for kicking your webserver or application server if you need to, in order for it to realize something changed.
Enjoy!