Jujutsu 的 jj absorb 怎么把修改自动归入最近改过对应行的提交?
【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj
你刚在 Jujutsu 仓库里堆了一串提交,又在 working copy 里随手改了几行,现在希望把这几行改动分别折回"最后修改过对应行的那一个提交"里,而不是再建一个补丁提交。在 Git 里要达到同样效果,需要给每个目标提交逐个执行git commit --fixup <ID>,再跑git rebase --autosquash;Jujutsu 用一条命令替代这个流程:jj absorb。它会自动拆分源修订里的改动,把每一处改动移到"对应行最近一次被修改的、最近的可变祖先提交"上,并把改动无法确定归入哪一个提交的行留在原地。
本文的任务就一件事:在已有提交栈上,把 working copy(或某个源修订)中的小修小补自动归并到栈中合适的提交,并验证结果。
jj absorb 的归并规则
根据 CLI reference 中jj absorb的说明,这条命令的行为可以拆成四条规则:
- 命令把源修订的改动拆开,每一处改动移动到最近的可变祖先(closest mutable ancestor)中对应行最后被修改的那个提交;
- 如果目标修订无法被唯一确定,该处改动留在源修订里,不会瞎猜;
- 如果源修订的所有改动都被吸走,且源修订没有描述,源修订会被 abandon;
- 命令造成的仓库变更可以用
jj op show -p复查。
jj absorb是 0.24.0 引入的命令(见 CHANGELOG),定位为"自动把当前提交的改动压入相关祖先提交"。docs/git-experts.md 一节 "jj absorbmakes it easier to update a patch stack" 也说明了它的典型场景:working copy 里做了小修小补,想把它并入栈里对应的提交,而不需要逐个手写 fixup。
准备条件:先有一串提交和一处小改动
命令的默认值已经把最常见的情况覆盖了:
jj absorb- 源修订(
-f/--from)默认是@,即当前 working copy 修订; - 目标范围(
-t/--into,别名to)默认是mutable(),即所有可变修订,且只会在源修订的祖先里找。
也就是说,只要你在@里改动了若干行,且这些行在提交栈里能被唯一地对应到某个祖先提交,直接运行jj absorb就能完成归并。
如果需要先复现这个场景,可以按 tutorial 里构建提交栈的方式做:用jj new -m逐个建提交,每个提交修改同一个文件,再在最后的 working copy 里对其中某一行做一次小修正。
执行步骤
基本用法:整栈吸收
在 working copy 里完成修改(文件会出现在@的 diff 中)后,直接运行:
jj absorb能归入栈中某个提交的行会被移走;不能唯一归类的行留在@中,此时@不会为空,也就不会被 abandon。
只处理部分文件
如果 working copy 里混了不想动的文件,用 FILESETS 参数限定路径。<FILESETS>的说明是"Move only changes to these paths (instead of all paths)":
jj absorb src/main.rs显式指定源和目标
默认参数不合适时用-f和-t指定:
jj absorb --from @ --into 'mutable() & description("B")'注意-t/--into只考虑源修订的祖先,写进去的非祖先修订不会生效。
交互式挑选 hunk
不想整个提交都被吸收时,用-i/--interactive打开 diff 编辑器,只勾选要吸收的 hunk;这些 hunk 随后可能被分配到多个祖先提交。--tool <NAME>用于换一个 diff 编辑器,并隐含--interactive:
jj absorb -i jj absorb --tool difftastic按 CHANGELOG 的说明,交互式选择适合"只想吸收提交的一部分、又不想先手动 split"的情况;未选中或无法唯一归类的 hunk 会留在源修订中。
验证结果
文档给出的复查方式是查看这次操作造成的 diff:
jj op show -p它会展示jj absorb对仓库做了什么修改,可以据此确认每一行改动落到了哪个提交上。再用jj log查看提交栈,确认:
- 源修订中能被吸收的行已经消失,对应祖先提交的描述/内容包含这些改动;
- 源修订如果变空且无描述,会被 abandon(这是 CHANGELOG 中记录的明确行为)。
已知限制与剩余改动
jj absorb不解决所有情况。docs/git-experts.md 明确指出的边界:
- 同一行被栈里多个提交改过:如果 working copy 改的那一行在栈中被多个提交修改过,该处改动不会被移动,需要你决定如何把剩余改动压入对应提交(例如用
jj squash手动处理)。 - 文件删除:
jj absorb可以在目标修订中添加了一个文件、而该文件被删除时,把"删除"压入对应的目标修订(CHANGELOG 记录的行为)。
换句话说,jj absorb负责把能唯一归类的行自动归位;归不进去的行和提交会保留在源修订里,留给你做最终判断,而不是静默丢弃。
更多参数细节(FILESETS 语法、--tool可用值等)可以直接参考 CLI reference 的jj absorb一节,或在仓库中运行jj help absorb获取更权威的输出——CLI reference 本身注明以jj help为准。
【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考