如何将git仓库设置为只读?

64

我有一些通过SSH远程访问的Git仓库,我想将其中一些设置为只读以防止更多的推送。有些人已经在这些仓库上建立了远程指向。

这些裸仓库是使用--shared=group初始化的,所以将所有文件的文件权限设置为660是否足以允许SSH访问但禁止写入?或者有更简单的方法吗?

谢谢。

10个回答

54

有不止一种可能的方法来完成这个任务。

  • 如果您的用户每个人都有一个shell帐户(可能是受限制的),并且他们每个人都通过自己的帐户访问git存储库,则可以使用文件系统权限来控制对git存储库的SSH访问。在Unix上,这些将是目录上的写入权限,可能需要创建一个组并为组设置特定权限(设置“粘性组ID”)。

  • 推送需要用户的$PATH中有git-receive-pack,并且对于他们来说可执行...虽然我不确定这种方法的可行性。

  • 您可以使用updatepre-receive挂钩来控制对存储库的访问控制,例如使用git源中的contrib/hooks中的update-paranoid示例挂钩。

  • 对于较大数量的用户,最好使用工具来管理对git存储库的访问,例如Gitosis(在Python中,需要setuptools)或Gitolite(在Perl中)。

  • 对于只读访问,您可以设置git daemon以通过git://协议提供只读匿名(未经身份验证)访问,而不是通过SSH协议访问。

    有关一种简化从SSH到GIT协议过渡的方法,请参阅url.<base>.insteadOf配置变量的文档。


请参阅Scott Chacon的Pro Git书中关于"服务器上的Git"的第四章(CC-BY-NC-SA许可证)。


2
应该注意到,对于文件系统权限,您可以使用chmod,正如Pat Notz所建议的那样。 - Emil Sit
10
谢谢大家的建议。受到“update-paranoid”例子hook的启发,我现在在我的代码库中有一个hook,它只是执行echo "Closed for all pushes" ; exit 1 - Steve Folly
2
@SteveFolly 如果您的评论是一个答案,我会投票支持它而不是被接受的答案。您的评论简短、明了且有效。 - Klas Mellbourn
@KlasMellbourn 我根据Steve的评论添加了一个适当的答案。 - Per Lundberg
在没有访问配置整个实例的情况下,是否可以使用GitHub Enterprise完成此操作,这意味着org/repo所有者可以执行此操作?根据此文档,似乎实际服务器的管理员需要帮助您:https://help.github.com/en/enterprise/2.18/admin/developer-workflow/creating-a-pre-receive-hook-script - kayleeFrye_onDeck

16

一个简单输出信息并以非零状态退出的 pre-receive 钩子就可以完成任务。

假设您在消息中放入了一些有意义的信息,它还可以减少来自沮丧的用户的查询,询问为什么他们无法推送:

#!/bin/bash
echo "=================================================="
echo "This repository is no longer available for pushes."
echo "Please visit blah blah yadda yadda ...."
echo "=================================================="
exit 1

记得为脚本设置可执行权限,并确保它归属于正确的用户和/或组,否则它将无法执行也不会给出任何警告。


8
chmod -R a-w /path/to/repo.git

1
“将其中一些设为只读以防止更多的推送” - 这样做会防止拉取,不是吗? - androidguy

3
由于git主要依赖文件系统进行访问控制,所以这将起作用。请注意,在您的权限中,世界无法访问该文件,但用户和组具有读/写访问权限。如果您想使世界可读,则应将权限设置为0444
您可以通过将repo权限设置为0664,其中用户为nobody,组为gitdevs之类的内容,进一步进行细粒度控制。然后,只有gitdevs组中的人才能够对repo进行写入,但世界可以从中读取。
跟进这里是一个链接,介绍了各种共享repo的方法,并涵盖了一些专业术语和访问控制功能。

666是全球可读写的文件。776是全球和组可读、可写和可执行,其他用户只能读写。不确定您推荐的数字来源在哪里,但它们通常是危险的。 - Dustin
谢谢,我改正了我的回答。打字太多,思考不够。 - jheddings

3

这个评论的启发:

  1. Update your hooks/pre-receive file with the following content:

    #!/bin/sh
    
    echo "Closed for all pushes" ; exit 1
    
这样,所有试图向此仓库推送更改的用户都将收到上述消息,并且推送将被拒绝。

1
谢谢。这对我有用。顺便提一下,值得一提的是,钩子目录位于存储库根文件系统路径下。 - hmacias

1
如果您需要访问控制,可以查看gitosis。它非常容易设置,并且您可以使用简单的脚本来控制谁可以做什么。

0
另一种可能性是使用git协议,但需要运行git守护进程。


0

由于我只是我们GitLab的用户(并且一开始不想打扰管理员),因此我寻找了另一种方法并找到了一个:

  • 打开GitLab Web界面并转到要设置为只读的存储库
  • 选择设置 > 存储库
  • 展开受保护的分支
  • 添加主分支并将允许合并允许推送设置为无人
  • 如果主分支已受保护,则可以在下面的列表中设置这些值

0

最近我使用了限制访问路径“/repo.git/git-receive-pack”来实现仓库对某些用户为读写权限,对其他用户为只读权限的结果。在httpd配置中,它看起来像这样:

    <Location /repo.git/>
            Require group developers developers-ro
    </Location>

    <Location /repo.git/git-receive-pack>
            Require group developers
    </Location>

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