git 注释压缩的提交

git annotate a squashed commit

我一直对 'squashing' 或重写历史持怀疑态度,现在我几乎确信我应该在我管理的回购协议中禁止这种做法。但也许有人可以回答这个问题,并为我的 squash-championing 同事节省时间。

我刚刚遇到一行代码,我想了解背后的原因,所以我用 git annotate 找出是谁写的以及为什么写的。但它指向一个 'squashed' 提交,一长串关于无数功能和 bug-fixes 的提交消息 headers,没有详细信息。没什么用。

'哦,但是总是有 reflog,'我得到了保证; 'information never actually gets lost in git!' 好的,很高兴听到这个消息!但我尝试了 git reflog <squashed-commit-hash>,但根本没有输出——没有帮助。我还尝试了 git rev-list <squashed-commit-hash>,得到了一个包含数百个哈希值的列表,在使用 git show 手动检查其中一些后,我得出结论,它们不是被压扁的部分——也没有帮助.

那么是否真的有可能找出哪一个提交对那行代码有贡献,并查看该提交的完整消息?是否可以在一个 git 命令中完成,而不必成为 bash 专家?还是这些信息实际上在 git 中丢失了?

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

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

我要强调一下:

I've been assured; 'information never actually gets lost in git!'

属于 Git 下的文件,通常是源代码。自然地,当一个人正在改写历史时,所有的赌注都会落空。

由于您可以看到谁提交了工作,因此获取有关该特定代码行的更多信息的最佳做法是与他们一起对其进行代码审查。如果他们不再与您合作,那么您所要做的就是整个压缩的提交。

So is it actually possible to find out which single commit contributed to that line of code, and see that commit's entire message?

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

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

由于其他答案没有解决,我认为这需要指出:

'Oh, but there's always the reflog,'

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

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

关于更广泛的问题:

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

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