听起来您希望能够限制每个目录的读取访问权限。这是可能的,但我所知道的唯一解决方案远非简单。它涉及服务器上同一存储库的多个版本,每个版本都使用一些复杂的钩子魔术来过滤子目录来保持同步。
我正在利用业余时间致力于实现这些钩子,最终目标是将它们作为开源软件发布(可能作为 gitolite 的一个功能补充),但不幸的是我的业余时间有限。
存储库
一般解决方案至少涉及同一存储库的三个变体: 一个权威协调两个或多个的存储库delegate存储库。用户绝不会克隆权限库;仅克隆委托存储库。
代表负责将传入的提交转发到权限存储库。权限存储库负责为每个其他委托存储库适当地过滤传入的提交。然后将结果推送给其他代表。
权限存储库并不是严格必需的 - 代表可以自己执行过滤,然后将结果直接推送给其他代表 - 但使用另一个存储库作为集中协调器可以大大简化实施。
委托存储库
每个委托存储库包含整个项目数据的子集(例如,过滤掉零个或多个子目录)。所有委托存储库彼此相同,只是每个委托过滤掉了一组不同的文件。它们都具有相同的提交历史记录图,但提交将具有不同的文件内容,因此具有不同的 SHA1 标识符。它们具有相同的分支和标签集(换句话说,如果项目有master
分支,那么每个委托存储库也有一个master
分支),但由于等效提交的 SHA1 标识符不同,因此引用将指向不同的 SHA1 标识符。
例如,以下是两个委托存储库的内容的图表。这everything.git
存储库没有过滤掉任何内容,但是no-foo.git
存储库包含子目录中的所有内容foo
过滤掉了。
$ cd ~git/repositories/everything.git
$ git log --graph --oneline --decorate --date-order --all
* 2faaad9 (HEAD, master) barbaz
| * c3eb6a9 (release) foobar
* | 8b56913 Merge branch 'release'
|\ \
| |/
| * b8f899c qux
* | aad30f1 baz
|/
* f4acd9f put a new file in subdirectory bar
* 2a15586 put a new file in subdirectory foo
$ cd ~git/repositories/no-foo.git
$ git log --graph --oneline --decorate --date-order --all
* 81c2189 (HEAD, master) barbaz
| * 6bbd85f (release) foobar
* | c579c4b Merge branch 'release'
|\ \
| |/
| * 42c45c7 qux
* | 90ecdc7 baz
|/
* 4d1cd8d put a new file in subdirectory bar
* 9cc719d put a new file in subdirectory foo
请注意,这两个图看起来相同,具有相同的提交消息、相同的分支名称等。唯一的区别是 SHA1 ID,因为文件内容不同。
(旁注:提交也可以被过滤掉,以防止另一个委托的用户知道在过滤出的目录中进行了提交。但是,只有当提交只涉及过滤目录中的文件时,才可以将其过滤掉。 out 目录。否则会出现合并冲突,无法通过钩子自动解决。)
权威库
权限存储库是所有委托权限的超集。每个委托存储库中的所有提交对象都会通过每个委托存储库中的挂钩自动推送到权限存储库中。因此,如果有两个委托存储库,则权限存储库中将有两个同构 DAG(每个委托一个)(假设委托不共享公共根提交)。
权限存储库还将具有每个委托的每个项目分支的版本,以委托名称为前缀。继续上面的例子,everything.git
委托存储库有一个master
指向提交的分支2faaad9
,同时委托no-foo.git
has a master
指向已过滤但在其他方面等效的提交的分支81c2189
。在这种情况下,authority.git
将有两个主分支:everything/master
指向2faaad9
and no-foo/master
指向81c2189
。下图说明了这一点。
$ cd ~git/repositories/authority.git
$ git log --graph --oneline --decorate --date-order --all
* 2faaad9 (everything/master) barbaz
| * 81c2189 (no-foo/master) barbaz
| | * c3eb6a9 (everything/release) foobar
| | | * 6bbd85f (no-foo/release) foobar
* | | | 8b56913 Merge branch 'release'
|\ \ \ \
| | |/ /
| |/| |
| | * | c579c4b Merge branch 'release'
| | |\ \
| | | |/
| * | | b8f899c qux
| | | * 42c45c7 qux
* | | | aad30f1 baz
|/ / /
| * | 90ecdc7 baz
| |/
* | f4acd9f put a new file in subdirectory bar
| * 4d1cd8d put a new file in subdirectory bar
* | 2a15586 put a new file in subdirectory foo
/
* 9cc719d put a new file in subdirectory foo
请注意,每个提交都有两个版本,每个委托都有一个版本。另请注意分支名称。
Hooks
委托存储库
每个代表都会将提交提交到权限存储库。
当用户更新参考时(通过git push
)在委托存储库中,该存储库的update
钩子自动执行git push
进入权限存储库。但是,它不是使用标准推送引用规范,而是使用一个引用规范,该引用规范会导致授权存储库中的引用以委托存储库的名称为前缀(例如,如果委托存储库名为foo.git
然后它将使用推送参考规范,例如+refs/heads/master:refs/heads/foo/master
and +refs/tags/v1.0:refs/tags/foo/v1.0
).
权威库
权限存储库过滤传入的提交并将其推送到其他委托存储库中。
当委托存储库推送到权限存储库时,权限的update
hook:
- 检查用户是否尝试在过滤掉的目录之一中创建文件。如果是这样,它将退出并出现错误(否则可能存在无法自动解决的合并冲突)。
- 移植回最初过滤掉的子目录,形成一棵没有过滤掉任何内容的树。
- 对于每个其他委托,过滤未过滤的树以进行等效提交并删除适当的内容。
- 将等效提交推送到委托存储库。
必须注意避免委托存储库之间的竞争条件并正确处理错误。
您的案例
在您的示例中,您将有两个像这样的委托存储库:
-
everything.git
(为你)
-
zend-project.git
(给你的设计师)
分行位于authority.git
将前缀为everything
and zend-project
对应于两个委托存储库。
当你推到master
in everything.git
,会发生以下情况:
- The
update
挂钩everything.git
会将传入的提交推送到everything/master
分支进入authority.git
.
- For each incoming commit, the
update
hook in authority.git
would:
- 创建一个与提交树 100% 相同的新树对象,但删除该树之外的所有内容
application
and public
子目录。
- 使用新树和等效父级创建新的提交对象,但重用原始提交消息、作者和时间戳。
- Update
zend-project/master
指向新的提交。
- Push
zend-project/master
in authority.git
to master
in zend-project.git
.
当你的设计师推动master
in zend-project.git
,会发生以下情况:
- The
update
挂钩zend-project.git
会将传入的提交推送到zend-project/master
分支进入authority.git
.
- For each incoming commit, the
update
hook in authority.git
would:
- 检查是否有任何新文件在外部创建
application
or public
子目录。如果是这样,则返回一条错误消息。
- 创建一个与提交树 100% 相同的新树对象,除了其他子目录之外
everything/master
嫁接于.
- 使用新树和等效父级创建新的提交对象,但重用原始提交消息、作者和时间戳。
- Update
everything/master
指向新的提交。
- Push
everything/master
in authority.git
to master
in everything.git
.
Notes
以上描述了一种实现按目录读访问控制的方式。如果您确实不希望某些用户能够访问存储库的某些部分,那么它应该是合适的。就您而言,设计人员的便利可能比限制访问更重要。如果是这样,可能有一种更简单的方法来完成您想要的事情。
我希望我能够足够清楚地解释这一点。