Hacker News 中文摘要

RSS订阅

预提交钩子已损坏 -- Pre-commit hooks are broken

文章摘要

文章指出pre-commit钩子存在根本性缺陷,作者通过一个Rust项目示例说明,即使添加了格式化检查的pre-commit钩子,开发者仍可能通过绕过钩子提交不符合规范的代码,表明这种机制无法真正保证代码质量。

文章总结

标题:预提交钩子的根本性缺陷

作者:jyn
发布日期:2025年12月26日
标签:Git、工作流、开发工具

核心观点: 预提交钩子(pre-commit hooks)存在根本性设计缺陷,建议改用推送前钩子(pre-push hooks)。

主要问题: 1. 工作树与索引不一致
- 预提交钩子检查的是工作树文件,而非暂存区(index)内容,导致可能漏检未暂存的修改。 - 示例:Rust代码格式化后未执行git add,钩子无法捕获问题。

  1. 变基操作中的灾难

    • 交互式变基(rebase -i)时钩子会意外触发
    • 当变基包含不符合当前规范的旧提交时,会导致操作失败
    • 必须使用--no-verify跳过检查才能完成操作
  2. 协作场景的局限性

    • 无法强制他人使用钩子(可通过--no-verify绕过)
    • 旧分支可能使用过时的检查标准
    • 合并冲突时钩子可能干扰解决过程

解决方案: 推荐使用pre-push钩子替代,其优势包括: - 在推送前统一检查多个提交 - 避免中断开发流程(如git stash或WIP提交) - 减少对变基/合并等操作的影响

例外情况: 仅凭证检查值得使用预提交钩子,因为敏感信息一旦提交就难以彻底清除。

最佳实践建议: 1. 始终对索引(而非工作树)进行检查 2. 只包含快速可靠的检查(避免网络请求或耗时操作) 3. 保持静默输出,避免干扰其他命令 4. 不要自动安装钩子,应提供手动设置文档

工具局限: 现有框架(如pre-commit.com/lint-staged)无法根本解决问题: - --keep-index会修改Git状态 - 仍无法处理变基场景 - 可能错误修改当前提交

开发者应结合git-absorbgit-revise等工具在推送前整理提交历史。

(注:原文中的代码示例和具体错误场景已简化为要点说明,保留了技术细节但删减了重复的调试过程)

评论总结

以下是评论内容的总结:

支持预提交钩子的观点: 1. 认为预提交钩子能提高效率,建议作为可选工具使用 - "put what you want in an optional pre-push hook... your fussiest developers will be happier" (nrclark) - "they save dev cycles back-and-forth with CI more than they hurt" (odie5533)

  1. 推荐使用pre-commit框架等工具简化流程
    • "The pre-commit framework abstracts all these issues away" (Dunedan)
    • "pre-commit is a really good way to share check definitions between local development and CI" (andrewaylett)

反对预提交钩子的观点: 1. 认为会干扰开发流程,建议仅通过CI检查 - "don't even run pre-push hooks. Just run the checks in CI" (tkzed49) - "What I do when the code is on my side of the line isn't your business" (jghn)

  1. 指出技术局限性
    • "they become stateful or depend on external context... start being a source of friction" (Simplita)
    • "git filter is made for that... Pre-commit is not for formatting your code" (PunchyHamster)

改进建议: 1. 保持钩子简单快速 - "pre-commit hooks should be pure functions" (nine_k) - "aim to have the hooks complete in under 1 second" (odie5533)

  1. 提供灵活的工作流

    • "allow the user to stage+commit new changes" (a_t48)
    • "jj fix is a more refined way of ensuring formatting in commits" (lemonlime227)
  2. 文档和自动化平衡

    • "add docs for how to set it up manually" (PunchyHamster)
    • "DO set it up automatically... don't want new developer to spend half a day setting up" (PunchyHamster)