检测 push --mirror 的 Git 钩子

3
在使用 Gitolite 在服务器上的主 Git 仓库旁边,我希望每个开发者都有可能建立自己本地仓库的镜像。这并不困难。但是,我想禁用主 Git 服务器仓库上的 `git push --mirror` 命令,以防止开发者在进行镜像时出错。我认为最好的地方是 hook,也许是 update hook。但是我无法找到如何在服务器 hook 中检测到客户端机器上已经执行了 `push --mirror` 命令的方法。由于我们还使用 Eclipse Git (JGit),所以客户端解决方案是不可行的。

https://dev59.com/YW435IYBdhLWcg3wtCWQ - sehe
我想保留对主仓库的所有访问权限,包括拉取、推送和删除。只是禁用推送 --mirror 功能。据我所知,文件系统访问无法帮助我实现这一点。 - xmedeko
2个回答

2
如果您真的想使用钩子来完成此操作,则要使用的钩子将是 pre-receive。您无法直接检测它是否为镜像推送,因为发送的数据中没有关于其的任何内容,但您可以很聪明地几乎每次都正确地获取到。pre-receive钩子获取要更新的引用列表,包括旧值和新值,如果以非零状态退出,则整个推送都会被取消。镜像推送的主要特征可能是它还会按原样推送远程分支。我想不出任何正常情况下您会这样做的情况,所以您可以进行检查,例如:
#!/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*都会触发此钩子,因此它应该适用于您;当然,这有点过于热心,但除非您打算在中央仓库中维护远程分支,否则不会有影响。 *除了一个非常手动的操作,即有人通过手动指定git push --mirror <url>从没有远程的仓库推送,但我真的希望您不必担心这个。
我仍然建议使用gitolite。它并不能完全阻止镜像推送,但可以在一定程度上提供帮助,并提供许多其他有用的功能。请注意,gitolite允许您添加自己的钩子,因此想要使用此功能不应妨碍您获取所有gitolite好处。如果您不打算使用Gitolite,则应将core.logAllRefUpdates设置为true以确保在出现错误推送时可以进行恢复。
与此问题相关的gitolite会为您完成以下事项:
  • 允许您限制大多数开发人员只能访问关键分支,并防止他们删除任何内容(使用而不是权限),因此他们可能造成的损害是有限的-删除分支可能是push --mirror的最糟糕部分
  • 更全面地记录访问,以便如果某人造成了损坏,您可以准确地看到是谁以及他们做了什么,并避免将来出现类似情况

非常好,非常感谢。只是在消息中应该使用普通的撇号:“你正在推送远程分支 - 你使用了 'push --mirror' 吗?” - xmedeko

2

我不建议使用钩子来“修补”安全性。它们没有为这种访问控制而设计。

你可以考虑使用 gitolite。它可以让你在预设的分支上控制访问权限。

请参考 https://github.com/sitaramc/gitolite/wiki


谢谢回复。当我在客户端执行 push --mirror 命令时,Gitolite 会接收到 "git-receive-pack" 和 "git-upload-pack" 这样的命令,就像普通的 fetch 和 push 一样。所以我不知道如何在 Gitolite 中检测 push --mirror。 - xmedeko
也许这是不可能的。我将继续保持--mirror允许,并编写一些好的备份脚本。谢谢您的回复。如果没有其他回复出现,我会将您的回答标记为已接受。 - xmedeko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接