单体仓库中目录的细粒度访问控制

18

我一直在阅读关于单一代码库的优点,但是还没有找到解决共享代码库部分问题的方法:

假设一个组织对于客户端/服务器Web应用程序有一个单一代码库。他们雇用了一位承包商来设计客户端的某个部分。他们如何只给承包商访问相关客户端代码?即使稀疏检出也不是微不足道的。


3
这是一个问题,没有好的解决方案。你所提供的相关问题中的子树分割方法可能是目前最好的方法,但如果没有明确定义的子树,它就毫无用处。 - torek
1
https://medium.com/@mattklein123/monorepos-please-dont-e9a279be011b - Alexan
3个回答

21

考虑使用git subtree

使用git subtree,您可以:

  • 创建由子树组成的单体库,每个子树可以链接到单独的远程仓库。

    在您的示例用例中,承包商只能访问与单体库的单个子树相关联的远程存储库。

  • 具有单一聚合/统一历史记录(单体库的关键)

  • 将来自子树远程的更改拉入单体库

  • 将在单体库的任何子树中进行的更改推送到其单独的远程位置

  • 保持简单易用的工作流。

    git subtree不需要您的版本库用户学习任何新知识。他们可以忽视您正在使用git subtree管理依赖项的事实。

有关优点和缺点的列表,请参见Atlassian的Git subtree: the alternative to Git submodule。尽管我认为本文中的示例步骤相当有限,如果没有过时。

有关具有git log每个步骤的详细演示的逐步说明:

  • 将多个存储库合并为单个管理库并保留历史记录,使用git subtree的示例和步骤比Atlassian文章更清晰和更合乎逻辑。

  • Git subtrees: a tutorial还提供了逐步操作和结果,并对在管理库中进行更改并推送到子树存储库以及反之亦然的一些好建议。它确实提到了一个警告,即包含子树拉取的重新定义不起作用。另一篇文章解释说:

    不要试图重新定义这个。按原样推送。如果您重新定义,当您进行下一个子树拉取时,git subtree将无法协调提交。

    如果一定要重新定义,则我链接下面的Atlassian文章提供了解决方法。

  • 我通常不喜欢观看视频,但介绍Git Subtrees 看起来值得一看,有很多细节。此外,它比所有其他文章都要新(2019年)。预先了解将要处理的内容是令人欣慰的。

如果您想深入了解::

  • 这个优秀的StackOverflow回答解释了git subtree和git的subtree merge strategy(git merge -s subtree)之间的区别。实质上,前者在幕后使用了后者。换句话说,这是git对于porcelainplumbing的概念。
  • GitHub有关Git子树合并的文章使用了合并策略,如果你更喜欢这种方法。
  • Atlassian文章的跟进更深入地探究了“Git子树”的内部机制。
  • 精通Git子树也不错,提到了一些你可能认可或不认可的细节,并且包含了所有链接中最详细的逐步操作和结果。
  • 关于git subtree的历史以及它的内部工作方式,以及为什么子树比子模块更好,请参见Git: Submodules vs. Subtrees
  • Monorepo-operator是一种工具,可能会使得管理基于子树的单体库更加容易。我没有使用过它,也无法保证其质量,但也许值得了解一下。


有趣!那么在我的情况下,我会有一个包含网页应用程序的子树,然后将其拉入包含后端和其他程序的较大仓库中?为什么Atlassian链接说"不混合超级项目和子项目代码的责任在于您"是一个缺点呢?实际上,我希望混合代码,例如当后端中的API更改需要反映在Web应用程序中时。这就是拥有一个monorepo的原因。 - Dan Dascalescu
@DanDascalescu 是的。 我已经更新了我的答案,并增加了更多文章(我可能最终不得不自己使用它,但现在还没有,但值得我花时间去理解)。 我不确定Atlassian为什么这样说。 如我提供的逐步说明所示,您确实可以跨子树边界提交更改。 其中一个解释了当您推送到子树的远程时如何智能地过滤到子树目录的这些更改。 我猜他们是说很容易引入不想要的依赖关系? - Inigo

3
他们如何只给承包商访问相关客户端代码的权限?
他们不会这样做。全面的单体库涉及机密问题,因此无法缓解。
而且Git本身没有授权(或认证)。
也就是说,任何原生Git功能(子模块或子树)本身都不足以解决这个问题。
通常会看到一个中间门户存储库,由相关部分组成,供承包商使用,并具有同步过程进行导入/导出工作。
如果该承包商是远程工作,则该提取将托管在单独的服务器上,该服务器本身在DMZ中进行管理,并复制到互联网上的外部服务器,通过VPN进行访问。

2
“中间门存储库”与承包商只能访问子树的隔离远程之间有什么区别?向/从子树远程推/拉可以像您提到的“同步过程”一样使用相同的权限和审查进行管理。” - Inigo
@Inigo 根据我的经验,在任何安全审计中,这种做法都是不可行的:你需要在一个完全分离的不同 DMZ 中,仅包含你想要共享的代码。事实上,代码被作为子树引用到你自己的代码库中,只是你方面的实现细节。 - VonC
1
是的,使用单一代码库和子树可以实现完全分离。 “代码在您自己的代码库中作为子树引用的事实是您方面的实现细节。” 是的,这种实现细节可以实现目标。鉴于此,您的绝对答案,特别是“他们不会”和接下来的句子,是错误的。 - Inigo

0

我不确定关于单体仓库,我知道这违反了单体仓库的问题,但我想到的一种方法是:(如果可能的话)结构化项目以支持模块,并使用git子模块 https://git-scm.com/book/en/v2/Git-Tools-Submodules

通过git提供商的访问控制(例如Gitlab、Bitbucket等),您只能将特定的git子模块访问权限赋予承包商,无论是读/写或管理员访问权限。

例如,在您的情况下,您可以将设计层(用于与客户共享的层)放在另一个仓库中,并将其作为主要仓库的子模块。如果您想要更严格的安全性,如@VonC所提到的,您可以为子模块设置VPN访问仓库。它可能需要一些时间来设置,但我认为一旦正确实施,考虑风险后它可能是值得的。


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