同一路径在Git索引资料中出现三次,不必意味着工作目录里摆着三个同名文件。git-ls-files 2.43.0的OUTPUT说明明确写道:对于尚未合并的路径,索引不只记录一组模式与对象标识,而是最多记录三组,分别来自三棵输入树。[1] 这是一项索引表达,理解它需要看见路径之外的stage。

文档列出的输出对象包含模式、对象、stage和文件路径。[1] 路径说明这些条目对应哪一个位置,stage则让同一路径的不同输入版本保留身份。只抄文件名,再把重复行当作重复文件,会丢失索引特意留下的这项区别;反过来,也不能因为有三行,就推定它们是三份已经并存的最终工作区内容。

git-read-tree的三方合并说明进一步解释了来源。stage 0是普通状态;三棵输入树进入三方关系时,第一棵位于stage 1,第二棵位于stage 2,第三棵位于stage 3。[2] 当把另一分支并入当前分支的场景被用作解释时,它们分别是共同祖先树、当前分支头和另一分支头。三个数字并不是文件新旧程度的通用等级,而是这一比较中的输入身份。

这种组织使“哪一边改变了什么”能够保留下来。官方列举的一个特定情况是stage 2与stage 3完全相同,此时取任一方都没有差别,可折叠回stage 0。[2] 这里的结果来自双方在该路径上的内容一致,不是系统任意偏向数字更大的那一项。

另一组情况则以祖先作为参照。stage 1与stage 2相同而stage 3不同,说明当前分支相对祖先没有在该路径改变,另一分支有变化;反向情形是stage 1与stage 3相同、stage 2不同。[2] 原文分别描述采用发生变化一侧的结果。本文只解释这组内容关系,没有在真实仓库发起合并或提供解决冲突命令。

当仍存在非零stage条目时,文档说结果树不能按普通完成状态写出。[2] 因而,索引保存多方内容,不等于已经有了某一份合并结果。stage 0与stage 1、2、3在这里表达的是结果与仍需处理的输入关系,而不是一个文件可以同时拥有三个最终版本。

对开发工具资料交接,这项说明的实际用途是保留比较来源:同一路径、哪个stage、对应哪棵树的对象,三者共同解释一行索引信息。正文采用git-ls-files 2.43.0的OUTPUT与git-read-tree三方合并连续段,未使用更换索引、覆盖文件、恢复历史或稀疏检出的操作;网页版本更新记录不充当首次发布日期,也没有把文档例子当作本项目的仓库状态。

资料:[1] https://git-scm.com/docs/git-ls-files/2.43.0.html
[2] https://git-scm.com/docs/git-read-tree

信息来源

本文基于上述公开资料整理,未使用来源页面的图片、视频或嵌入媒体。