开始使用 jj
原文由 Ellie Huxtable 于 发布,订阅该博客
过去几周我一直在用 jj!这不是我第一次尝试它,但却是第一次真正坚持用下来。
多年来,我的 git 工作流一直是在分支上“改完就 git commit --amend --no-edit && git push --force-with-lease”。这样我的改动能以极低的延迟同步到远程。PR 很少会包含很多个提交,通常就只有一个,我也会尽量让它们保持精简。
自从和 agent 一起工作以来,我发现自己切换分支的频率高了很多。因此,我要么得用 git stash,要么就得提交一个无意义的 wip 提交,来避免不同改动互相干扰。
于是我们的新主角 jj 登场了!它的模型有些不一样。我就不写一份大而全的手册了,因为网上已经有很多,而且都比我随手记的这些要好得多。
简单来说,最吸引我的一点是,改动始终处于已提交的状态。每次编辑都会自动修改最近的一次提交,而推送则会覆盖远程(或者用 jj 的话说,把它“平移”)。
编辑某个变更非常轻松,不用再折腾 checkout / rebase 那一套。感觉就像有人把我喜欢的 git 工作流直接做成了一个工具。真不知道我为什么花了这么久才想明白这点。
说到底这也只是随手记录的想法。之后学到更多东西,我大概还会再发一些笔记。
工作流
发起一次改动时,我的工作流是这样的:
jj new main
<do some coding>
jj describe -m 'feat: something really cool'
jj git push -c @搞定。合并 PR,然后重复。
在 jj 里,我们更常说 change(变更)而不是 commit(提交)。一个 change 就是一个在不断演进的 commit。而 “@” 指的就是当前的 change
开始一次新的变更
在开始工作之前,你应该先创建一个变更。接下来你所有的编辑都会归到这里:
jj new main这会在 main(也就是带有 main 书签的那个提交)之上创建你的提交(刚接触时,change 和 commit 的区别确实让人困惑)。如果你想在当前变更之下再创建一个子变更,只需运行 jj new。
为变更添加描述
你可能已经习惯先把改动加到暂存区,再用一条提交信息提交。但在 jj 里,你的改动本身就已经被添加好了。只是你的变更可能还没有描述信息!(就相当于提交信息)
jj describe -m 'hello i am a message'你也可以在创建变更时就直接加上描述:
jj new -m "hello i am a message"把提交推送到新分支
如果你正在某个变更上,对它已经满意,想把它推到 GitHub 上让某个 agent 来吐槽一下你的(Claude 写的)代码呢?
很简单。
jj git push -c @也就是“用 git 推送当前提交”。它会自动创建一个分支并推送到远程。实际上,你可以在持续修改的过程中反复执行这条命令,它会自动把 jj 的魔法转换成 git 的 amend 和 force push。
不过,我还是很期待 jj 能拥有自己的协议和托管平台。
编辑提交
想跳回去编辑某个已有的变更?很简单:
jj edit <change-id>从这里开始,我才真正感觉到它的强大,同时我原本试图套用的那套心智模型也开始不管用了。完全不用去折腾什么 checkout、rebase 之类的操作。
jj 同时有 change 和 commit。如果回想一下,它是没有暂存区、而是持续演进同一个 commit 的,那么就可以把 change 理解为稳定的 ID,而 commit ID 则是每次编辑都会变化的那个
撤销操作
在 jj 里,你做的几乎所有操作都会被记录在操作日志里。如果搞砸了?jj undo 来救场。
更多 git 相关操作
jj 目前很大程度上还是构建在 git 之上的。他们已经让现有仓库的转换变得很容易,也能很好地与 GitHub 集成:
# Create a jj repo inside of a git repo
jj git init
# Fetch from the remote (github etc)
jj git fetch
# Push
jj git push
# Clone
jj git clone那分支去哪了
没有分支!至少不是你习惯的那种。jj 用的是“书签(bookmark)”,也就是你可以附加到某个提交上的一串字符串。当你推送一个变更时,它会自动为你创建一个书签——比如 push-refrefref
# bookmark the current change with a name
jj bookmark create <name>
# move a bookmark to a new commit
jj bookmark set <name> -r <commit>
# other things exist just use --help让我最头疼的一点是,创建新变更时,书签并不会跟着移动。
用术语表里的话来说:
与 Git 不同,这里没有“当前书签”的概念;创建新提交时,书签不会随之移动。但如果提交被重写,书签会自动跟着走。
关于变基、编辑和其他好玩的东西,我以后再另写一篇。
备注:在 Vim 里写这篇文章真的很烦,因为我把 jj 绑定到了 <esc>。
随机一篇博客
评论
登录后参与讨论