网易首页 > 网易号 > 正文 申请入驻

一个提交里塞了五处改动,怎么只拆出你要的那两处?

0
分享至

下午就要合一个 bug 修复,它偏偏和一处你想先吵一架的重构躺在同一个提交里。Agent 给这个提交起的名字叫Update checkout,动了五个文件。其中两个修的是客户今天就能看见的格式 bug,还配了测试;另外三个把写死的税率挪到接口后面,顺手把测试也重写了。这个提交只给你两个按钮:全要,或者全不要。


写代码的 agent 很容易走到这一步——任务说的是"清理 checkout",它一路上碰过的东西就全进了一个提交。放在以前,想把它拆开只能上交互式 rebase:标记edit、reset、分块重新暂存、提交两次、continue。

Git 2.54(2026 年 4 月发布)加了一条实验性命令专门干这个:git history split。你像用git add -p那样挑 hunk,Git 把它们写进一个新的父提交,所有建在其上的分支被移到重写后的历史上。没有待办清单,也不会卡在 rebase 进行中。

下面用一个一次性仓库复现:造一个 agent 风格的巨型提交,把它拆开,再用reword改消息、用fixup修补一个旧提交。

先把烂摊子故意造出来

split 和 reword 需要 Git 2.54 或更新,fixup 需要 2.55。用git --version确认。文件是几个小 PHP 类,但你不需要装 PHP 或 PHPUnit——Git 只认文本。

先在 main 上放起点。Money::format有个真 bug:1205 分输出成 12.5,因为分位没有补零。初始化仓库、建好 src 和 tests 目录、提交一个 "Initial checkout"。

然后扮演 agent。在任务分支上,一个提交同时修了补零、加了回归测试、抽出TaxRate接口、让 Checkout 依赖它、重写 Checkout 测试。接着第二个更小的提交落在上面,消息什么也没说。跑git show --stat HEAD~1,问题一目了然:五个文件、一条消息、两件不相干的事。

动手重写之前,先打个标签记住起点:git tag before-split。用标签,别用分支。默认情况下 git history 会移动所有从被重写提交派生出来的本地分支,放在顶端的备份分支会被一起挪走;而标签会留在你放它的地方。

用 git history split 拆开

把 split 指向那个巨型提交。它在顶端下面一个,正是以前需要 rebase 的场景:git history split HEAD~1。

Git 按路径顺序遍历这个提交的 hunk,逐个询问,按键和git add -p一样。y把 hunk 移进新提交,n留在原地,d连同该文件剩下的部分一起留下。对这个提交来说,选择是:

  • src/Checkout.php:d
  • src/Money.php:y
  • src/TaxRate.php:d
  • tests/CheckoutTest.php:d
  • tests/MoneyTest.php:y

然后编辑器会打开两次,两次都从 agent 的原始消息开始。第一次是给拆出来的那个提交——你挑中的 hunk,它成为新的父提交,写Fix zero-padding in Money::format。第二次是给留在原提交里的部分,写Extract TaxRate port from Checkout。作者身份保留原提交的作者。

如果两件事本来就分在不同文件里,用 pathspec 就能省掉按 d 的功夫,只有匹配的文件会被拿出来,其余留在原提交:git history split HEAD~1 -- src/Money.php tests/MoneyTest.php。

注意你没拆出去的东西:Checkout 测试的重写。旧测试调用new Checkout()不带参数,构造函数一旦需要 TaxRate 就会立刻崩。一个同时装着重构和旧测试的提交会让测试套件变红。重写后的测试要跟着逼它改的那处改动走。按"评审者会一起通过"的标准给 hunk 分组。

一个提交进去,两个提交出来:修复成为父提交,重构坐在它上面。接着确认什么都没丢:git log --oneline main..agent/checkout和git diff before-split agent/checkout。日志显示三个提交,原来是两个;diff 应该什么都不打印。split 只是重新分配 hunk,顶端代码不变。

