如何消除git中模糊缩写sha1的歧义

时间:2014-12-11 17:04:12

标签: git

我被Josh Stone's analysis of sha1 abbreviation collisions感兴趣。

让我们说有人在明确的时候写下了缩写的提交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>...]'

现在,作为一个人,如果git只是向我展示模棱两可的物体,我可能会告诉我的意思。我怎样才能达到以下目的?

$ git objects-starting-with 8b82547e33
8b82547e33e: commit: l2tp: Restore socket refcount when sendmsg succeeds
8b82547e338: tree [2 files, 26 subtrees]

(注意:以上示例使用的是http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git的相对当前的克隆。)

2 个答案:

答案 0 :(得分:42)

您可以使用git rev-parse,假设您至少有4位数的完整哈希前缀。

git rev-parse --disambiguate=8b82547e33

答案 1 :(得分:6)

使用Git 2.11 +(2016年第4季度),您甚至不必输入git rev-parse --disambiguate=...

Git会为您列出可能的候选人!

请参阅commit 5b33cb1(2016年9月27日),commit 1ffa26ccommit fad6b9ecommit 16ddcd4commit 0c99171commit 59e4e34,{{3} },commit 0016043commit 5d5def2commit 8a10feacommit 7243ffd(2016年9月26日)commit 259942f

(由Jeff King (peff)合并于Junio C Hamano -- gitster --,2016年10月6日)

  

get_short_sha1:列出错误的不明确对象

     

当用户给我们一个模糊的短sha1时,我们会打印错误并拒绝解决它   在某些情况下,下一步是让他们为我们提供更多字符(例如,如果他们正在重新输入或从完整的sha1中剪切和粘贴)。但在其他情况下,这可能就是他们所拥有的一切。

     

例如,旧的提交消息可能使用了7个字符的十六进制   在当时是独一无二的,但现在是模棱两可的   Git没有提供有关它找到的模糊对象的任何信息,因此用户很难找出他们可能意味着哪一个。

     

这个补丁教导commit 66c22ba列出它找到的对象的sha1,以及一些可以帮助用户决定它们意味着什么的信息
  这是get_short_sha1()上的样子:

  $ 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>...]'
  

我们显示标签的标记名,以及提交的日期和主题   对于树木和斑点,从理论上讲,我们可以挖掘历史,找到它们存在的路径。但这非常昂贵(内核大约30秒),而且它不太可能有所帮助。
  大多数简短引用都是提交,因此有用的信息通常是有问题的对象不是提交。因此,花费大量CPU抢先挖掘路径是愚蠢的;如果他们确实需要,用户可以自己完成。

     

当然,我们在消除歧义的提示中缩写了sha1s,这有点讽刺。
  但是完整的sha1会导致提交行的烦恼换行,并且可能用户只是使用更正的sha1立即重新发出命令。

     

我们还将列表限制为与任何消除歧义提示相匹配的列表。 E.g:

  $ 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'.
  

不打算报告blob,因为它们不能像树一样工作。

2017年11月更新(一年后),使用Git 2.16(2018年第一季度),消除歧义的速度会更快: 最初git.gitcommit 0e87b85 Derrick Stolee

  

sha1_name:在消除歧义期间最小化OID比较

     

在消除packfile OID消歧时最小化OID比较。

     

教git使用带有完整OID的二进制搜索来查找对象   pack-index中的位置(或插入位置,如果不存在)。   对象之前和之后(或插入时的对象)   position)给出最大公共前缀。没有后续的线性搜索   是必需的。

     

如果对象id存在于中,请注意检查哪两个   打包文件。

     

如果find_unique_abbrev_r()的输入是部分前缀,那么   用于二进制搜索的OID用零填充,因此对象将   回购中不存在(具有高概率)和相同的逻辑   适用。

     

此提交完成了对OID缩写的一系列三次更改   代码,使用标准命令可以看到整体更改   大回购。下面我们报告perf test 4211.6的性能统计数据   来自p4211-line-log.sh使用Linux repo的三个副本:

| 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% |

2018年3月更新,sha1消歧更加强大,因为(在21.7之前)找到唯一对象名称缩写时,代码可能意外地读取了包中对象名称数组的末尾。

discussed herecommit 21abed5(2018年2月27日) (由Derrick Stolee (derrickstolee)合并于Junio C Hamano -- gitster --,2018年3月8日)

它也更快:

  

sha1_name:在消除歧义期间最小化OID比较

     

在消除packfile OID消歧时最小化OID比较。

     

git使用二进制搜索和完整的OID来查找对象   pack-index中的位置(或插入位置,如果不存在)   对象之前和之后(或插入时的对象)   position)给出最大公共前缀。没有后续的线性搜索   是必需的。

     

此提交完成了对OID缩写的一系列三次更改   代码,使用标准命令可以看到整体更改   大回购。
  下面我们报告perf test 4211.6的性能统计数据   来自p4211-line-log.sh使用Linux repo的三个副本:

| 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% |

Git 2.18(2018年第二季度)改进了该候选列表:当使用短十六进制字符串来命名对象但是有多个对象共享该字符串作为其名称的前缀时,代码在帮助中列出这些不明确的候选者消息。
这些对象名称现在根据其类型进行排序,以便更容易观看。

commit 7519a60commit 5cc044ecommit a885c93commit 89f32a9commit 7248672commit a264f22(2018年5月10日)。 帮助:Ævar Arnfjörð Bjarmason (avar)
(由Derrick Stolee (derrickstolee)合并于Junio C Hamano -- gitster --,2018年5月30日)

  

get_short_oid:按类型排序不明确的对象,然后是SHA-1

     

更改遇到不明确对象时发出的输出   我们首先显示标签,然后提交,然后是树,最后   斑点即可。
  在每种类型中,我们以hashcmp()顺序显示对象   在此更改之前,对象仅按hashcmp()排序。

     

这样做的原因是输出看起来更好,   例如在此更改之前的v2.17.0标记&#34; git show e8f2&#34;将   显示:

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
  

现在我们改为显示:

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