题 如何在计算机上与多个用户共享Git存储库?


我在登台服务器上有一个Git存储库,多个开发人员需要能够提供这个存储库。 git-init 似乎有一个非常接近我正在寻找的旗帜: --shared,除了我想让多个人拉到那个存储库之外。该 git-clone--shared 旗帜完全不同。

更改现有存储库权限的最简单方法是什么?


201
2018-06-17 01:04




我正在使用“Github for Windows”并在两个Github帐户之间切换: stackoverflow.com/questions/18565876/... - Alisa


答案:


许可是一种害虫。

基本上,您需要确保所有这些开发人员都可以写入git仓库中的所有内容。

简要介绍新浪潮解决方案,以获得授予一组开发人员写入功能的卓越方法。

标准解决方案

如果您将所有开发人员放在一个特别创建的组中,原则上您可以这样做:

chgrp -R <whatever group> gitrepo
chmod -R g+swX gitrepo

然后改变 umask 为了用户 002,以便使用组可写权限创建新文件。

这个问题很多;如果你在一个假设一个发行版的发行版上 umask 的 022 (比如有共同点 users 默认情况下包含所有人的组),这可以在其他地方打开安全问题。迟早,某些东西会搞砸你精心设计的权限计划,让repo停止运行直到你得到 root 访问并修复它(即重新运行上述命令)。

新浪潮解决方案

一个优秀的解决方案 - 虽然不太了解,需要更多的OS /工具支持 - 是使用POSIX扩展属性。我最近才来到这个地区,所以我的知识并不是那么热。但基本上,扩展ACL是能够在不仅仅是3个默认插槽(用户/组/其他)上设置权限。

再次,创建您的组,然后运行:

setfacl -R -m g:<whatever group>:rwX gitrepo
find gitrepo -type d | xargs setfacl -R -m d:g:<whatever group>:rwX

这将为组设置扩展ACL,以便组成员可以读取/写入/访问已存在的任何文件(第一行);然后,还告诉所有现有目录新文件应该应用相同的ACL(第二行)。

希望能让你顺利前进。


171
2018-06-17 06:00



