【问题标题】:How to setup server side pre-receive hook?如何设置服务器端预接收挂钩?
【发布时间】:2018-11-03 10:50:49
【问题描述】:

我是 git 钩子和服务器端 git 功能的新手。我在客户端 git 上工作以提交和推送我的代码,我们使用 应用程序生命周期管理 (ALM) 工具 进行 git 合并。 我正在尝试编写 git 挂钩来对存储库中的新/修改文件进行一些测试。我能够编写和测试客户端钩子,例如 pre-commit

现在,我需要在合并到 master 之前添加一些服务器端 git 挂钩来验证文件,因为使用 -no-verify 选项跳过客户端验证进行了更改。当我浏览一些 git hook 教程时,pre-push hook 是服务器端的 hook。我试图创建预推送挂钩,它正在客户端工作。现在,即使使用 --no-verify 选项(不应在客户端上控制),当用户尝试推送更改时,如何将其作为服务器端挂钩并强制验证文件。

我最大的问题是当我们从本地分支/repo 执行git push 时如何触发服务器挂钩。

钩子的创建:

创建了一个名为 pre-commit 的钩子,并将其放在某个文件夹 git_hooks/pre-push.git/hooks/pre-push 中。现在,为我的预推送脚本创建了一个符号链接。因此,每当我执行 git push 时,它都会触发 .git/hooks/pre-push,这是我的脚本的符号链接 git_hooks/pre-push

编辑:

我认为pre-pushpre-receive 钩子是相同的,因为它们都是在git push 命令上触发的,但pre-push 仅在客户端工作,pre-recieve 在服务器端工作。 我创建了pre-receive 钩子并将其推送到主分支。现在,当我 git push 得到这个 error: cannot spawn hooks/pre-receive: No such file or directory

我在 WindowsLinux 平台上都在尝试这个。在 Windows 上我收到此错误,在 Linux 上它甚至没有被触发。我在两个平台的主分支上都放置了pre-receive 钩子。

【问题讨论】:

  • 我回答你的问题了吗?
  • @for 寻找答案的人: 错误:无法生成挂钩/预接收:没有这样的文件或目录。这个错误的原因是错误的 SHEBANG。我修改了它,我没有收到任何错误,并且预接收挂钩工作正常。我们应该将 pre-receive 钩子放在服务器 .git/hook 文件夹中,然后每当您尝试推送更改时,服务器都会触发此钩子。无需在本地仓库中使用它。

标签: git githooks


【解决方案1】:

您应该查看 Server side hooks 文档部分。

共有三个钩子可让您对 git push 过程的不同阶段做出反应。

  • 预收
  • 更新
  • 接收后

当你推送到服务器pre-receive 时,钩子被触发。然后,对于您推送的每个分支,都会触发 update 挂钩。当这些钩子完成且没有错误时,您的补丁将被应用并触发post-receive 钩子

更详细的DOC关于pre-receive钩子:

当 git-receive-pack 响应 git push 并更新其存储库中的引用时,会调用此钩子。就在开始更新远程存储库上的 refs 之前,调用了 pre-receive 钩子。它的退出状态决定了更新的成败。

UPD

要设置pre-receive 服务器端挂钩,您应将脚本放入服务器上的.git/hooks 目录。并将其命名为pre-receive。仅此而已。
您不应该在您的存储库中创建 hooks 目录并提交它。 pre-receive 脚本在 repo 之外

UPD
这是示例脚本:

#!/bin/bash


# check each branch being pushed

echo "pre-receive HOOK"

while read old_sha new_sha refname
do

if git diff "$old_sha" "$new_sha" | grep -qE '^\+(<<<<<<<|>>>>>>>)'; then
    echo "Saw a conflict marker in $(basename "$refname")."
    git diff "$old_sha" "$new_sha" | grep -nE '^\+(<<<<<<<|>>>>>>>)'
    exit 1
fi

if git diff "$old_sha" "$new_sha" | grep -qE '^\+.*\s+$'; then
    echo "Saw whitespaces at EOL."
    git diff "$old_sha" "$new_sha" | grep -nE '^\+.*\s+$'
    exit 1
fi

done

exit 0

【讨论】:

  • 感谢您的帮助。我认为 pre-push 和 pre-receive 是相同的,但两者是不同的。 git push 也会触发预推送,但仅限客户端。我已经创建了 pre-receive 钩子,但我得到 error: cannot spawn hooks/pre-receive: No such file or directory.
  • @Rekha:我已经更新了答案。您只需将服务器上的pre-receive 脚本放入.git/hooks 目录即可。就这些。如何使这个脚本正常工作是另一个问题。
  • 是的。我也补充了。 hooks/pre-receive: 没有这样的文件或目录 这仅代表 .git/hooks。文件在那里,但仍然显示这样的错误。我无法弄清楚。一些它是如何触发事件但无法正常工作的。
  • @Rekha:我想你使用pre-push 作为pre-receive。你不能这样做。看看我的脚本。
  • @Eugen Konkov 感谢您的帮助。
猜你喜欢
  • 2020-02-11
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
相关资源
最近更新 更多