git checkout的实现机制是什么?

6
运行git checkout时,旧的HEAD和新的HEAD的合并基可以是任意远的。朴素的实现方式是逐个应用每个diff,但该操作会立即运行。
我有一种预感它可能是通过某种跳表结构来实现中间diff缓存的,但这只是一个猜测。
有人知道它是如何实现的吗?谢谢! :)

4
你可以前往 Github 查看 Git 的源代码,知道吗... - Makoto
Git就是魔法,就这么简单 :) - Sergio Tulentsev
1
提交并不存储增量,它们存储树形结构。无需应用差异:checkout只是提取文件。(存储在包文件中的对象可能需要一些增量解压缩,但这是另一回事。) - torek
1个回答

5
您可以参考Mary Rose Cook的JavaScript实现Git(作为练习)Gitlet中,关于结账(checkout)的良好示例。
详见注释源代码
进行结账操作的步骤如下:
  • checkout()更改索引、工作副本和HEAD以反映ref的内容。
    ref可能是分支名称或提交哈希。
  • 获取要检查的提交哈希。
  • 如果无法找到ref,则中止。
  • 如果要检出的哈希指向不是提交对象的对象,则中止。
  • 如果ref是当前正在检出的分支的名称,则中止。 如果head已分离,ref是提交哈希,且HEAD指向该哈希,则中止。
  • 获取更改了工作副本中的文件的列表。
    获取head提交和要检查的提交中不同的文件的列表。
    如果这两个列表中有任何一个文件,则中止。
  • 否则,执行结账操作。
  • 如果ref在对象目录中,则它必须是哈希,因此此次结账将分离head。
  • 获取当前提交和要检查的提交之间的差异列表。将它们写入工作副本中。
  • 将正在被检出的提交写入HEAD
    如果head已分离,则将提交哈希直接写入HEAD文件中。
    如果head未分离,则将正在检出的分支写入HEAD
  • 将索引设置为正在检出的提交的内容。
  • 报告结账结果。
再次说明,这是一种简化(与实际Git代码相比),但可以很好地说明结账操作的工作原理。
如果需要了解更多信息,可以听Thomas Ferris Nicolaisen主持的GitMinutes #31: Mary Rose Cook on Gitlet播客。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接