git init有一个名为--shared的参数,它为组工作设置core.sharedRepository变量。您还可以在现有存储库上设置变量。这消除了手动设置umask的需要,因为git会在操作文件之前将其设置为合理的值。 - ptman
为POSIX扩展属性+1 - 给我新闻! - RobM
我什么时候做的 chmod -R g+swX,它让Git非常不满意,并且它决定它不再是一个git存储库(“repo似乎不是一个git存储库”)。我不得不chmod g-s所有的 档。只需设置setgid位 目录,试试 find /path/to/repo -type d -print0 | xargs -0 chmod g+s。仍然这样做 chgrp -R thegroup /path/to/repo。 - rescdsk
chmod -R g+swX gitrepo 将setguid位应用于文件,这是一个安全风险。相反,你可以使用 find . -type d -exec chmod g+s {} + 仅将其应用于目录。 - Ian Dunn
ACL(setfacl)没有setgid的设置来强制执行在目录中创建的新文件和子目录以继承其组ID。因此,您必须通过chmod单独设置setgid。 Git的 - 共享选项(git-scm.com/docs/git-init但是,允许您setgid并覆盖用户的umask。 - Chase T.


如果您创建了存储库(或克隆了现有存储库中的新裸存储库)

$ git init --shared=group 

要么

$ git init --shared=0NNN

Git应该处理超出默认umask提供的权限。最后,我的Git版本(1.6.3)也是如此。当然,这假设您的用户属于同一组。

如果我需要管理具有不同读/写程度的多个组中的用户,我会选择gitosis。我也听说过提及gitolite(http://github.com/sitaramc/gitolite),一个被提供分支级别权限的gitosis fork,但不能说我已经亲自使用它了。


113
2018-02-17 05:40



这绝对是正确的答案。 - ELLIOTTCABLE
我有这个问题,这是迄今为止最好的答案。唯一的问题是 --shared 参数采用八进制,而不是十六进制。我已经在Git 1.7.8的源代码中证实了这一点,第二个例子应该是 git init --shared=0NNN。 - qpingu
什么是 NNN - 许可掩码或组号或其他? - Craig McQueen
顺便说一句,上面的“群组”是关键字,而不是群组名称的占位符。您可以使用chgrp命令分配组。对于一个新的回购它是 git init --bare --shared=group myproj myproj是你的回购名称,其次是 chgrp -R mygroup myproj mygroup是你的组名。 - labradort
请注意,如果您的用户在默认组不同于应用程序时进行提交,则可能会搞砸。要解决此问题,您需要每个用户将repo中拥有的每个文件chgrp到正确的组。除非您在提交和推送之前弄清楚如何让每个人在/在正确的组下创建/切换新文件,否则这将再次发生。 - ragerdl


这没有说,所以我想快速添加它。

要确保权限问题不会出现问题,请确保在git共享存储库的配置文件中设置以下内容:

[core]
    sharedRepository = true

这将确保您的系统的“umask”设置得到尊重。


50
2018-03-09 05:52



根据git-config(1)(kernel.org/pub/software/scm/git/docs/git-config.html)core.sharedRepository,你需要将其设置为“umask”或“false”以让git尊重用户的umask。 - David Schmitt
这和user35117的答案是正确的。请注意,“true”与“group”相同,可以使用该命令进行设置 git config core.sharedRepository true。 - ColinM
当它被推送到远程时,它是否仍会改变文件的所有权? - Duc Tran
如果你想在克隆时而不是在事实之后设置它,相当于 git init --shared是 git clone --config core.sharedRepository=true。奇怪的git使用 --shared 对于这种类似命令中的这种不同含义。 - stevek_mcc


Git用户手册 描述如何 共享存储库 在几个方面。

更复杂,但共享存储库的功能完整方法是:

我们将GitHub用于由6名开发人员组成的团队。


21
2018-06-17 07:35



我喜欢Gitosis。这是一种基于公钥控制访问的非常有效的方法。 - Mike Mazur
这些解决方案中的任何一个如何解决“我想让多个人拉到那个存储库”的问题? - womble♦
看看gitosis。那一个解决了你的问题。 - pilif
当您共享存储库时,人们将能够从中获取存储库。他们可能需要克隆它,或添加一个远程分支。我链接的文档将非常清楚地指导您解决问题;我已经使用了所有描述的方法来帮助开发人员与Git协作源代码。据我所知,ServerFault不是为了手持。 - jtimberman
我不得不同意使用Gitosis。它通过使用由多个SSH密钥验证的单个帐户来解决权限问题。它也是通过git提交完全自己管理的。 - Jeremy Bouse


另外看看 gitolite 用于托管您的git存储库。 Gitosis显然还没有被开发出来。


9
2018-01-19 08:55





修复共享存储库中的权限的一种方法是,用户在推送时不会遇到权限问题,就是创建一个更新后的钩子脚本来实现这一点。这应该适用于任何git版本。

假设您在/myrepo.git中有一个共享存储库。该存储库中的所有文件都属于say mysharedgroup。推送到该存储库的所有用户都应该属于 mysharedgroup 也。现在创建以下文件(更改 mysharedgroup 根据您的喜好):

/myrepo.git/hooks/post-update

#!/bin/sh
chmod -R g+w . 2>/dev/null
chgrp -R mysharedgroup . 2>/dev/null

4
2017-09-27 14:35



用户具有不同默认组的正确答案 - Pat
在目录上设置setgid位将导致用户创建的文件继承与目录相同的组所有权(如果用户属于该组)。即使它不是用户的默认组。然后不需要这个钩子。这就是@womble的答案(以及我对它的评论)的作用。 - rescdsk
在我的centos7机器上,在尝试了本页列出的每个解决方案之后,上面的@ bkmks解决方案的变体是实际工作的唯一选项(设置合并后和结账后挂钩而不是上面的更新后)。 - Mike Godin


从各种其他答案和关于设置新回购的评论中汇总好的建议的点点滴滴:

如果你正在建立一个全新的回购 myrepo 在 /srv/git 对于小组 mygroup,这就是你想要的:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. 第一行创建repo目录
  2. 第二行将其组设置为 mygroup
  3. 第三行使用以下配置初始化一个裸仓库:
    1. core.bare = true:让它成为一个简单的回购
    2. core.sharedrepository = 1 (与...一样 core.sharedrepository = group):repo目录和后来在其中创建的所有目录将由git管理以允许 mygroup 读取,写入和执行权限(也设置了sgid位 - 以便与用户合作 mygroup 不是他们的主要群体)
    3. receive.denyNonFastforwards = 1:拒绝非快进推送回购

如果要微调用户,组或其他用户的权限,请使用 --shared=0NNN,哪里 NNN 是标准用户,组和其他位  (执行和sgid位 目录 将由git妥善管理)。例如,这允许对用户进行读写访问,以及对组的只读访问(并且不能访问其他组):

git init --bare --shared=0640 /srv/git/myrepo.git

这允许对用户和组进行读写访问(并且不能访问其他用户):

git init --bare --shared=0660 /srv/git/myrepo.git

这允许对用户和组的读写访问,以及对其他的只读访问:

git init --bare --shared=0664 /srv/git/myrepo.git

请注意,如果您不允许对该组进行写访问,请务必先使用 chown 设置repo的所有者,然后运行 git init 命令作为该用户(以确保使用所有初始文件和子目录的正确所有者初始化repo)。


3
2018-05-26 01:24



比更高的投票反应更正确。 - XO01


您可以使用git-daemon来共享存储库。阅读文档 git的守护欲获得更多信息。

编辑:

另请查看这篇文章 共享git存储库的8种方法


2
2018-06-17 02:58





对我来说,这对现有的存储库来说正是这样做的。这可以从以下几个答案和评论中获得建议:

从您的存储库父目录,在服务器上:

chgrp -R <whatever group> gitrepo
chmod -R g+wX gitrepo
cd gitrepo
find . -type d -exec chmod g+s {} +
git config core.sharedRepository group

1
2017-12-13 12:44