【问题标题】:git annotate a squashed commitgit 注释一个压扁的提交
【发布时间】:2019-01-21 13:30:17
【问题描述】:

我一直对“压缩”或重写历史持怀疑态度,现在我几乎确信我应该从我管理的存储库中禁止这种做法。但也许有人可以回答这个问题,并为我的壁球冠军同事节省一天的时间。

我刚刚遇到了一行代码,我想了解其背后的原因,所以我使用了git annotate 来找出是谁写的以及为什么写的。但它指向一个“压缩”提交,一长串关于无数功能和错误修复的提交消息头列表,没有详细信息。不是很有帮助。

'哦,但总是有 reflog,'我确信; “信息永远不会在 git 中丢失!”好的,很高兴听到它!但是我尝试了git reflog <squashed-commit-hash>,但根本没有输出——没有帮助。我还尝试了git rev-list <squashed-commit-hash>,得到了一个包含数百个哈希的列表,在使用git show 手动检查了其中一些之后,我得出结论,它们不是被压扁的部分——也没有帮助。

那么实际上是否有可能找出对那行代码有贡献的单个提交,并查看该提交的全部信息?是否可以在一个 git 命令中完成,而不必成为 bash 大师?还是说这些信息实际上已经在 git 中丢失了?

【问题讨论】:

  • “我几乎确信我应该从我管理的存储库中禁止这种做法。”你打算如何做到这一点,究竟是什么? Git 是一个分布式版本控制系统;在与您分享我的提交之前,我在自己的系统上所做的与您无关(您也不能说我已经做到了)。我想你可以通过政策来做到这一点,但我认为这样的政策毫无意义。
  • “但它指向一个 'squashed' 提交,一长串提交消息头,没有详细信息。没有真正的帮助。”压缩原始提交的人通常应确保新提交的提交消息有用的。这可能涉及编辑旧的提交消息、替换它们或添加某种摘要。 Git 实际上会在 squash 期间提示用户输入新的提交消息,并提供旧消息作为起点。来自压缩的无用提交消息可能会在代码审查中被发现,就像常规提交消息和代码更改一样。
  • 我认为“但是 reflogs!”论证回答了错误的问题。无论我是提交原始提交还是重写提交都无关紧要——无论哪种情况,我作为提交作品的人的责任是确保它是正确的、清晰的、通过测试等。如果在审查期间发现我的作品没有满足我需要修复的项目的任何标准。同样,您无法知道给定的提交是否是“原始的”。
  • 嗯...只要提交实际上还没有发布,它们就会在远程。如果它们是(我怀疑它们是),并且最初的提交者选择丢弃它们,那么它们就永远消失了(除非他们想为它们深入研究 reflog)。如果您对最终生成的提交消息有疑问,git commit --amend 将允许您编辑 那个 特定的提交消息。
  • 我的直觉告诉我,与在日常工作流程中使用此功能的人交谈会使您受益更多,这样您就可以更习惯他们的工作方式。我自己在某些情况下使用 rebase 和 squash,但我会尽我所能留下有用的信息;那些不是你一起工作的人,你肯定需要和他们谈谈。

标签: git git-squash git-blame


【解决方案1】:

由于其他答案尚未解决,我认为需要指出这一点:

'哦,但总是有 reflog,'

没有。 100% 错误。 reflog 既是本地的又是临时的。

确实,git 在防止历史丢失方面做得非常好(除非您专门指示它丢失历史),但是说信息永远不会丢失是非常不准确和危险的。人们需要了解信息可能(和不能)丢失的方式,以便他们知道何时以及如何依赖 git 真正提供的保护。

关于更广泛的问题:

重写共享历史记录通常不是一个好习惯。大多数提倡激进的 rebase 的人都希望在推送到远程之前 重写历史记录。这不仅是一种不那么受欢迎的做法,即使你想禁止也几乎不可能(因为当我推送一个提交时,你不知道我是否通过压缩之前的几个提交来创建它)。

最终提交的可接受粒度以及每次提交的可接受文档是您需要与团队一起设定的标准。执法最终可能更多的是社会性而非技术性。

【讨论】:

  • 这个答案最直接地回答了这个问题,所以我把它标记为“接受”的答案。但是我很感谢大家的回答和cmets;他们在很大程度上证实了我对 git 中压缩的理解,并帮助我意识到什么时候合适,什么时候不合适。
  • 不错的答案@MichaelScheper,这是否意味着我不能保证能够运行git show <SQUASHED-COMMIT-SHA>,甚至不能保证使用git bisect 对原子提交有完整的粒度?
  • @tallamjr 我不是 100% 确定你在问什么。如果您从提交 A、B、C 开始,然后将它们压缩到提交 Z,您可以git show <sha-of-Z> 并一起查看所有更改。您可能无法再看到各个变更集 - 即,如果 A 已被 gc 清理,或者如果您处于从未有过 A 的仓库中,则 git show <sha-of-A> 将无法工作,因为它只有 @ 987654327@。同样,在重写的历史记录中,bisect 将无法看到“A 之后但BC 之前的代码状态”
  • 感谢@MarkAdelsberger,这确实为我澄清了一些事情并帮助了我的整体理解。我担心无法在原子级别看到如果随后被 squash 提交可能会导致麻烦;例如,如果提交 B 是罪魁祸首,我将无法看到,只有提交 Z 很麻烦。
【解决方案2】:

压缩一个提交会将多个提交合并为一个,让提交者可以选择为每个单独的提交维护提交消息。

如果他们选择这样做,那么就无法辨别合并为一个的单个提交的信息。

我应该强调:

我已经放心了; “信息永远不会在 git 中丢失!”

适用于 Git 下的文件,通常是源代码。自然,当一个人正在改写历史时,所有的赌注都没有了。

由于您可以看到谁提交了这项工作,因此获得有关该特定代码行的更多信息的最佳选择是与他们一起进行代码审查。如果他们不再与您合作,那么您只需要完成整个压缩提交即可。

【讨论】:

    【解决方案3】:

    那么实际上是否有可能找出对那行代码有贡献的单个提交,并查看该提交的整个消息?

    就您的项目历史而言,“单一提交”是压缩的提交,因此这将显示为代码更改的来源。这是有意的,实际目的是将多个提交合并为一个以保持 git 历史可管理。这是我何时压缩项目提交的示例:

    我正在开发一个中等规模的功能。需要几天时间才能完成。我倾向于定期提交“正在进行的工作”(WIP)提交,并且总是在一天结束时提交。我的提交消息通常在我正在处理的当前功能的范围内,而不是整个项目的范围内。一旦功能完成并且我合并到任何工作分支(比如说 dev),这些消息很难在项目的上下文中解析,并且我在功能分支上所做的提交之间的差异对于可维护性并不重要.重要的区别在于功能之前与功能之后,因此我会将所有提交合并为一个标记为“(票号)-(功能名称)”的内容

    【讨论】:

    • 是的,压扁这个分支的人似乎滥用了这个功能,因为它实际上是一个发布分支,为了一些票。但我最关心的是原始提交中缺少提交细节。我提倡使用“主题”行来解释功能/错误修复是什么,有时还会有一段解释方法,通常是考虑的替代方案。这些信息可能实际上属于代码 cmets 或票证,但它仍然帮助解释了无数次代码,所以我很苦恼它很难找到。
    猜你喜欢
    • 2018-08-14
    • 2013-08-18
    • 2015-01-15
    • 1970-01-01
    • 2020-08-29
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    相关资源
    最近更新 更多