第一次在真实分支上做?加上--dry-run。Git 会写出新对象但不移动任何 ref,并按git update-ref能读的格式打印 ref 更新。只想移动当前分支,就传--update-refs=head。

不用 rebase 的 reword 和 fixup

那个 "more fixes" 提交还在顶上。git history reword会在编辑器里打开任意提交的消息并就地重写,不碰工作区和索引,甚至在裸仓库里也能用。把它改成Document the TaxRate dependency in README。对 HEAD 来说,git commit --amend效果一样;reword 是给三四个提交之前、amend 够不着的地方用的。

然后评审发现一个缺口:修复没有覆盖金额小于 1.00 的测试。Git 2.55 加了git history fixup,把你暂存的改动折进更早的提交,再把后面的重放上去:git history fixup 'agent/checkout^{/Fix zero}'。这个^{/Fix zero}后缀会找到分支上消息匹配的最新提交。修复提交保留自己的消息和作者;想改消息就加--reedit-message。Git 2.56 加了git history drop,删掉一个提交并把它的后代重放到其父提交上。

如果 agent/checkout 已经推过,这些和任何 rebase 一样都是重写:用git push --force-with-lease推。想整个丢掉这次练习,在分支上执行git reset --hard before-split就回去了。

git history 拒绝做的事

手册页对限制写得很直白,而且大多是有意为之:

  • 不碰含合并提交的历史,那种情况用git rebase --rebase-merges
  • 任何会以合并冲突收尾的操作都会被拒绝。历史重写不该把你留在半成品状态,所以它直接中止,而不是中途停下。
  • Git 钩子"在当前时间点"不会运行。如果 commit-msg 钩子检查消息格式,它看不到你在 split 期间输入的消息。
  • 源码调用 hunk 选择器时禁用了编辑,所以不提供e。当一处修复和一处重构共享同一个 hunk,试试s把它切成更小的 hunk,或者退回git rebase -i

全选或全不选也是无效的,因为两个提交里会有一个是空的。截至 2.56,整条命令仍标记为实验性,并警告行为可能变化。要重排一段范围或把它移到新基底上,git rebase仍是那个工具;git history 一次只覆盖一处有针对性的编辑。

挑哪些 hunk 该在一起,是拆分里最难的部分,而 agent 的单个提交不会告诉你它按什么顺序干活。如果 agent 在一个回合里做了补零修复、下一个回合做重构,按回合看就能在你敲 pathspec 之前把路径给你。要是在 agent 提交之前就打开评审台,还能逐个文件暂存和提交,那就没什么可拆的了。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
男子打羽毛球时不慎摔倒,裤兜里的手机突然爆燃,致其二级重度烧伤,知情人:手机刚买两个月

男子打羽毛球时不慎摔倒,裤兜里的手机突然爆燃,致其二级重度烧伤,知情人:手机刚买两个月

第一财经资讯
2026-10-18 14:40:44
嘲讽苍井空的大V,何必呢!

嘲讽苍井空的大V,何必呢!

新动察
2026-10-19 12:17:44
带领8名CBA弃将,险些掀翻三冠王,球迷:让他取代郭士强当国帅

带领8名CBA弃将,险些掀翻三冠王,球迷:让他取代郭士强当国帅

南海浪花
2026-10-19 11:49:35
终于判了!疫苗女王无期徒刑,被罚91亿,但那些接种家庭怎么办?

终于判了!疫苗女王无期徒刑,被罚91亿,但那些接种家庭怎么办?

哄动一时啊
2026-10-18 09:57:57
印度突发踩踏事故,莫迪发文哀悼

印度突发踩踏事故,莫迪发文哀悼

参考消息
2026-10-18 15:54:07
三季度亏了521万,“浙江早餐大王”关闭132家店

三季度亏了521万,“浙江早餐大王”关闭132家店

都市快报橙柿互动
2026-10-19 00:34:21
中国农大食堂上新蛋糕外形酷似蛤蟆走红,每块售价9.9元,学生:很多人抢购,就是抹茶口味

