GitHub 和 GitLab 上的并行需求让分支管理成了开发者的日常噩梦——频繁的 rebase 操作稍有不慎就会把代码树搞成一团乱麻。不少人转向 jj 这样的替代工具寻找出路,但折腾几个月后又乖乖回到 git。现在有个更省心的选项:Git 2.54 起内置的 experimental 命令 git history,已经能提供 jj 吹捧的部分核心能力,而且装完 git 就能用。
为什么需要它
在多人协作的项目里,给两周前的提交打补丁、再让所有下游分支跟上,这事儿用传统命令做起来很麻烦:git commit --fixup 配合 --autosquash 只能处理当前分支,想要同步到其他分支得再折腾 rebase --update-refs。更别提 rebase -i 这种交互式操作,稍有冲突就可能留下半成品状态,让人提心吊胆。
jj 作为替代方案确实解决了这些痛点,但它要求你彻底换掉使用习惯。而 git history 不一样——它就嵌在 git 里,学习成本几乎为零。
三个子命令能干啥
fixup:把暂存区的改动合并进任意旧提交,同时自动重写所有下游分支。操作前你只需 git add 正常暂存,运行 git history fixup <目标提交>,它就会原子化地完成合并和重基。关键特性是「原子性」——它会拒绝任何可能产生冲突的操作,保证不会把代码树留在半损坏状态。
reword:修改旧提交的消息。和 fixup 一样会自动重建整个栈,但只动消息不动文件,所以不会触发任何暂存区或工作树的变化。这功能对付「提交时没想到后来改了方向」的情况特别有用。
split:把一个臃肿的提交拆成两个。它会逐块(hunk)展示原提交的 diff,你选哪些进第一个新提交,剩下的自动归到第二个。对比 git rebase -i 那套繁琐操作,这直观得多。
需要注意的是,三个命令目前都不支持合并提交(merge commits),这是个明显局限。不过文档暗示未来可能会放开这个限制。
值不值得迁移
git history 还没有 jj 的操作日志和 easy undo,也没有处理冲突状态的能力。但它已经覆盖了很多让开发者心动的场景,而且完全不用装任何东西。如果你不想折腾工具链切换,这套组合值得先用起来。
编注:信源为技术博客,材料详细演示三个子命令的操作流程与对比,未涉及性能基准或企业采用情况。