Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
353 views
in Technique[技术] by (71.8m points)

Git checkout in post-receive hook: "Not a git repository '.'"

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:

#!/bin/sh
GIT_WORK_TREE=/home/andrew/web git checkout -f

When I run sh .git/hooks/post-receive, everything works fine. But when I push from my PC I get this error:

remote: fatal: Not a git repository: '.'

Is there a way how can I solve this issue? And eventually without having to switch bare repo?

Thank you

EDIT: Here's my new post-receive hook. Why it is like this has been described in the accepted answer.

echo "
Checking out $PWD"
GIT_DIR=/home/andrew/web/.git
GIT_WORK_TREE=/home/andrew/web git checkout -f
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

[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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...