我以前觉得 squash 提交很酷,然后我就不得不每天都使用它们。下面就是你应该避免 squash 的原因。
当我第一次加入一个拥有 200 多名成员的大型工程组织时,我注意到的第一件事就是 squash 提交。
对我来说,整个公司一致使用 squash commits 体现了“专业精神”和“我们知道我们在这里做什么!”
我花了大约一个月的时间才意识到我真的不喜欢压缩提交,并且我开始渴望好的、老式的合并提交。
比较压缩与合并 Git 提交
需要提醒的是,“压缩提交”和“合并提交”之间的区别在于,常规“合并”包括目标分支历史记录中的所有 Git 提交,而“压缩”将它们扁平化为一个提交。
令人困惑的是,“squash” 本身并不是命令。相反,您可以在运行git merge或git rebase命令时分别选择“squash and merge”或“squash and rebase”作为选项。
默认情况下,拉取请求 (PR) 将是合并提交,因此在 PR 合并后,工作分支的整个历史记录将合并,外加一个额外的提交(“从分支合并拉取请求 #21...”)。
另一方面,您可以将存储库默认设置为“压缩和合并”,这意味着合并的 PR 将只产生一个提交,而不是从工作分支中带来所有提交。
为什么有人会使用 Squash Commits?
压缩提交的好处是您可以保留“干净的” Git 提交历史记录。由于我们开发人员以……可以说“精确”而闻名……那么整洁的提交历史记录听起来绝对很棒。但事实并非如此。
你可以看到为什么我对他们的专业精神印象深刻——整个工程组织都致力于拥有干净的提交历史,以至于他们强制将“压缩和合并”作为默认设置!
不幸的是,拥有干净的提交历史的好处就到此为止了 —— 历史可能是干净的,但我的日常工作需要比压缩提交所能提供的更多的背景信息。
根据定义,压缩提交会丢失信息。我喜欢把它想象成一个黑洞,信息会变成“霍金辐射”,在这个特定案例中,它是以开发人员的挫败感为单位来衡量的。
壁球的致命弱点
我很快就对压缩提交感到失望,原因很简单,我的工作 90% 是修复旧代码中的错误。当我使用Git Lens运行检查一行时git blame,我永远无法学到所有内容。
公司里几乎每个人都git blame 看到“{我的老板或同事} 提交的合并请求 #237”,没有其他信息。如果不手动查找,我甚至找不到 PR 的主题!真让人沮丧!
我会尽职尽责地调出原始 PR 和工单,试图弄清楚为什么这行代码会发生变化,但我却一无所知。你知道 PR 经常会一次更改数百行代码吗?是的……
我可以用一只手指数出我需要一次性撤销整个压缩提交的次数,而且这是一次戏剧性的 PR 回滚,导致我们的整个路线图被推迟了整整一个月。
其余时间,我会做我正常的工作,尝试在“你能在今天结束前把这个交给 QA 吗?”的期限内修复错误。当我检查一行代码时,我完全不知道它为什么被修改,因为压缩提交。
为什么我不喜欢压缩我的合并提交
瞧,我也想要一个干净的提交历史,但缺点是会严重影响日常工作。虽然知道“修复另一个错误时这个错误就坏了”很棒,但压缩提交并不能给我足够的信息。
假设我知道我的老板 18 个月前通过检查修改了某行代码git blame。此时,他肯定不知道为什么要修改它,即使他能抽出时间为我调查一下。
使用压缩提交后,我剩下的信息就更少了:我只能找出导致行被更改的错误修复或功能,而不能找出行被更改的实际原因,而这还不足以继续下去。
虽然如果每一行都有一两条代码注释那就太好了,但我们都知道大多数开发人员的工作方式并非如此——当我查看新的 React 代码库时,通常只会看到不到 1% 的代码实际上有任何注释。
我不知道代码更改的原因很简单;我的老板当时写下了原因(在提交消息中),但后来我们决定毫无理由地“压制”它。
解决方案是合并提交,而不是压缩提交
这里有一个非常简单的解决方案,它实际上是默认的——只是不要挤压。我想知道的不多,但它却带来了很大的不同:
重构:我的老板是否“重构”了这段代码,使其更具可读性或可维护性,希望不影响实际功能?
琐事:我的老板是否在做一些不应该影响生产代码的清理“琐事”,例如添加代码注释或测试?
修复:我的老板是否正在“修复”已发现的问题?如果是,这段代码具体存在什么问题?
feat:我的老板是否正在实施一项新功能,例如创建一个具有面向用户的功能的全新组件?
您是否意识到这些是常规提交(也称为“语义提交”),它们最适合与原子提交搭配使用?
我之所以对这家公司如此失望,是因为他们在提交信息方面的文化很好,但在 PR 方面的文化却很糟糕。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。