Fab*_*bio 5 git git-merge branching-and-merging git-subtree
我正在开始一个新的Zend Framework项目,我将与设计师合作.我将使用git维护这个项目代码,通常设计师不会说git(或任何编程语言),所以我想让他的事情变得简单,否则我恐怕他根本不会使用git.我的计划是给他一些Git gui,并且他应该只使用基本的git功能,例如commit,diff,fetch,merge,push和pull.
我正在使用gitolite来维护我们的git存储库的共享副本,因为它有一个精细的权限系统,我将只为设计者提供RW访问权限(设计)和对其他分支的读访问权限.
为了简单起见,我想与他分享主项目中的一些文件夹(遵循ZF推荐的结构),他确实需要访问它才能完成工作.与此同时,我希望我们两个人仍然能够相互融合.
他的分支的结构减少应该是这样的:
<project name>/
application/
layouts/
scripts/
views/
scripts/
public/
css/
images/
js/
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用子模块完成这项任务,但维护起来会很麻烦,因为我应该将项目拆分到(至少)4子库中,他应该只能访问子库,并且他有3个存储库可以使用.因此,如果这是唯一的解决方案,我会放弃这个想法.
我已经读过的一些链接让我觉得我所要求的是可能的:
这是我的问题:
design(git checkout -b design和git mv/rm?)git merge design从主分支,反之亦然)我找到了另外两种可能解决这两个问题的方法
我尝试git rm all-unneeded-stuff在设计分支中实现第一个后,我在主分支中进行提交,其中涉及白名单路径中的文件和黑名单路径中的另一个文件,但是git merge失败并显示以下消息
CONFLICT (delete/modify): application/Bootstrap.php deleted in HEAD and modified in master. Version master of application/Bootstrap.php left in tree.
Run Code Online (Sandbox Code Playgroud)
然后我在master分支中添加了一个新目录,当从设计中合并时,添加了新目录.我在驱动程序中添加了一些调试回声,我发现在两种情况下都没有调用它,可能是因为它不是真正的合并.
我还没有尝试过第二种方法(.gitignore),但是如果我已经理解这种方法不符合我的需求,因为它只会忽略设计分支中列入黑名单的文件,但是它们会在设计分公司,打破了我的要求.
我把我的实验推到了GitHub上
我认为目前没有解决方案.使用当前的git实现,这根本无法实现.
我想要反驳,但我担心它不会发生.
听起来您希望能够在每个目录的基础上限制读取访问权限.这是可能的,但我所知道的唯一解决方案远非简单.它涉及服务器上同一存储库的多个版本,每个版本使用一些复杂的钩子魔术保持同步以过滤掉子目录.
我正在努力在我的业余时间实现钩子,最终的目标是将它们作为开源软件发布(可能作为gitolite的一个特性添加),但不幸的是我的业余时间有限.
一般解决方案涉及同一存储库的至少三个变体:一个权威存储库,用于协调两个或多个委托存储库.用户永远不会克隆权限存储库; 只克隆代理存储库.
代理负责将传入的提交转发到权限存储库.权限存储库负责为每个其他委托存储库适当地过滤传入的提交.然后将结果推送给其他代表.
权限存储库不是严格要求的 - 委托可以自己执行过滤,然后将结果直接推送到其他委托 - 但使用另一个存储库作为集中协调器可以大大简化实现.
每个委托存储库包含整个项目数据的子集(例如,过滤掉零个或多个子目录).除了每个委托都有一组不同的文件被过滤掉之外,所有委托存储库都是相同的.它们都具有相同的提交历史图,但提交将具有不同的文件内容,因此具有不同的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
Run Code Online (Sandbox Code Playgroud)
请注意,这两个图看起来相同,具有相同的提交消息,相同的分支名称等.唯一的区别是SHA1 ID,因为文件内容不同.
(旁注:也可以过滤掉提交,以防止另一个委托的用户甚至知道已经过滤掉的目录中的提交.但是,如果提交只接触过滤的文件,则只能过滤掉 - out directory.否则,钩子会无法自动解决合并冲突.)
权威存储库是所有委托权限的超集.每个委托存储库中的所有提交对象都会通过每个委托存储库中的挂钩自动推送到权限存储库中.因此,如果有两个委托存储库,则在权限存储库中将有两个同构DAG(每个委托一个)(假设委托不共享公共根提交).
权限存储库还将具有每个委托的每个项目分支的版本,前缀为委托的名称.继续上面的示例,everything.git委托存储库有一个master指向commit 的分支2faaad9,而委托no-foo.git有一个master分支指向过滤但等效的提交81c2189.在这种情况下,authority.git将有两个主分支: everything/master指向2faaad9和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
Run Code Online (Sandbox Code Playgroud)
请注意,每个提交有两个版本,每个代表一个.还要注意分支名称.
每个委托将提交提交到权限存储库.
当用户更新git push委托存储库中的引用(via )时,该存储库的update钩子会自动git push进入权限存储库.但是,它不使用标准的push refspec,而是使用refspec,它使权限的存储库中的引用以委托存储库的名称为前缀(例如,如果委托存储库被命名,foo.git那么它将使用push refspecs +refs/heads/master:refs/heads/foo/master和+refs/tags/v1.0:refs/tags/foo/v1.0).
权限存储库过滤传入的提交并将其推送到其他委托存储库.
当委托存储库推入权限存储库时,权限的update钩子:
必须注意避免委托存储库之间的竞争条件并正确处理错误.
在您的示例中,您将拥有两个代理存储库,如下所示:
everything.git (为了你)zend-project.git (适合您的设计师)分支authority.git将以两个委托存储库为前缀everything并zend-project对应.
当你进入master时everything.git,会发生以下情况:
update钩everything.git将推动进入提交到everything/master分支authority.git.update钩子authority.git将:
application和public子目录之外的所有内容.zend-project/master以指向新提交.zend-project/master在authority.git对master中zend-project.git.当您的设计师推进master时zend-project.git,会发生以下情况:
update钩zend-project.git将推动进入提交到zend-project/master分支authority.git.update钩子authority.git将:
application或public子目录.如果是这样,请返回错误消息.everything/master移植的其他子目录.everything/master以指向新提交.everything/master在authority.git对master中everything.git.以上描述了实现每目录读访问控制的方法.如果您确实不希望某些用户能够访问存储库的某些部分,那么它应该是合适的.在您的情况下,为您的设计师提供便利可能比限制访问更重要.如果是这样,可能有一种更简单的方法来完成你想要的.
我希望我能够清楚地解释清楚这一点.
| 归档时间: |
|
| 查看次数: |
1902 次 |
| 最近记录: |