Git post-receive钩子报错:No such file or directory及‘Not a git’问题求助
解决Git Post-Receive钩子同步报错问题
你的post-receive钩子用git checkout -f同步代码时出现fatal: Not a git...和No such file or directory报错,大概率是路径、权限或Git环境变量的问题,咱们一步步排查解决:
1. 先验证路径的准确性
No such file or directory首先要怀疑路径写错了:
- 确认
WRK_DIR和GIT_DIR是绝对路径,比如服务器上真实的/var/www/my-project/或/home/git/my-repo.git,别用相对路径——钩子运行时的工作目录是裸仓库根目录,相对路径极易出错。 - 直接在服务器终端手动执行钩子里的命令:
git --work-tree=/真实工作目录 --git-dir=/真实裸仓库.git checkout -f,如果这里就报错,那肯定是路径不对。
2. 检查目录权限
即使路径正确,钩子运行的用户(通常是git用户或推送代码的用户)可能没有访问权限:
- 裸仓库的
.git目录(即GIT_DIR)需要给运行用户读权限,工作目录WRK_DIR需要读写权限。 - 可以用
sudo chown -R git:git /真实工作目录 /真实裸仓库.git(假设运行钩子的用户是git)统一设置权限。
3. 修复fatal: Not a git repository错误
这个错误通常是GIT_DIR路径不对,或者环境变量干扰了Git的识别:
- 裸仓库路径要直接指向
.git目录,比如你的裸仓库是/home/git/my-site.git,那GIT_DIR就写这个完整路径,别多写或少写层级。 - 钩子脚本开头加上
unset GIT_DIR,因为Git有时会自动设置这个环境变量,导致你指定的--git-dir参数失效。修改后的脚本示例:
#!/bin/bash unset GIT_DIR WRK_DIR="/真实的工作目录/" GIT_DIR="/真实的裸仓库.git/" git --work-tree=$WRK_DIR --git-dir=$GIT_DIR checkout -f
- 别忘了给钩子加执行权限!运行
chmod +x post-receive,否则钩子根本无法执行,也会报奇怪的错误。
4. 调试技巧:加日志定位问题
如果还是排查不出,可以在钩子里加日志输出,方便看详细错误:
#!/bin/bash unset GIT_DIR WRK_DIR="/真实的工作目录/" GIT_DIR="/真实的裸仓库.git/" # 把操作日志写入文件 echo "[$(date)] 开始同步,WRK_DIR: $WRK_DIR, GIT_DIR: $GIT_DIR" >> /var/log/git-hook.log git --work-tree=$WRK_DIR --git-dir=$GIT_DIR checkout -f >> /var/log/git-hook.log 2>&1
推送代码后查看/var/log/git-hook.log,就能看到具体是哪个路径不存在,或者Git命令的详细报错信息。
最后提醒:钩子脚本开头一定要加#!/bin/bash,否则系统可能用默认的sh执行,会出现语法或环境适配问题。
内容的提问来源于stack exchange,提问作者ToastedToast
相关产品推荐
相关产品推荐

