用于检测推送的 Git 钩子(Hook) --mirror

标签 git githooks gitolite

除了服务器上的主 Git 存储库(使用 Gitolite)之外,我希望每个开发人员都可以设置一个镜像,它是自己的本地存储库。这并不难。

但是,我想在主 Git 服务器存储库上禁用 git push --mirror,以防止开发人员搞砸镜像时出错。我认为最好的地方是一个钩子(Hook),也许是更新钩子(Hook)。但是我找不到如何在服务器 Hook 中检测到 push --mirror 命令已在客户端计算机上执行。

客户端解决方案是不可能的,因为我们也使用 Eclipse Git (JGit)。

最佳答案

如果你真的想用钩子(Hook)来做这件事,要使用的钩子(Hook)是pre-receive .您无法直接检测到它是镜像推送,因为发送的数据中没有任何内容表明它是镜像推送,但您可以聪明地几乎始终正确。预接收 Hook 获取要更新的引用列表,其中包含旧值和新值,如果它以非零状态退出,则整个推送将中止。镜像推送的主要区别可能是它还按原样推送远程分支。我想不出你会在任何正常情况下这样做,所以你可以检查一下,比如:

#!/bin/bash
while read old new ref; do
   if [[ "$ref" =~ "^refs/remotes/.*" ]]; then
        echo "You're pushing remote branches - did you use 'push --mirror'?"
        echo "Rejecting push"
        exit 1
   fi
done

任何push --mirror * 会绊住这个钩子(Hook),所以它应该能盖住你;这当然有点过分热心,但除非您打算在中央仓库中维护远程分支,否则这无关紧要。

*除了一个真正手动的,有人通过手动指定 git push --mirror <url> 从没有远程的 repo 推送,但我真的希望您不必为此担心。


我仍然会推荐 gitolite .它并不能完全让您拒绝镜像推送,但它可以提供一些帮助,并提供许多其他有用的东西。请注意,gitolite 确实允许您添加自己的钩子(Hook),因此想要使用它不应该阻止您获得所有 gitolite 的优点。如果你不打算使用 Gitolite,你真的应该设置 core.logAllRefUpdates在中央仓库中设置为 true,这样如果有人确实收到了你的错误推送,你就可以恢复。

gitolite 会为您做的与此问题相关的事情:

  • 让您限制大多数开发人员只能访问关键分支,并防止他们删除任何内容(使用 RW,而不是 RW+ 权限),因此他们可以造成的损害是有限的——删除分支可能是push --mirror 最糟糕的部分
  • 更全面地记录访问,这样如果有人确实造成了损害,您可以准确地看到是谁以及他们做了什么,并在将来避免这种情况

关于用于检测推送的 Git 钩子(Hook) --mirror,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9210957/

相关文章:

javascript - 重复的 git 仓库

git - 在预推 Hook 中克隆 GIT 存储库时出现异常 "working tree already exists"

git - 让 Git 在提交之前自动删除尾随空格

git - 如何在 git push 后运行 bash 脚本

git - git镜像后无法从远程存储库读取

python - sourcetree 与 python Hook

git cherry-pick 不只是选择提交的差异

发布分支上的 Git 流困惑

GIT Smart Http - R 任何被 fallthru 拒绝

gitolite 设置恢复了更改