Git 子树合并策略或子树命令?

2024-03-23

我正在启动一个新的 Zend Framework 项目,我将在其中与设计师合作。我将使用 git 维护这个项目代码,通常设计师不会说 git (或任何编程语言),所以我想让他变得简单,否则我担心他根本不会使用 git。我的计划是给他一些 Git gui,这样他就应该只使用基本的 git 功能,例如提交、差异、获取、合并、推送和拉取。

我使用 gitolite 来维护 git 存储库的共享副本,并且由于它具有细粒度的权限系统,因此我将仅向设计者授予专用分支(设计)的 RW 访问权限和对其他分支的读取访问权限。

为了简单起见,我只想与他分享主项目中的一些文件夹(如下ZF推荐结构 http://framework.zend.com/manual/en/project-structure.project.html),他确实需要访问权限来完成其工作。同时我希望我们双方仍然能够融合在一起。

他的分支的简化结构应该是这样的:

<project name>/
    application/
        layouts/
            scripts/
        views/
            scripts/
    public/
        css/
        images/
        js/

我知道我可以使用子模块来完成这个任务,但是维护起来会很痛苦,因为我应该将我的项目分成(至少)4个子存储库,他应该只能访问子存储库,并且他有3个存储库可以使用。因此,如果这是唯一的解决方案,我会放弃这个想法。

我已经阅读过的一些链接让我认为我所要求的是可能的:

  • git 子树命令 https://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt
  • git 子树合并策略 https://stackoverflow.com/questions/1551473/git-subtree-why-cant-i-branch-from-a-subtree-rather-than-the-root/1551525#1551525

这是我的问题:

  1. 如何创建缩减分支design (git checkout -b design and git mv/rm?)
  2. 如何配置 git 来跟踪跨分支的编辑(这样我就可以git merge design来自主分支,反之亦然)

Update:

我发现了解决这两个问题的另一种可能的方法

  • 如何告诉 git 始终选择本地版本来进行特定文件上的冲突合并? https://stackoverflow.com/questions/928646/how-do-i-tell-git-to-always-select-my-local-version-for-conflicted-merges-on-a-sp
  • 如何设置 git 驱动程序以忽略合并时的文件夹 https://stackoverflow.com/questions/3111515/how-to-setup-a-git-driver-to-ignore-a-folder-on-merge

我尝试执行第一个之后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.

然后我在主分支中添加了一个新目录,并且在从设计合并时添加了新目录。我在驱动程序中添加了一些调试回显,我发现在这两种情况下都没有调用它,可能是因为它不是真正的合并。

我还没有尝试过第二种方法(.gitignore 方法),但如果我理解该方法不符合我的需求,因为它只会忽略设计分支中列入黑名单的文件,但它们将在设计分支,打破了我的要求。

我继续我的实验GitHub https://github.com/fabn/fake-project

更新2:

我认为目前还没有解决方案。对于当前的 git 实现,这是根本无法实现的。

我很想被反驳,但我担心这不会发生。


听起来您希望能够限制每个目录的读取访问权限。这是可能的,但我所知道的唯一解决方案远非简单。它涉及服务器上同一存储库的多个版本,每个版本都使用一些复杂的钩子魔术来过滤子目录来保持同步。

我正在利用业余时间致力于实现这些钩子,最终目标是将它们作为开源软件发布(可能作为 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:

  1. 检查用户是否尝试在过滤掉的目录之一中创建文件。如果是这样,它将退出并出现错误(否则可能存在无法自动解决的合并冲突)。
  2. 移植回最初过滤掉的子目录,形成一棵没有过滤掉任何内容的树。
  3. 对于每个其他委托,过滤未过滤的树以进行等效提交并删除适当的内容。
  4. 将等效提交推送到委托存储库。

必须注意避免委托存储库之间的竞争条件并正确处理错误。

您的案例

在您的示例中,您将有两个像这样的委托存储库:

  • everything.git(为你)
  • zend-project.git(给你的设计师)

分行位于authority.git将前缀为everything and zend-project对应于两个委托存储库。

当你推到master in everything.git,会发生以下情况:

  1. The update挂钩everything.git会将传入的提交推送到everything/master分支进入authority.git.
  2. For each incoming commit, the update hook in authority.git would:
    1. 创建一个与提交树 100% 相同的新树对象,但删除该树之外的所有内容application and public子目录。
    2. 使用新树和等效父级创建新的提交对象,但重用原始提交消息、作者和时间戳。
    3. Update zend-project/master指向新的提交。
  3. Push zend-project/master in authority.git to master in zend-project.git.

当你的设计师推动master in zend-project.git,会发生以下情况:

  1. The update挂钩zend-project.git会将传入的提交推送到zend-project/master分支进入authority.git.
  2. For each incoming commit, the update hook in authority.git would:
    1. 检查是否有任何新文件在外部创建application or public子目录。如果是这样,则返回一条错误消息。
    2. 创建一个与提交树 100% 相同的新树对象,除了其他子目录之外everything/master嫁接于.
    3. 使用新树和等效父级创建新的提交对象,但重用原始提交消息、作者和时间戳。
    4. Update everything/master指向新的提交。
  3. Push everything/master in authority.git to master in everything.git.

Notes

以上描述了一种实现按目录读访问控制的方式。如果您确实不希望某些用户能够访问存储库的某些部分,那么它应该是合适的。就您而言,设计人员的便利可能比限制访问更重要。如果是这样,可能有一种更简单的方法来完成您想要的事情。

我希望我能够足够清楚地解释这一点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Git 子树合并策略或子树命令? 的相关文章

  • GitHub API:标记提交所属(与 git describe --tag 并行)

    我正在使用 GitHub API 进行实验octokit https github com octokit octokit rb红宝石 我的目标是能够提取提交 SHA 所属的 标签 现在我可以使用命令行轻松地执行此操作 gt git des
  • 有没有办法缓存 https 凭据以推送提交?

    我最近转而将我的存储库同步到 GitHub 上的 https 由于防火墙问题 并且每次都要求输入密码 有没有办法缓存凭据 而不是每次都进行身份验证git push 自 Git 1 7 9 2012 年发布 以来 Git 中有一个巧妙的机制可
  • 在 git repo 中查找超过 x MB 且 HEAD 中不存在的文件

    我有一个 Git 存储库 用于存储随机的内容 主要是随机脚本 文本文件 我设计的网站等 随着时间的推移 我删除了一些大型二进制文件 通常为 1 5MB 这些文件会增加存储库的大小 而我在修订历史记录中不需要这些文件 基本上我希望能够做到 m
  • 如何使用 .gitattributes 避免在 git root 中包含文件夹,但在 zip 的 dist 文件夹中包含同名文件夹

    我有一个名为lib在存储库的根目录和另一个名为lib在 dist 文件夹中 我正在尝试使用 gitattributes文件排除除 dist 之外的所有文件夹和文件 以便任何下载为 zip 或 tarball 的人都只会 git 分发文件 我
  • git 可以与 Xcode 集成吗?

    有没有办法将 git 存储库与 Xcode 内置的 SCM 功能一起使用 Xcode 4 原生支持 git WWDC 2010 上的开发者工具国情咨文演讲 在这里了解更多 Xcode 4 中的新增功能 http developer appl
  • refname 不明确且拉取失败

    我运行了以下命令 因为我想将生产分支移回而不必先签出 git branch f production HEAD 1 现在 当我检查生产时 我收到以下警告 warning refname production is ambiguous 然后我
  • 分支明显不同,但提交历史是相同的

    git status告诉我我的分支和我在另一个存储库上开始的分支已经分歧 On branch master Your branch and origin master have diverged and have 13 and 13 dif
  • 代表 Git 存储库的数学结构是什么

    我正在学习 Git 如果我能描述一下代表 Git 存储库的数学结构 那就太好了 例如 它是一个有向无环图 它的节点代表提交 它的节点有代表分支等的标签 每个节点最多一个标签 没有标签使用两次 我知道这个描述不正确 我只是想解释我正在寻找的内
  • 如何从 android.googlesource.com 或 github.com 下载单个目录?

    我想下载 https android googlesource com platform frameworks base git master tools aapt https android googlesource com platfo
  • 如何 git grep 仅一组文件扩展名

    如何执行 git grep 并将检查的文件限制为一组文件 我希望能够 grep cpp 和 h 文件的内容来查找 MyFunc 例如 git grep MyFunc hc 但是 这也匹配 c 文件和 cs 文件 Use git grep M
  • `git ls-files -s` 输出中不同字段的含义是什么?

    在 Git 中 命令返回的典型结果行git ls files s好像 100755 be2c2e9b0966253096472d4b482c458bc892e493 0 gitignore 这些字段是什么意思 不用再犹豫了git ls fi
  • git 显示已添加到 gitignore 的文件中的更改?

    我已经将 log2 文件夹和 main js 文件添加到 gitignore 如屏幕截图所示 但即使执行后git rm cached r我仍然可以看到 git 正在检测 main js 和 log2 文件夹内文件的更改 怎么会 这些的常见问
  • Git:发送电子邮件而不提交

    我有一个项目 我做了更改 并想使用 git send email 功能将它们发送给另一个用户 我发现它可以通过发送补丁来工作 由git format patch每次提交 是否可以只发送diff的 我不想先提交 然后发送补丁 是否有gitfo
  • 如何合并两个连续的 git 存储库

    我有一个相当独特的情况 我有一个名为 Project1 的存储库 我在其中工作了一些时间 几个月 一年后 我创建了存储库 Project1 Again 从 Project1 停止的地方开始 现在 我希望修订历史记录是连续的 因此我希望它们合
  • 无法从 Sourcetree 拉取 Git 远程存储库

    我生成了 ssh 密钥并配置了我的 git 和 SourceTree 我可以 git pull 并从 Git bash 执行其他操作 注意 我在 bashrc 中添加了以下内容以使其正常工作 eval ssh agent ssh add 然
  • 使用终端时 Git 推送在总计后卡住了?

    我尝试将一些文件推送到Github 总大小只有22 2M 我不知道为什么它在总行之后卡住了 我读过推送到 Github 时 Git 推送挂起 https stackoverflow com questions 16906161 git pu
  • git 日志历史记录图,每次提交一行,彩色,带有日期

    我需要的格式如下 git log decorate graph oneline date order 但我也需要它 包含日期 短 具有相同的颜色 I tried git log decorate graph oneline date ord
  • 如何在 macOS 上将 Git 升级到最新版本?

    我刚刚购买了一台装有 OS X Lion 的新 Mac 我在终端中检查了默认安装的 git 版本 我得到了答案 git version gt git version 1 7 5 4 我想将 git 升级到最新版本 1 7 8 3 因此我下载
  • GIT:以下未跟踪的工作树文件将被签出覆盖

    我有两个分支 一个称为 master 另一个称为 dev 我目前位于 master 分支 我想转到 dev 分支将文件移动到开发服务器 但是当我执行 git checkout dev 我收到消息 以下未跟踪的工作树文件将被覆盖 查看 pag
  • git 提交错误:检测到大文件

    您好 我正在为 ios 8 1 开发一个应用程序 xcode 我已经使用 googleMaps 框架来实现自动完成功能 当我尝试在 Git 中推送我的项目时 我收到大文件检测错误 后来尝试使用 git lfs 并跟踪 git 检测到的文件

随机推荐

  • 奇数或偶数反斜杠和转义字符

    我对下面的代码有一点问题 import re pattern re compile r for text in r ok py r ok py r ok py r ok py r ok py search re search pattern
  • ReactJs“不变违规...”经典反应问题

    这是一个典型的反应问题 但我有点不知道如何处理它 我只想动态渲染我的表格线 但我收到错误 未捕获错误 不变违规 processUpdates 无法找到元素的子元素 2 这可能意味着 DOM 意外变异 例如 通过浏览器 通常是由于在使用表 嵌
  • 如何以简单的方式将 CGPoint 对象添加到 NSArray 中?

    我有大约 50 个 CGPoint 对象 它们描述了类似 路径 的东西 我想将它们添加到 NSArray 中 这将是一个只返回给定索引对应的 CGPoint 的方法 我不想创建 50 个变量 例如 p1 p2 依此类推 有没有一种简单的方法
  • 在 Windows Phone 8 中存储配置值/设置的最佳方法

    由于 WP8 应用程序中没有默认配置文件 因此存储配置值的最佳方式是什么 例如WCF 服务 URL 用户名和密码 我希望当手机重新启动且应用程序关闭时这些值可用且可更新 提前致谢 你应该使用IsolatedStorageSettings A
  • 如何在 Swift 中的自定义类中初始化 Timer? [复制]

    这个问题在这里已经有答案了 我制作了一个简单的计时器应用程序 但是 现在我想让它变得更好 并且我想为计时器控件编写一个类 class Cronometer private var counter Int 0 private var time
  • https://graph.microsoft.com/v1.0/places/microsoft.graph.room Api 未提供更新的数据

    我正在使用 Microsoft Graph 获取可供租户使用的房间列表 根据文档 列出 Palace Api 应该用于此目的 现在 我在使用 List Places api 获取更新数据时遇到问题 我已向租户添加了一些房间 但这些房间并未反
  • 使用 LINQ 时谓词的顺序重要吗?

    我知道以不同的顺序执行操作会产生不同的性能 例如以下慢速查询之间的差异 List
  • 无法在电子js中加载反应

    这是我的 package js 文件 name cabed version 0 1 0 private false dependencies testing library jest dom 5 16 5 testing library r
  • 经典 ASP 错误行 0 列 -1

    我们运行一个基于经典 ASP 构建的繁忙网站 出于各种遗留原因 在繁忙期间 我们会看到无法解释的错误 但无法追根究底 它通过 IIS 7 触发我们的自定义 500 错误页面来体现 在此页面上 我们使用 ASPError 对象和 err 对象
  • 如何用点更改 ggplot2 箱线图颜色

    解决了抖动问题 https stackoverflow com questions 52506296 ggplot geom point position jitterdodge not working when color specifi
  • 如何在宽度可变的 div 中居中/对齐 Google 地图

    我在 div 中加载了 Google 地图 其宽度为页面的 100 通过 API 叠加层位于中心 地图应如下所示放置 问题是地图现在左对齐 我可以使用与页面宽度相对应的 LatLng 移动中心 但这对于一个简单的任务来说似乎需要大量工作 我
  • C# 为 Azure Function v3 全局设置大小写约定

    我是 Azure Functions 的新手 正在尝试将 NET Core API 转换为 Azure Functions 我面临的问题是如何全局设置响应命名约定 JSON 默认情况下 它是CamelCase但我想用PascalCase 我
  • 如何从 git 上的 filter-branch 命令中删除重复的提交?

    我有一个 Django 项目 我已经将其保密很长一段时间了 在我参与的项目的整个生命周期中settings py base settings py and secret settings py包含敏感信息的文件 现在我决定将代码开源 因为我
  • React Native - TextInput 的 onChange 与 onChangeText 之间的区别

    我不确定什么时候使用onChange vs onChangeText in a TextInput成分 我知道onChangeText接受更改后的文本作为回调中的参数 但这就是您要使用的原因onChangeText 因为您可以在回调中更新状
  • Array_merge 与 + [重复]

    这个问题在这里已经有答案了 当我使用array merge 使用关联数组我得到了我想要的 但是当我将它们与数字键数组一起使用时 键会发生变化 With 键被保留 但它不适用于关联数组 我不明白这是如何工作的 有人能给我解释一下吗 由于两个数
  • FabricJs - 通过 SVG 对象剪切区域

    我对 FabricJS 对象有疑问 我想创建一个剪切区域 svg 对象 它将剪切加载的图像 我在加载的图像上使用 ClipTo 方法 将其传递到剪切区域形状对象 SVG 中 但它不起作用 因为 SVG 不是 FabricJS 意义上的形状对
  • 设置 java URLConnection 的用户代理

    我正在尝试使用 Java 和 URLConnection 来解析网页 我尝试像这样设置用户代理 java net URLConnection c url openConnection c setRequestProperty User Ag
  • 在 dll 中嵌入 prolog 引擎

    我最近一直在开发一个嵌入 prolog 推理引擎的 C 应用程序 正如标题中所述 我现在尝试生成一个 DLL 而不是可执行文件 以便我可以在另一个项目中使用它 由于我是 DLL 开发的新手 我想我可以从一个小例子开始 我有3个文件 like
  • Spark DropDownList 自定义 ItemRenderer 问题

    我有一个 Spark DropDownList 它有一个自定义 ItemRenderer ItemRenderer 在创建时会检查标签文本 如果它符合特定条件 则标签文本颜色会发生变化 标签文本颜色正在改变 但它是错误的标签 似乎发生的情况
  • Git 子树合并策略或子树命令?

    我正在启动一个新的 Zend Framework 项目 我将在其中与设计师合作 我将使用 git 维护这个项目代码 通常设计师不会说 git 或任何编程语言 所以我想让他变得简单 否则我担心他根本不会使用 git 我的计划是给他一些 Git