Py学习  »  Git

Git是按文件还是按目录合并信息?

Hyunjik Bae • 5 年前 • 1367 次点击  

在Perforce中,合并信息(如合并历史记录)是每个文件的一部分。 在Subversion中,合并信息是每个目录的。 在Git中,是每个文件还是每个目录的合并信息?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/51680
 
1367 次点击  
文章 [ 1 ]  |  最新文章 5 年前
torek
Reply   •   1 楼
torek    6 年前

两者都不是。

Subversion在这里有点奇怪,因为它建立在一个系统之上,这个系统从根本上处理 目录 . 这意味着您可以使用Subversion签出一个特定的目录well,类似于:您也可以得到它的子目录。但它以一个目录开始:因此是目录级的合并信息。

Git的基本单元既不是文件也不是目录,而是 犯罪 . 你不能得到少于一个完整的承诺。 1个 当你跑的时候 git checkout commit-specifier ,Git复制 整个提交树 在索引/暂存区域这占用的空间相对较小;请参见脚注1将所有这些文件从索引复制到 工作树 你可以在那里工作。

每个Git提交都是 全部的 项目中的文件,或者更准确地说,提交时索引中的所有文件。由于索引以当前提交中的所有文件开始,因此它在下一次提交中也将继续拥有所有文件。合并提交与其他提交没有什么不同:它拥有所有的文件,在它们的全部和完整的荣耀中,但是压缩、冻结和Git化,任何提交中的所有文件都是压缩、冻结和Git化的。因为它们是冰冻的你不能改变 任何 部分 任何 承诺,永远 共享 如果它们没有改变,那么如果你提交一个100兆字节的文件10次,甚至100万次,那么 文件 使用的磁盘空间量与只提交一次100兆字节的文件相同,因为实际上 . (每次提交都会在文件顶部为提交的元数据添加一点空间,但是如果您熟悉 链接 在Unix/Linux系统上,您可以将每次提交都看作与一个底层文件有一个硬链接。)

同时,事实上 通过 起源 一个或多个哈希ID存储在每个提交中。每个提交都会记住原始散列ID(s)的真实名称,因为它是紧接着这个特定提交之前的提交的真实名称。对于大多数提交,只有一个这样的散列ID,我们最后得到一个向后看的链,因此如果我们从 最近的 提交其哈希值为某个大而丑陋的哈希值,我们将只调用该哈希值 H ,我们可以找到它的父级,我们将调用其散列 G . 我们可以用 找到 ,我们称之为 F ,然后使用 F型 寻找 F型 的父级,依此类推:

... <-F <-G <-H

我们只需要知道这个问题的答案: 的哈希ID是什么 最后的 在这个链条上承诺? 为了找到答案,我们查了 分行名称 例如 master . 这个 名称 包含 最新的 仅此而已!其他一切都来自承诺。

合并提交的唯一特殊之处是它至少记录 父哈希:

...--F--G--H
            \
             M--...
            /
...--J--K--L

合并信息在于 M 有两个父母, 小时 L . 从 我们要么回去 小时 ,然后沿着那条链条往回走,或者我们可以回到 然后沿着那条链子往回走。三项承诺 , 小时 ,和 是完整的快照,所以如果我们想了解顶级链如何提交 小时 通过合并底部链进行修改 投入其中,我们可以比较 小时 . 如果我们想看看下链如何提交 通过合并顶级链提交进行了修改 小时 我们可以比较一下 . 这些是 相同的 例如,当我们想知道 小时 修改:我们比较 小时 ,这是两个快照,以查看 小时 .

如果我们想先看看这两条锁链在哪 发散的 ,我们只需要更广阔的视野:

...--E---F---G----H
      \            \
       \            M--...
        \          /
         I--J--K--L

如果 F型 的父级是 E ,和 J 的父级是 I 他的父母是 E类 ,然后我们可以看到 E类 是我们合并时的合并基地吗 小时 . 因为所有提交都会被冻结,如果 E类 当时是合并基地, E类 现在仍然是合并基础。

这意味着你的问题的答案是: 根本没有显式的合并信息。存在合并以及重复合并所需的信息这一事实由提交图暗示。 提交图是您(或Git)通过读取各个提交而派生的数据结构。因为commit是基本单元,所以总是有一个完整的commit。 2个 在一个 浅的 克隆,你被允许失踪 早期的 提交,但您可以通过返回克隆的位置并“取消”克隆来填充这些内容(或者将其深入到足以看到需要看到的内容)。


1个 Git确实支持 稀疏签出 ,但你还是得到了全部承诺。 全部 它的文件仍会复制到索引中。稀疏签出仅限制将哪些文件从索引复制到工作树。由于索引副本大多是冻结的,并且可以直接共享提交中的副本,这就减少了所需的磁盘空间量,因为有些文件永远不需要从其提交中冻结的格式中解压出来。下一次提交(如果您确实进行了另一次提交)是从索引中的内容进行的,而不是从工作树中的内容进行的,因此新的提交将继续 全部的 尽管签出的文件很少。

2个 Git添加了一种允许占位符的思想,其形式是 承诺人包 ,其中可以有一个提交,但缺少一些内部数据。也就是说,提交本身仍然是基本单元,但是您将知道提交 C类 有树 T型 ,您可能缺少对象 T型 直到有人明确要求它,在那一点上,Git会试图通过打电话给做出承诺的人来实现承诺。这实际上还不在Git中,但它正在慢慢进入代码库。

注意,这有点类似于浅层克隆。对于浅层克隆,您知道提交 C 有父级 第页 ,但你缺少对象 第页 因为有一个浅的移植物使得Git的某些部分假装 C 没有父母。使用 git fetch --deepen= number ,你可以让Git获得 第页 ,但也许是一些祖父母 第页 . 这只是用一个新的移植点替换了那个祖父母的浅移植点,或者如果你已经得到了所有的父母,比如,通过 git fetch --unshallow .