为什么父项存储在git notes中?
git store注意到:为什么父项存储在git notes中?,git,git-svn,internals,git-notes,Git,Git Svn,Internals,Git Notes,git store注意到: Git对于单个名称空间每次提交只存储一个注释。一个可以有多个名称空间。默认名称空间是commit .git/refs/notes/包含一个哈希(例如,MainHash_2),它是一个树对象。无论何时创建便笺,哈希都会更改 此树对象还包含两个哈希。一个到另一个树结构(notes树结构,例如notes_2)和一个到父树对象(创建此备注之前的.git/refs/notes/中的一个,例如MainHash_1) 注释树结构包含每个注释的一个条目。每个条目有两个散列:一个用于
- Git对于单个名称空间每次提交只存储一个注释。一个可以有多个名称空间。默认名称空间是commit
- .git/refs/notes/包含一个哈希(例如,
),它是一个树对象。无论何时创建便笺,哈希都会更改李>MainHash_2
- 此树对象还包含两个哈希。一个到另一个树结构(notes树结构,例如
)和一个到父树对象(创建此备注之前的.git/refs/notes/中的一个,例如notes_2
)MainHash_1
- 注释树结构包含每个注释的一个条目。每个条目有两个散列:一个用于记录内容,另一个用于指定提交
假设你现在有三个音符
MainHash_2
包含到NOTES_2
的散列,每个note包含三个条目MainHash_1
包含一个到NOTES_1
的散列,其中包含两个条目(对于除现在创建的注释外的所有其余注释)为什么要将这两个条目存储两次,以此类推???因为notes名称空间在git中不是什么特别的东西,它们只是具有完整历史记录的普通分支。你能行
git checkout notes/commits
并像处理任何其他分支一样处理您的笔记,例如,您可以
git log notes/commits
查看笔记的提交日志。这样,您就可以跟踪笔记的所有更改
你说:
.git/refs/notes/commits
包含一个散列(例如,MainHash_2
),它是一个树对象
它不是树对象,而是提交。就像在.git/refs/heads/master中一样。您可以使用git cat文件检查它-t
是在中引入的。2010年2月,Git v1.7.1-rc0引入了扇出的概念,在
.Git/refs/notes/commits
中确定了notes树这一部分的最佳磁盘扇出
“fanout
”变量的值:
:无扇出(所有注释直接存储在根注释树中)0
:1
fanout2/38
:2
fanout2/2/36
:3
fanout2/2/2/34
(于2020年2月14日合并) :更仔细、更稳健地检查注释扇出 简而言之,在此修补程序之前,此测试脚本:
- 创建许多注释
- 验证notes树中的所有notes的扇出值是否为1
- 删除大多数注释
- 验证notes树中的notes现在是否具有0的扇出
但是,更改哈希函数或其他外部因素会改变这些数字,理论上,后者可能会低至15。
有关更多详细信息,请参阅 以及: :在减少注释扇出时修复一个错误 如前一次提交中所述,notes代码中扇出启发式的性质导致我们增加或减少notes扇出的确切点随注释对象的不同而变化。
由于测试环境生成的对象ID是确定性的(根据设计),t3305生成和测试的注释总是相同的,因此我们在一次运行到下一次运行时碰巧看到相同的扇出行为 巧合的是,如果我们稍微改变一下测试环境(比如在开始t3305测试之前在一个不相关的分支上进行测试提交),我们不仅看到扇出开关在不同的点上发生,我们还设法在notes代码中触发一个bug,其中fanout
1->0
开关未在notes树中统一应用,而是生成如下notes树:
...
bdeafb301e44b0e4db0f738a2d2a7beefdb70b70
bff2d39b4f7122bd4c5caee3de353a774d1e632a
d3/8ec8f851adf470131178085bfbaab4b12ad2a7
e0b173960431a3e692ae929736df3c9b73a11d5b
eb3c3aede523d729990ac25c62a93eb47c21e2e3
...
当我们使用新减少的扇出写入notes树时,会发生此错误,并且notes树包含未扩展的子树,这些子树应由于扇出减少而合并到父树中):
恰好位于内部notes 16树结构中偶数级别的子树(换句话说:其路径-“d3
”在上例中-在第一个半字节中是唯一的-即,没有其他以“d
”开头的注释路径)不会作为树写出的一部分进行解压缩。此错误将在随后的注释树中重复,直到子树被强制解包。在t3305中,只有当
d38ec8f8
注释本身从树中删除时,才会发生这种情况
错误并不严重(没有信息丢失,notes代码能够读取/解码此树并正确操作),但这仍然是c语言中的一个错误