代码之家  ›  专栏  ›  技术社区  ›  ATL_DEV

Git工作树和Git子树有什么区别?

  •  0
  • ATL_DEV  · 技术社区  · 7 年前

    就在我认为Git不能变得更复杂的时候,我发现了Git工作树。这要么是子树的同义词,要么是我不知道的特性。工作树与子树相同还是不同?如果它们是不同的,它们是如何不同的,WorkTree解决了什么问题?

    2 回复  |  直到 7 年前
        1
  •  3
  •   torek    7 年前

    这些是非常不同的。为了正确理解它们,让我们定义 工作树 (或“工作树”或“工作树”或几乎所有这些拼写的变体),关于 指数 并且 提交 .

    您已经知道提交保存快照,并且每个提交都有一个唯一的哈希ID,用于命名一个特定的提交。同一提交可以有许多其他名称(例如分支和/或标记名),但只有一个哈希ID。您可能还知道提交具有 元数据: 是谁制造的(姓名和电子邮件地址)、时间(时间戳)和原因(消息 git log 展示)每个提交还具有 起源 哈希IDOR,一个父类列表,通常只有一个条目。父级是刚好在这个提交之前的提交,这样Git就可以向后遍历提交链,以显示随时间变化的内容。(具有两个父哈希ID的提交是 合并提交 . 提交 父哈希ID是 根提交 ,并且在任何非空存储库中至少有一个,因为第一次提交之前没有提交。)

    包括提交中的文件在内的所有内容在任何时候都是完全冻结的。您不能更改其中的任何一个,不是一个位,原因是哈希ID实际上是提交的所有内容的加密校验和。如果你只改变了一个位,校验和就会不同,所以这是一个 不同的 使用其他哈希ID提交。

    这意味着存储在任何提交中的所有文件都将被冻结。它们也被压缩成一种只有git才能读取的特殊git格式。这对 历史 但是我们怎样才能完成任何工作呢?这就是 工作树 进入图片。

    要处理文件,我们必须让Git复制它们。 外面的 提交的这将把文件放回到它们的日常形式中,在那里,所有的编辑、编译器、计算机上的任何东西都可以读取它们,当然,它们是可写/可更改的。你处理文件的地方就是你的 工作树 .

    之间 现在的 提交(但是选择了)和工作树,因此 两份 每个文件:提交中的冻结副本,以及工作树中的有用副本。

    Git可以在这里停止,以及其他版本控制系统,如Mercurial(请参见 )就这么做。但出于各种原因,他们中的许多人都与“快速行动”有关,Git补充道 第三的 每个文件的副本。这第三个副本被Git称为 指数 , the 分级区 ,或者 隐藏物 . (您看到的名称取决于Git的谁或哪个部分正在进行调用。)索引中的文件与提交时的格式基本相同,但索引中的文件除外。 冰冻的如果你愿意的话,它们更容易结冰,或者说“烂泥”。

    索引还保留工作树上的选项卡,以便它们紧密配对:索引“知道”工作树中的内容,或者如果索引的缓存方面过期,则它知道 那个 这有助于Git快速了解发生了什么变化。而且,当你跑步时 git commit ,Git不太可能 在工作树上(除了在要为日志消息编辑的文件中添加一些注释)。它只是将准备好的文件从索引中冻结出来,而索引就是在索引中获取其名称的。 分级区 ,进行新的提交。

    最后,当您使用git中的commit时,您可以 任何时候的活动副本:

    • 这个 HEAD 提交副本已冻结,仅限于Git。
    • 索引副本很模糊:仅限于git,但不完全冻结。最初它与 复制,但可以用覆盖它 git add .
    • 工作树拷贝是正常的和流动的,您可以用它做任何事情。

    索引和工作树是成对的。此外,在合并冲突期间,索引承担了一个扩展的角色:它最终保存来自 提交,这是合并的三个输入。当它处于这种扩展模式时,你甚至不能 git stash 或者,在不完成或中止合并的情况下,从修改过的索引和工作树状态中脱离出来。

    这给我们留下了一个需要解决的问题:如果在做某件事情的过程中,我们需要,相当紧急地,修复一些 其他 分支机构?我们可以做另一个克隆,这是传统的答案。如果我们不处于冲突合并的中间,我们可以使用 暂存 那是另一个答案。一个不是非常令人满意,另一个是无用的,如果我们正在合并。

    所以,进入 git worktree add . 使用 Git工作树添加 ,您可以添加另一个 一对 现有存储库的索引和工作树。有一个非常强的约束(出于良好的实现特定的原因):每个添加的工作树都必须打开 它自己 分支,或使用“分离头”模式。也就是说,如果您的主工作树在分支上 feature/short 没有 补充 工作树可以使用此分支。他们可以使用 master hotfix develop ,但不是 特征/短 . (或者,他们可以在存储库中的任何地方使用分离的头进行提交。)

    当您完成任何添加的二级工作树时,您可以简单地 rm -rf 然后跑 git worktree prune 从另一个二级工作树,或主工作树,要有git搜索,而没有找到添加的工作树。这将“解锁”添加的工作树签出的任何分支。

    与此同时, git subtree 命令是一个奇特的shell脚本,它允许您将现有存储库的某些部分提取到将在其他地方使用的新存储库中,或者提取正在在其他地方使用的现有存储库,并尝试从中提取内容。因此,在某些情况下,这是一个存储库到存储库的传输者,至少是它的设置。

    ( RomainValeri has also mentioned the git-merge-subtree merge strategy ,这与 Git子树 因为它的目标是在合并的三个输入中的一个或两个中处理子树重命名。)

        2
  •  0
  •   Romain Valeri    7 年前

    这些概念是不相似的,比较似乎很奇怪,除了相似的声音。

    git worktree ( doc )是正确的git命令(而子树是 contribution , 多亏了 Chris 为了信息 )这基本上有助于您在同一个repo上管理多个工作树,并附加几个子命令( list , add 等)。

    而子树,除了前面提到的贡献外,是可用的 merge strategies .

    但正如我所说,这两个并不特别相关,即使其中一个 能够 在多工作树报告的上下文中使用子树合并…我想这不是你问题的一部分。