为所有命令制作git输出完整(非缩写)哈希值?

时间:2014-01-09 04:44:42

标签: git

问题更新

(n.b。我已经接受了罗兰的答案,因为它确实是正确的(和 最简单的解决方案从git 1.7.4.4开始,但请考虑这个问题 关于早期版本的git打开到1.7.0.4。)

这个问题有点散漫(主要是由于我的编辑所导致的编辑) 随后尝试建立更多有关情况的信息),但是 标题中的文字是最重要的一点。

那就是:我试图建立明确的方法来确保所有 git 命令将在其输出中显示完整(未缩写)的哈希值。

由于我专注于向后兼容性,因此需要涵盖旧版本 git 1.7。 理想情况解决方案适用于git 1.7.0.4(用于 仍然支持的Ubuntu 10.04 LTS),但我很满意至少 1.7.2.5(对于Debian 6 / Squeeze LTS)。任何需要晚于版本的版本 1.7.9.5(Ubuntu 12.04 LTS)绝对不理想,但我还是很乐意听到 关于他们。

请注意,我不希望失去能力以缩短哈希值 - 这个问题背后的目的是确保工具与git交互 始终可以访问完整且明确的哈希值。当我手动使用git时 命令行我大部分时间都想要正常的缩写。

Roland Smith建议使用命令行参数覆盖 core.abbrev看起来很理想,但遗憾的是只有自v1.7.4.4起作用(如core.abbrev 以前没有存在)。我怀疑这意味着我们确实需要确定 最全面的特定于命令的参数集(例如git blame -l) 产生同等效果。

编辑的原始问题

一些(大多数?)git命令默认输出缩写的哈希值。对于 实例git blamegit-annotate执行此操作,这个事实就是绊倒 当冲突出现时,当前的Emacs支持(因为他们可以在git之前做) 1.7.11.1 - 参见下面的编辑1),因为模糊的哈希值会导致错误 试图对他们采取行动)。


开始编辑1

我在Changelog中注意到以下内容,这表明原始问题 这促使这个问题不会出现在更新版本的 GIT中。

Fixes since v1.7.11.1
---------------------
 * "git blame" did not try to make sure that the abbreviated commit
   object names in its output are unique.

如果是git应该保证唯一性的情况(至少在 对于任何git命令报告的所有对象名,然后运行该命令的时间 这将大大减轻我的担忧;但显然是一个解决方案 支持早期版本的git的问题仍然存在 兴趣。

结束编辑1


可以使用git blame -lgit annotate -l修复,但我不知道 这两个命令是否是孤立的情况,我想确保这一点 这个问题在其他情况下不会出现。

我能看到的唯一相关configurationscore.abbrev

  

设置长度对象名称缩写为。如果未指定,则有许多命令   缩写为7个hexdigits,对于缩写对象可能不够   名字在足够长的时间内保持独特。

(但我不想删除看到缩写提交的选项), log.abbrevCommit其中:

  

如果为true,则生成git-log(1),git-show(1)和git-whatchanged(1)   --abbrev-commit。您可以使用--no-abbrev-commit覆盖此选项。

--no-abbrev-commit论证并不是一贯的事情 - 我猜想 只有该引文中提到的命令才能识别它(但请参见编辑2 下文)。


开始编辑2

parse-options API document州:

  

布尔长选项可以通过在no-前加上取消(或取消设置),例如   --no-abbrev代替--abbrev。相反,以no-开头的选项   可以否定删除它。

所以接受--abbrev(其中有很多)的命令实际上就是这样 所有人都接受--no-abbrev?通常没有提到这种否定的选择; 虽然--abbrev=40目前是等效的,但即使没有 否定是可以的。)

默认的布尔否定选项功能是什么时候我不清楚 然而,介绍了。

在我的1.7.9.5版git-blame --no-abbrev中导致单字符对象 名。事实上,它与--abbrev=0相同,因为责备使用n+1个字符。 相反,我注意到git branch -v --abbrev=0给出了完整的40 字符。

结束编辑2


潜在问题命令的完整列表及其相应选项 虽然理想的解决方案是可行的,但它会很棒 (或至少应该)被所有git命令(包括 future )尊重 命令),但保持在需要时显示缩写哈希的能力?

