Git 是目前使用最广泛的版本控制工具,它把代码的每一次修改都记录下来,让多人协作开发时不会互相覆盖,随时可以回退。2026 年 4 月发布的 Git 2.54,由 137 位贡献者共同完成,其中 66 人是第一次参与贡献。这个版本最值得关注的变化有三个:新增实验命令 git history(让日常改写提交历史更简单)、钩子可以直接写进配置文件(跨仓库共享钩子不再靠复制脚本)、仓库维护的默认策略换成更省时的 geometric 打包。

git history:专为「小改动」设计的提交历史改写命令

改写提交历史是 Git 里的常见需求。比如发现三条提交之前的一条提交,说明文字里有错别字想改掉,或者想把一个提交拆成两个。过去这类操作要用 git rebase -i(交互式变基,把一段提交重新排列组合的命令),它功能强大,但要打开待办清单、标记要修改的提交、再处理可能出现的冲突,为一处小改动动用整套流程显得笨重。

Git 2.54 新增的实验命令 git history 就是为这类简单场景设计的。它目前支持两个操作:

  • git history reword <commit>:打开编辑器直接修改指定提交的说明文字,改完自动更新所有基于它的分支。全程不修改工作区(当前看到的文件目录)里的文件,也不动暂存区(提交前临时存放待提交改动的位置);还能在裸仓库(bare repository,没有工作目录、只用来存放历史的服务端仓库)里运行。
  • git history split <commit>:把一个提交拆成两个,交互方式与 git add -p(逐个选择代码块暂存的命令)相同,选中哪些代码块归入新的提交即可。

git history 的定位是「有明确目标的非交互式改写」:它不支持包含合并提交(merge commit,把两个分支的历史合并到一起的提交)的历史,遇到会产生冲突的操作会直接拒绝。它基于 git replay 的核心机制构建,天然适合脚本化和自动化。需要留意的是它仍处于实验阶段,接口未来可能调整。

钩子写进配置文件:一处定义,处处生效

钩子(hook)是 Git 在特定动作前后自动运行的脚本,最常见的用途是提交前自动跑一遍代码检查(linter)。过去一个钩子只能以脚本文件形式放在仓库的 .git/hooks 目录,想在多个仓库统一启用同一个钩子,只能把脚本复制进每个仓库;或者用 core.hooksPath 指向共享目录,但这样所有仓库的钩子完全一样,无法混搭。

Git 2.54 允许在 Git 配置文件里定义钩子:

[hook "linter"] event = pre-commit command = ~/bin/linter --cpp20

这段配置的意思是:在 pre-commit(提交前)这个时机,运行 ~/bin/linter --cpp20 这条命令。配置可以放在用户级 ~/.gitconfig、系统级 /etc/gitconfig 或某个仓库的本地配置里,一处定义、全局生效。

同一事件可以配置多个钩子,Git 按配置出现的顺序依次执行;传统的脚本钩子仍然有效,排在最后执行。用 git hook list <event> 可以查看当前配置了哪些钩子及其来源。想临时停用某个钩子,把 hook.<name>.enabled 设为 false 即可,不必删掉配置——系统级配置里定义的钩子,某个仓库想豁免时用这个开关很方便。

geometric 打包成为仓库维护的默认策略

Git 在后台会把代码历史压缩成打包文件(packfile)来节省空间,日常操作会产生许多小打包文件,需要定期整理。过去用 gc(垃圾回收,把打包文件重新整理压缩的命令)一次性全部重打,仓库越大越耗时。

Git 2.52 引入的 geometric 策略(按数量级渐进合并打包文件的维护策略)只做增量合并,多数时候不用全量重打。到 2.54,geometric 成为 git maintenance run 的默认策略:如果你没有在配置里指定策略,现在手动跑 git maintenance run(按计划执行仓库维护的命令)会默认走 geometric,维护更快,commit-graph(提交图缓存)、reflog(引用日志)等辅助数据也会同步更新。原本显式配置了 maintenance.strategy = gc 的仓库行为不变。

其他值得关注的变化

  • HTTP 传输支持 429 限流重试:服务器返回「请求过多」时不再直接失败,会按 Retry-After 头或 http.retryAfter / http.maxRetries / http.maxRetryTime 配置重试。
  • git log -L(追踪文件里某段代码的行修改历史)接入标准 diff 对比管线,首次支持 -S / -G 按内容变化搜索。
  • git rebase 新增 --trailer 选项,一条命令给重放的提交批量追加签名尾注(trailer)。
  • git add -p 交互改进:J / K 键浏览代码块时显示之前是否已接受或跳过;新增 --no-auto-advance,操作完一个文件后不自动跳到下一个。
  • git replay 实验命令继续成熟:默认原子更新引用、新增 --revert 模式、可丢弃重放中变空的提交。
  • 用已过期 GPG 密钥(用于给提交签名的加密密钥)签名的提交,签名本身有效,界面不再误显示红色告警。
  • git blame(逐行查看代码是哪个提交改的)支持 --diff-algorithm,可选直方图 / 耐心 / 最小 / Myers 四种差异算法。
  • 别名(alias,给 Git 命令起的快捷方式)支持非 ASCII 字符,比如 [alias "hämta"] command = fetch。
  • git backfill(部分克隆中按需补下载历史内容的实验命令)支持指定版本范围和路径通配。

升级后能得到什么

Git 2.54 没有改变 Git 的基本用法,升级后最直接的体感是:仓库维护变快、钩子管理变省事。如果你常做「改个提交信息、拆个提交」这类小事,值得试用 git history;它是实验命令,接口还会演进,但方向是明确的——让简单的事不再需要复杂的交互式变基。