I have a non-bare repository at my server (dirs /home/andrew/web and /home/andrew/web/.git), set receive.denyCurrentBranch to ignore and created post-receive hook:
[Edit, Feb 2017: this old answer still gets hit a bit, so let's add a few notes. (1) This kind of live update is often a bad idea: be sure you know why you're doing it, and that you won't clobber your own work. (2) In Git since 2.3, you can now configure receive.denyCurrentBranch
to updateInstead
, plus a hook tweak in Git 2.4 and later. For details, see the git config documentation.]
The post-receive hook is run with $GIT_DIR
set to .
. This causes git to look for ./HEAD
, ./refs/heads/master
, etc., rather than .git/HEAD
, .git/refs/heads/master
, etc. But, since you don't do anything to change $PWD
in the hook (as shown anyway), the hook will be running in the .git
subdirectory (/home/andrew/web/.git
), and hence this failure is quite mysterious: .
will in fact be a valid git repository.
One standard trick that avoids hard-coding the path name is to use cd ..; git checkout -f
as the post-receive hook. This is where the setting of $GIT_DIR
becomes a problem, because after cd ..
the hook is running in (still assuming this case) /home/andrew/web
and of course at that point, $GIT_DIR
should be .git
rather than .
. The standard fix for that is simply to unset GIT_DIR
(setting it to .git
would also work).
Your post-receive hook as shown works fine for me, though (with appropriate hard-coded-path changes). Then again I am pushing from a Unix-like machine, not a PC. Is it possible there's something else happening, that changes directories out of the .git
subdirectory? You can do something like echo running in $PWD
in the hook to see where you are.