中国农大食堂上新蛋糕外形酷似蛤蟆走红,每块售价9.9元,学生:很多人抢购,就是抹茶口味

极目新闻
2026-10-19 13:10:11
“通便冠军”来了!隔天吃一次,清热去火,缓解便秘一身轻松!

“通便冠军”来了!隔天吃一次,清热去火,缓解便秘一身轻松!

荷兰豆爱健康
2026-10-19 03:50:52
164比24狂胜140分!中国篮坛又现夸张比分:单节0分被钉耻辱柱?

164比24狂胜140分!中国篮坛又现夸张比分:单节0分被钉耻辱柱?

篮球快餐车
2026-10-19 02:10:25
做完手术人就废了,这5种手术不需要做,别让无知害了自己!

做完手术人就废了,这5种手术不需要做,别让无知害了自己!

健身狂人
2026-10-08 13:49:26
18分12助12板!正负值高达+27,都说你底薪抱团,可你又混成大腿

18分12助12板!正负值高达+27,都说你底薪抱团,可你又混成大腿

月亮的麦片
2026-10-19 11:15:45
到处都在过紧日子,为什么税务招了近七成的国考编制?

到处都在过紧日子,为什么税务招了近七成的国考编制?

大何日拱一卒
2026-10-18 18:19:37
形势挺严重了!这5个行业,工资都发不下来了!

形势挺严重了!这5个行业,工资都发不下来了!

职场资深秘书
2026-10-16 19:47:24
交易浓眉?NBA要被颠覆了!……

交易浓眉?NBA要被颠覆了!……

体育新角度
2026-10-18 21:15:21
“红果短剧降智”热议背后,平台日活1.68亿,已超“爱优腾芒”四家总和

“红果短剧降智”热议背后,平台日活1.68亿,已超“爱优腾芒”四家总和

上观新闻
2026-10-19 08:21:51
刚刚,Anthropic官宣!要捐3200亿分给普通人

刚刚,Anthropic官宣!要捐3200亿分给普通人

新智元
2026-10-19 08:12:04
又一个许利民?前三节3次使用单外援,直接葬送胜利,球迷怒问:使用双外有罪吗?

又一个许利民?前三节3次使用单外援,直接葬送胜利,球迷怒问:使用双外有罪吗?

南海浪花
2026-10-19 07:07:28
AI短剧席卷海外,美媒批评是垃圾,8亿月活强势反击

AI短剧席卷海外,美媒批评是垃圾,8亿月活强势反击

娱乐剧汇
2026-10-18 22:09:03
重要发布会,就在今日

重要发布会,就在今日

中国基金报
2026-10-19 06:43:46
疯狂小杨哥新号粉丝被清零,大杨哥新号粉丝跌至2.6万!此前注销亿级旧账号

疯狂小杨哥新号粉丝被清零,大杨哥新号粉丝跌至2.6万!此前注销亿级旧账号

上观新闻
2026-10-19 08:52:23
2026-10-19 16:36:49
Ping值焦虑
Ping值焦虑
有态度网友ytd
210文章数 109关注度
往期回顾 全部

科技要闻

王晟:近千亿资金涌入后 具身智能开始退烧

头条要闻

男子称入狱20多天被贷款、转走超38万 报警1年多无进展

头条要闻

男子称入狱20多天被贷款、转走超38万 报警1年多无进展

体育要闻

从NBA退役10年后,他真去警局上班了

娱乐要闻

奚梦瑶回应重返维密:还是很开心的

财经要闻

黄奇帆之子往事:从广微系到魏桥的跳跃

汽车要闻

不知道二代海鸥多好玩? 上赛道跑两圈 很过瘾的

态度原创

艺术
手机
旅游
教育
公开课

艺术要闻

缅怀 | 著名油画家 宋惠民先生逝世,享年89岁

手机要闻

iQOO Neo12「争锋」图赏:赤金弧光流转,更强立体视觉

旅游要闻

西宁下南关:千年古道上的烟火街巷

教育要闻

新华视点|校园焕彩 文脉新生

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版