为什么`git checkout <branch> <file>`进行更改?

Luk*_*uke 11 git branch git-checkout git-branch

如果我从一个干净的工作树开始运行git checkout <branch> <file>,那里<branch>有这个文件的不同版本,我最终会进行一个阶段而不是一个非分阶段的更改.

这是什么原因?这是否只是为了与其他命令保持一致git mv,您希望这些命令可以进行更改?用于git checkout解决合并冲突时是否方便?还是有其他理由吗?

这对我来说似乎有点奇怪,因为只是使用git checkout <branch> <file>并没有提供任何关于我是否计划改变的指示.

tor*_*rek 8

它实际上是Git作者选择透露的实现细节.

Git的不能,或者说,在一个点上,可以直接从仓库到工作树不读文件.它具有(或有)通过中介先通过他们:它必须将它们复制,或至少他们的生命统计,1别的地方.只有这样,Git才能将数据复制到工作树文件中.2 "其他地方"是索引条目.索引也称为暂存区域.

当你完成git checkout整个提交时,无论如何这都是你想要的.因此,首先复制到索引然后再复制到工作树的内部限制实际上是一个加分.因此,这种首先复制到索引中,然后再导入工作树的机制被嵌入到实现中.然后,最终,面向用户的git checkout前端获得了检出一个单独文件或一些小文件子集的能力......并且它继续通过索引这样做.实现细节成为记录的功能.

请注意,有时,索引在冲突合并期间用作帮助区域.在这种情况下,对于某些文件F,在编号的插槽1(基本),2()和3()中最多有三个条目,而不是正常插槽零中的一个条目.如果是这样,您可以将三个索引槽条目中的任何一个提取到工作树,而不会干扰索引.但是如果您使用从其他提交或树中提取文件,Git会将文件复制到索引中,并将其写入插槽零.这有消除更高编号的插槽的副作用,解决合并冲突!--ours--theirsgit checkout


1主要是哈希ID.正如ElpieKay在评论中指出的那样,Git必须将提交哈希解析为树形哈希,然后搜索各种树以找到感兴趣的文件,以便它可以获得blob哈希.索引条目本身也包含更多数据,但包括stat工作树文件的结构数据,以使Git快速运行.

2您仍然可以使用此工作流,方法git read-tree是将树复制到索引中,然后使用git checkout-index将索引复制到工作树.最初,Git由一堆shell脚本组成,就像git-checkout包裹着一些基本的C编码片段一样git-read-tree.(这些名字都是这样的连字符,并且没有前端git命令.)