我对Josh Stone对sha1缩写碰撞的分析很感兴趣.
让我们说有人写下了一个缩写的提交ID 8b82547e33
,在它明确无误的时候.但从那时起,其他对象已经创建了相同的前缀,所以现在git告诉你(由于某种原因两次):
$ git show 8b82547e33
error: short SHA1 8b82547e33 is ambiguous.
error: short SHA1 8b82547e33 is ambiguous.
fatal: ambiguous argument '8b82547e33': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Run Code Online (Sandbox Code Playgroud)
现在,作为一个人,如果git只是向我展示模糊的对象,我可能会告诉我的意思.我怎样才能实现以下内容?
$ git objects-starting-with 8b82547e33
8b82547e33e: commit: l2tp: Restore socket refcount when sendmsg succeeds
8b82547e338: tree [2 files, 26 subtrees]
Run Code Online (Sandbox Code Playgroud)
(注意:以上示例使用的是http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git的相对最新的克隆.)
che*_*ner 42
git rev-parse
假设您至少有4位数的完整哈希前缀,则可以使用.
git rev-parse --disambiguate=8b82547e33
Run Code Online (Sandbox Code Playgroud)
使用Git 2.11 +(2016年第4季度),您甚至不必输入git rev-parse --disambiguate=...
.
Git会为您列出可能的候选人!
请参阅提交5b33cb1(2016年9月27日),并提交1ffa26c,提交fad6b9e,提交16ddcd4,提交0c99171,提交59e4e34,提交0016043,提交5d5def2,提交8a10fea,提交7243ffd,提交259942f(2016年9月26日)作者:Jeff King(peff
).
(由Junio C gitster
Hamano合并- -在承诺66c22ba,2016年10月6日)
get_short_sha1
:列出错误的歧义对象当用户给我们一个模糊的短sha1时,我们会打印错误并拒绝解决它.
在某些情况下,下一步是让他们为我们提供更多的角色(例如,如果他们正在重新填充或从完整的sha1中剪切和粘贴).但在其他情况下,这可能就是他们所拥有的一切.例如,旧的提交消息可能使用了当时唯一的7字符十六进制,但现在是不明确的.
Git没有提供有关它找到的模糊对象的任何信息,因此用户很难找出它们可能意味着哪一个.这个补丁教导
get_short_sha1()
列出它找到的对象的sha1,以及一些可以帮助用户决定它们意味着什么的信息.
这是git.git上的样子:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Run Code Online (Sandbox Code Playgroud)
我们显示标签的标记名,以及提交的日期和主题.
对于树木和斑点,从理论上讲,我们可以挖掘历史,找到它们存在的路径.但这是非常昂贵的(内核大约30秒),并且它不太可能有用.
大多数简短引用都是提交,因此有用的信息通常是有问题的对象不是提交.因此,花费大量CPU抢先挖掘路径是愚蠢的; 如果用户真的需要,用户可以自己完成.当然,我们在消除歧义的提示中缩写sha1是有点讽刺的.
但是完整的sha1会导致提交行令人讨厌的换行,并且可能用户只是使用更正的sha1立即重新发出命令.我们还将列表限制为与任何消除歧义提示相匹配的列表.例如:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
Run Code Online (Sandbox Code Playgroud)
不打扰报告blob,因为它们不能像树木一样工作.
更新于2017年11月(一年后),Git 2.16(2018年第一季度)的消歧将更快:
请参见Derrick Stolee 提交的0e87b85,最初在此处讨论.
sha1_name
:在消除歧义期间最小化OID比较在消除packfile OID的消歧期间最小化OID比较.
教git使用带有完整OID的二进制搜索来查找pack-index中对象的位置(或插入位置,如果不存在).之前和之后的对象(或插入位置处的对象)给出最大公共前缀.不需要后续的线性搜索.
如果packfile中存在对象id,请注意检查哪两个.
如果输入to
find_unique_abbrev_r()
是部分前缀,则用于二进制搜索的OID用零填充,因此对象将不存在于repo中(具有高概率)并且适用相同的逻辑.此提交完成了对OID缩写代码的一系列三次更改,并且可以使用用于大型回购的标准命令来查看整体更改.下面我们
p4211-line-log.sh
使用三个Linux repo副本报告perf test 4211.6的性能统计信息:
| Packs | Loose | HEAD~3 | HEAD | Rel% |
|-------|--------|----------|----------|-------|
| 1 | 0 | 41.27 s | 38.93 s | -4.8% |
| 24 | 0 | 98.04 s | 91.35 s | -5.7% |
| 23 | 323952 | 117.78 s | 112.18 s | -4.8% |
Run Code Online (Sandbox Code Playgroud)
更新2018年3月,sha1消歧更加强大,因为(在21.7之前)找到唯一对象名称缩写时,代码可能会意外地读取超出包中对象名称数组的末尾.
见Derrick Stolee()提交21abed5(2018年2月27日).(由Junio C Hamano合并- -在提交7519a60,2018年3月8日)derrickstolee
gitster
它也更快:
sha1_name
:在消除歧义期间最小化OID比较在消除packfile OID的消歧期间最小化OID比较.
教导
git
使用具有完整OID的二分搜索来查找对象的位置(或插入位置,如果不存在)pack-index
.
之前和之后的对象(或插入位置处的对象)给出最大公共前缀.不需要后续的线性搜索.此提交完成了对OID缩写代码的一系列三次更改,并且可以使用用于大型回购的标准命令来查看整体更改.
下面我们p4211-line-log.sh
使用三个Linux repo副本报告perf test 4211.6的性能统计信息:
| Packs | Loose | HEAD~3 | HEAD | Rel% |
|-------|--------|----------|----------|-------|
| 1 | 0 | 41.27 s | 38.93 s | -4.8% |
| 24 | 0 | 98.04 s | 91.35 s | -5.7% |
| 23 | 323952 | 117.78 s | 112.18 s | -4.8% |
Run Code Online (Sandbox Code Playgroud)
Git 2.18(2018年第二季度)改进了该候选列表:当使用短十六进制字符串来命名对象但是有多个对象共享该字符串作为其名称的前缀时,代码在帮助消息中列出这些不明确的候选者.
现在,这些对象名称根据其类型进行排序,以便更容易进行眼球定位.
见提交5cc044e,提交a885c93,提交89f32a9,提交7248672,提交a264f22(2018月10日)通过ÆvarArnfjörðBjarmason( )avar
.
帮助:Derrick Stolee(derrickstolee
).
(由Junio C gitster
Hamano合并- -在提交ab48bc0,2018年5月30日)
get_short_oid
:按类型排序不明确的对象,然后是SHA-1更改遇到不明确对象时发出的输出,以便首先显示标记,然后提交,然后是树,最后是blob.
在每种类型中,我们按hashcmp()
顺序显示对象.
在此更改之前,对象仅按顺序排序hashcmp()
.这样做的原因是输出结果看起来更好,例如在"
git show e8f2
" 更改之前的v2.17.0标记将显示:
hint: The candidates are:
hint: e8f2093055 tree
hint: e8f21ca commit 2013-06-24 - bash prompt: print unique detached HEAD abbreviated object name
hint: e8f21d02f7 blob
hint: e8f21d577c blob
hint: e8f25a3a50 tree
hint: e8f2625 commit 2017-02-03 - Merge pull request #996 from jeffhostetler/jeffhostetler/register_rename_src
hint: e8f2650052 tag v2.17.0
hint: e8f2867228 blob
hint: e8f28d537c tree
hint: e8f2a35526 blob
hint: e8f2bc0 commit 2015-05-10 - Documentation: note behavior for multiple remote.url entries
hint: e8f2cf6ec0 tree
Run Code Online (Sandbox Code Playgroud)
现在我们将改为:
hint: e8f2650052 tag v2.17.0
hint: e8f21ca commit 2013-06-24 - bash prompt: print unique detached HEAD abbreviated object name
hint: e8f2625 commit 2017-02-03 - Merge pull request #996 from jeffhostetler/jeffhostetler/register_rename_src
hint: e8f2bc0 commit 2015-05-10 - Documentation: note behavior for multiple remote.url entries
hint: e8f2093055 tree
hint: e8f25a3a50 tree
hint: e8f28d537c tree
hint: e8f2cf6ec0 tree
hint: e8f21d02f7 blob
hint: e8f21d577c blob
hint: e8f2867228 blob
hint: e8f2a35526 blob
Run Code Online (Sandbox Code Playgroud)