从 git post-update 挂钩调用“git pull”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3542854/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 04:30:57  来源:igfitidea点击:

Calling 'git pull' from a git post-update hook

gitshellgithooks

提问by Kevin Dolan

I have a central git repo set up using gitolite.

我有一个使用 gitolite 设置的中央 git 存储库。

I want to set up a hook such that whenever a user pushes to the repo, it performs a pull elsewhere followed by some automated testing.

我想设置一个钩子,这样每当用户推送到存储库时,它就会在其他地方执行拉取操作,然后进行一些自动化测试。

So far, I only want to it perform the pull.

到目前为止,我只想让它执行拉动。

In the hooks directory I created the following script names post-update:

在 hooks 目录中,我在更新后创建了以下脚本名称:

#!/bin/sh  
cd /home/git/www/epicac
git pull

When I invoke this script using ./post-update, it does exactly what I want.

当我使用 ./post-update 调用此脚本时,它完全符合我的要求。

However, whenever it's invoked automatically as I hook, I get: fatal: Not a git repository: '.'

但是,每当它在我挂钩时自动调用时,我都会得到:fatal: Not a git repository: '.'

Any idea why this might be happening?

知道为什么会发生这种情况吗?

回答by VonC

You have various diagnostics to run as suggested in this SO answer.

您可以按照此SO answer 中的建议运行各种诊断程序。

In particular, check out the the value of GIT_DIRand GIT_WORK_TREE.

特别是,检查出的数值GIT_DIRGIT_WORK_TREE

While the hook is running, GIT_DIRand (if the worktree can't be inferred from GIT_DIR) GIT_WORK_TREEare set.
That means your pull won't run with the repository in the directory you changed to.

当钩子运行时,GIT_DIR和(如果不能从 推断出工作树GIT_DIRGIT_WORK_TREE被设置。
这意味着您的拉取不会与您更改的目录中的存储库一起运行。



See also blog post Using Git Inside a Git Hook:

另请参阅博客文章在 Git Hook 中使用 Git

Eventually we got our linux guru over and he noticed that the environment under which the git user runs is totally different when inside a hook.
Gitolite does a bunch of things to the env, but the one that was screwing us up was the setting of the GIT_DIR.
After we figured that out, the solution was as easy as:

最终我们得到了我们的 linux 大师,他注意到 git 用户在钩子中运行的环境完全不同。
Gitolite 对环境做了很多事情,但让我们搞砸的是GIT_DIR.
在我们弄清楚之后,解决方案很简单:

ENV.delete 'GIT_DIR'

in our ruby script that is triggered by the 'post-receive' hook.

在由 ' post-receive' 钩子触发的 ruby​​ 脚本中。



Same deal in Git Tip: Auto update working tree via post-receive hook, but with an elegant way out of this:

Git Tip: Auto update working tree via post-receive hook中也有同样的处理,但有一个优雅的方法:

The solution?
It turns out the post-receivehook starts out with the GIT_DIRenvironment variable set to the repo/.gitfolder, so no matter what path you 'cd' into it will always try to run any following git commands there.
Fixing this is simply a matter of unsetting the GIT_DIR
(thanks to Ulrich Petri for the elegant env -isolution):

解决方案?
事实证明,post-receive钩子开始时将GIT_DIR环境变量设置为repo/.git文件夹,因此无论您 'cd' 进入哪个路径,它都会始终尝试在那里运行任何以下 git 命令
解决这个问题只需取消设置GIT_DIR
(感谢 Ulrich Petri 的优雅env -i解决方案):

#!/bin/sh
cd ..
env -i git reset --hard

回答by satomacoto

How about specifying the --git-dir.

如何指定--git-dir.

#!/bin/sh
cd /home/git/www/epicac
git --git-dir=.git pull

回答by Fran Marzoa

This should do the trick in just one line:

这应该只用一行就可以解决问题:

git -C /home/git/www/epicac pull