我遇到的一个丑陋的方法是创建一个git配置文件 导入原始配置文件(虽然我注意到仅导入 可从1.7.10获得,然后将core.abbrev设置为40;并通过一个使用它 临时GIT_CONFIG环境变量,在调用git时,只要满 提交是必要的。我想这会奏效,但我不愿意这样做。

显然存在错误,至少有一些错误 固定;但是,目标是支持尽可能多的(实际)版本的git 一个用户可能合理地碰巧正在运行,我正在寻找一些东西 向后兼容。

对于它的价值,这里是我通过阅读手册获取的内容 版本1.7.12.4:

接受--abbrev的命令(理论上也是--no-abbrev):

  • 分支
  • CLI
  • 描述
  • DIFF
  • DIFF-索引
  • DIFF-树
  • 日志
  • LS-文件
  • LS-树
  • REV-列表
  • REV-解析
  • 显示-REF

其他选择:

  • git annotate -l <​​/ li>
  • git blame -l <​​/ li>
  • git diff --full-index
  • git log --no-abbrev-commit
  • git show --no-abbrev-commit
  • git whatchanged --no-abbrev-commit

4 个答案:

答案 0 :(得分:16)

使用git -c core.abbrev=40 <command>应该适用于所有命令,因为它&#34;将覆盖配置文件中定义的任何内容&#34;。

似乎已在8b1fa778676ae94f7a6d4113fa90947b548154dd中引入(在1.7.2版本中登陆)。

Edit2 :正如phils注意到的那样,core.abbrev参数已添加到1.7.4.4中。

编辑:W.r.t。硬编码的哈希长度,您可以在初始化程序/库时通过查看.git/objects/*中的文件名长度来查找哈希长度。

答案 1 :(得分:1)

新的更新答案(2021 年)将与 Git 2.31(2021 年第一季度)一起发布

可以将配置变量“core.abbrev”设置为“no”以强制不使用任何缩写,而不管哈希算法如何。

这在 Git will switch from SHA1 to SHA2 时很重要。

请参阅 commit a9ecaa0Eric Wong (ele828)(2020 年 9 月 1 日)。
(于 2021 年 1 月 15 日在 Junio C Hamano -- gitster --commit 6dbbae1 合并)

<块引用>

core.abbrev=no:禁用缩写

签字人:Eric Wong

<块引用>

这允许用户通过禁用缩写来编写与哈希无关的脚本和配置。

在 SHA-256 中使用“-c core.abbrev=40”是不够的,而“-c core.abbrev=64”现在不适用于 SHA-1 存储库。

[jc:调整实现,添加文档和测试]

git config 现在包含在其 man page 中:

<块引用>

如果设置为“no”,则不进行缩写并且对象名称 以完整长度显示。

答案 2 :(得分:0)

注意:使用git -c core.abbrev=x rebase -i适用于编辑器(将显示缩写的提交SHA1)

但是:在内部对于rebase本身的 start 使用相同的缩写SHA1。

不再需要了(根本不需要git -c core.abbrev=40 rebase -i)。

请参阅Kirill A. Shutemov的commit edb72d5,了解Git 2.3.1 +(2015年第1季度/第2季度):

  

rebase -i:在整个脚本内部使用完整对象名称

     

在早些时候,向最终用户显示的缩写提交对象名称是使用硬编码--abbrev=7生成的; commit 5689503rebase -i:尊重core.abbrev,2013-09-28,Git 1.8.5+)试图让它尊重用户指定的core.abbrev,但它错过了初始调用编辑器。

     

现在,我们尝试在内部使用完整的40-hex对象名称,以避免在rebase开始运行后出现歧义。
  在rebase期间新创建的对象可以与 insn表中列出的现有提交共享相同的前缀。
  在调用序列编辑器以将 insn表重新发送给最终用户之前缩短这些对象名,然后在编辑器返回时将其扩展回完整的对象名。

     

但是代码在第一次准备insn表时仍然使用缩写的名称,导致&#34; 7个十六进制或更多&#34;输出给用户

     

将代码更改为从一开始就使用完整的40-hex提交对象名称,以使事情更加统一。

注意:对于交互式变基,&#34; insn sheet&#34;是说明书。有关插图,请参阅commit 3322ad4

答案 3 :(得分:0)

请注意,使用Git 2.12(2017年第1季度),您可以使用git diff --no-index--no-abbrev添加到命令列表中:

commit 43d1948Jack Bates (jablko)(2016年12月6日) Junio C Hamano -- gitster --合并于commit c89606f,2016年12月19日)

  

diff:处理--no-abbrev案例

中的no-index      

解析--no-abbrev选项有两个不同的地方,   和SHA-1缩写的两个不同的地方   我们通常使用--no-abbrev解析setup_revisions(),但在无索引的情况下,“git diff”直接调用diff_opt_parse(),而diff_opt_parse()未处理--no-abbrev 1}}直到现在。 (但它确实处理了--abbrev。)
  我们通常将SHA-1缩写为find_unique_abbrev(),但是当您在存储库外运行“git diff”时,提交4f03666 ("diff: handle sha1 abbreviations outside of repository, 2016-10-20)最近引入了一个特殊情况。

     

setup_revisions()也会调用diff_opt_parse(),但不会调用自己处理的--abbrev--no-abbrev
  setup_revisions()设置rev_info->abbrev,然后将其复制到diff_options->abbrev。它通过将abbrev设置为零来处理--no-abbrev。 (这种变化不会触及那种情况。)

     

在存储库外部特殊情况下,将缩写设置为零   情况,直到现在导致真正的零长度SHA-1,而不是   取零意味着不要缩写。
  但是,触发此错误的唯一方法是在没有git diff --raw--abbrev选项的情况下运行“--no-abbrev”,因为

     
      
  1. 没有--raw它不尊重缩写(这是奇怪的,但一直都是这样),
  2.   
  3. 我们默默地将--abbrev=0钳位到MINIMUM_ABBREV
  4.   
  5. --no-abbrev直到现在才处理。
  6.         

    存储库外的案例是三个无索引案例之一。该   另外两个是你正在比较的文件之一是在...之外   您所在的存储库以及--no-index选项。