bash Git post-receive hook 不工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2314500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git post-receive hook not working
提问by Silas Snider
We're using git with a central repo (using Gitosis). I've created a post-receive hook to generate an email to the dev mailing list whenever changes are pushed to the central repo, and to generate documentation from the documentation folder in the git repo.
我们将 git 与中央仓库一起使用(使用 Gitosis)。我创建了一个 post-receive 挂钩,以便在将更改推送到中央存储库时向开发邮件列表生成一封电子邮件,并从 git 存储库中的文档文件夹生成文档。
Therefore, in ~git/ I've got a directory, we'll call it 'a' that contains a clone of the git repo. The post-receive hook looks like:
因此,在 ~git/ 中,我有一个目录,我们将其称为“a”,其中包含 git 存储库的克隆。post-receive 钩子看起来像:
#!/bin/bash
cd ~git/repositories/a.git
. ~git/post-receive-email &> /dev/null
( cd ~git/a && git pull &> ~git/pull_log.log && php ~git/a/scripts/generate_markdown_documentation.php &> ~git/doc_log.log )
The email script is working, but the documentation generation is not. The content of pull_log.log is:
电子邮件脚本有效,但文档生成无效。pull_log.log 的内容是:
fatal: Not a git repository: '.'
Which makes me think that it's not changing to the correct directory in line 5 of the above script. Am I wrong? How can I get this to work?
这让我认为它没有更改为上述脚本第 5 行中的正确目录。我错了吗?我怎样才能让它工作?
Edit:I've updated the post-receive hook as suggested in the responses. The script is now:
编辑:我已经按照回复中的建议更新了接收后挂钩。脚本现在是:
#!/bin/bash
function die {
echo "$*" >&2; exit 1
}
function checkgit {
[ -d "/.git" ] || die " could not possibly be a git repo; /.git is not a dir"
}
cd ~git/repositories/a.git
. ~git/post-receive-email &> /dev/null
( set -x
checkgit ~git/a
cd ~git/a
checkgit .
pwd
git pull
php ~git/a/scripts/generate_markdown_documentation.php )
And I get the following output from git push:
我从 git push 得到以下输出:
+ checkgit /var/git/a
+ '[' -d /var/git/a/.git ']'
+ cd /var/git/a
+ checkgit .
+ '[' -d ./.git ']'
+ pwd
/var/git/a
+ git pull
fatal: Not a git repository: '.'
+ php /var/git/a/scripts/generate_markdown_documentation.php
Any more help?
还有什么帮助吗?
Oh, and if I run the script myself, it works (I run it by saying hooks/post-receive)
哦,如果我自己运行脚本,它就可以工作(我通过说 hooks/post-receive 来运行它)
Discovered the problem, thanks to serverfault-- basically, environment variables GIT_DIRand GIT_WORK_TREEare set when the hook runs, and these affect git pull adversely. Unsetting the variables fixes the problem.
发现问题,多亏了serverfault——基本上,环境变量GIT_DIR和GIT_WORK_TREE钩子运行时设置,这些对 git pull 产生不利影响。取消设置变量可以解决问题。
采纳答案by Norman Ramsey
You need more diagnostics, e.g.,
您需要更多的诊断,例如,
function die {
echo "$*" >&2; exit 1
}
function checkgit {
[ -d "/.git" ] || die " could not possibly be a git repo; /.git is not a dir"
}
At this point, in the subshell right after the parenthesis, you can try stuff like
此时,在括号后的子shell中,您可以尝试类似的东西
set -x # show exactly what's executed (writes to stderr)
checkgit ~git/a
cd ~git/a && checkgit . && git pull ...
You might also consider redirecting the whole stderr of the subshell, e.g.,
您也可以考虑重定向子shell的整个stderr,例如,
( ... ) 2>/tmp/mydiagnosis$$.log
(This is a temporary measure and is OK only if there's no confidential info in the logs.)
(这是一种临时措施,只有在日志中没有机密信息时才可以。)
OK Silas, your additional info rules out a lot of awkward possibilities. I'm nearing the end of my gitfu, but here are some more things to try:
好的塞拉斯,你的附加信息排除了很多尴尬的可能性。我的gitfu快要结束了,但还有一些事情要尝试:
- Go into
~git/aand see if you can make itgit pullby hand. This should fail. - Got into
~git/aand rungit status. This should also fail. If it doesn't, thengitis giving you a very bad error message.
- 进去
~git/a看看能不能git pull亲手做。这应该失败。 - 进入
~git/a并运行git status。这也应该失败。如果没有,那么git会给你一个非常糟糕的错误信息。
If both steps fail, ~git/ais not the clone you thought it was. Rename it, make a new clone, and see if you can get the problem to persist.
如果这两个步骤都失败了,那么这~git/a不是您认为的克隆。重命名它,制作一个新的克隆,看看是否可以让问题持续存在。
If the first step succeeds by hand, then something strange is going on and I'm baffled.
如果第一步手动成功,那么就会发生一些奇怪的事情,我很困惑。
If the first step fails but the second succeeds, you may have a problem with branches:
如果第一步失败但第二步成功,你可能会遇到分支问题:
Perhaps repo
~git/ais set to the wrong branch, and your repo needs a branch it doesn't have. Trygit branch -aand see if you see something unexpected.Perhaps you have the branch, but it's not properly associated with a remote repository. At this point you have to dive into
~git/a/.git/config, and I don't really know how to explain what you should expect to find there. At that point you will need a realgit expert; I just play one on TV.
也许 repo
~git/a设置了错误的分支,而您的 repo 需要一个它没有的分支。试着git branch -a看看你是否看到了意想不到的东西。也许你有这个分支,但它没有与远程存储库正确关联。在这一点上,您必须深入了解
~git/a/.git/config,我真的不知道如何解释您应该期望在那里找到什么。那时你将需要一个真正的git 专家;我只在电视上玩一个。
回答by TheDeadSerious
I recently ran into a similar problem and I think it is related to the environment variables that git sets, specifically the $GIT_DIR variable. If you have that set, all git commands on other repos start to act weirdly. Basically I think that running your git pull inside the hook must be invoked in a neutral shell environment that does not have those odd variables and leads to git confusion, though I haven't figured out how to do that just yet.
我最近遇到了一个类似的问题,我认为它与 git 设置的环境变量有关,特别是 $GIT_DIR 变量。如果你有这个设置,其他 repos 上的所有 git 命令都会开始表现得很奇怪。基本上,我认为在钩子内运行 git pull 必须在没有那些奇怪变量并导致 git 混乱的中性 shell 环境中调用,尽管我还没有想出如何做到这一点。
回答by Sunthar
unset GIT_DIRis a solution which works for the fatal error you are seeing.
unset GIT_DIR是一种适用于您所看到的致命错误的解决方案。
This applies to all scripts in hooks (post-update is another common one), which uses the git command inside it. git command uses the GIT_DIR from env instead of pwd.
这适用于钩子中的所有脚本(post-update 是另一个常见的脚本),它在其中使用 git 命令。git 命令使用来自 env 的 GIT_DIR 而不是 pwd。
See https://stackoverflow.com/a/4100577for further explanation.
有关进一步说明,请参阅https://stackoverflow.com/a/4100577。

