Git 的那些事

围绕日常 Git 实践的争论揭示了人们对一个健康代码库究竟需要多少结构和纪律存在深刻分歧。评论者争论提交信息的长度与内容、是否保留“凌乱”的中间提交还是进行 squash、如何处理失败测试和重构,以及何时适合 rebase 或 merge。技术细节之下,是一种更广泛的张力:一边是追求快速、低摩擦的变更,另一边是维护清晰、可靠的历史,以帮助审查、调试和长期维护。

代码审查与工作流

  • 一些团队采用“ship/show/ask”风格,由作者自行决定需要多少审查,从而让小而低风险的改动能够快速合并。
  • 也有人认为,审查者的选择应更多取决于谁真正理解受影响的代码,而不应只看作者的自信程度。
  • 有人提出先“乐观地”合并到 main,之后再审查;但这遭到反对:批评者认为这会削弱 main 的可靠性,移除审查所带来的社交压力,也让初级开发者失去在合并前通过反馈学习的机会。
  • 文档和测试常常拖慢 PR;建议包括把文档视为一等公民(没有文档的 PR 不可接受)、先写文档以澄清意图,或者由审查者先起草初始文档以暴露缺口。

提交信息与历史

  • 对“minor”/“fix”这类消息存在强烈分歧:有人认为在极小改动中可以接受;也有人坚持每个提交都必须表达意图,尤其是为了 blame/bisect 调试。
  • 许多人希望主题至少包含高层次上下文(“what”),有时还要带工单 ID;另一些人则认为最低要求应该是“why”,因为 diff 已经展示了“what”。
  • 关于 50 字符主题行规范的争论很大:有人认为这是由旧终端驱动的过时习惯;也有人为简短主题辩护,认为它们在 logblame 等工具里更便于快速浏览。强制限制 50 字符的工具被视为令人 раздражающим。
  • 是压缩提交还是保留细粒度提交:有人更喜欢 squash 以减少杂乱;另一些人认为你可以用 --first-parent 模拟“压缩视图”,而 squash 会破坏有用的历史。

测试、失败测试与 bisect

  • 先提交一个失败的测试,再提交修复,被称赞为低摩擦的 TDD,并有助于审查。
  • 批评者指出,如果失败测试进入 main,这会破坏 git bisect 和 CI 预期。
  • 另一个相关建议是调整断言以锁定当前错误行为(并加上 TODO),这遭到广泛批评;多人认为测试绝不应强制错误行为,而应标记为预期失败或直接移除。

重命名与历史跟踪

  • 有些人认为 Git 基于内容的重命名检测是失败的;他们希望有显式的移动元数据(对 git mv 进行稳健记录)。
  • 另一些人则为当前模型辩护,指出它能跨文件拆分/合并以及细粒度移动追踪历史,尽管并不完美;git blame -C 之类的标志可以提供帮助。
  • 引入显式移动元数据的提议引发了对复杂性、工具支持以及合并冲突的担忧。

行长度与工具约定

  • 行/主题长度限制(代码 80–120 字符、提交主题约 50–72 字符)被讨论为历史遗留与实际可读性的混合:并排 diff、小笔记本屏幕、视力老化。
  • 有人主张放宽甚至取消硬性限制,让工具自动换行;也有人强调更短的行更易阅读,而软性限制还能暴露过于复杂的表达式。

分支:merge vs rebase

  • merge 和 rebase 被视为不同的工具:rebase 用于共享功能分支和重写历史;merge 用于集成工作并保留原始提交。
  • 有人偏好 merge commit,因为它们是冲突解决发生的明确位置;也有人偏好 rebase,以避免充满“dragon”的 merge commit,并让 main 保持线性,便于 CI/bisect。