jj 入門
原文由 Ellie Huxtable 于 發布,訂閱此部落格
過去幾週我一直在用 jj!這不是我第一次嘗試它,但卻是第一次真正上手並持續使用。
多年來,我的 git 工作流程都是「改完東西,然後 git commit --amend --no-edit && git push --force-with-lease」,而且在同一個分支上。這讓我的修改能以非常低的延遲保持在遠端的最新狀態。PR 通常只有少數幾個 commit,通常只有一個,我也會盡量讓它們保持精簡。
自從開始跟 agent 一起工作後,我發現自己切換分支的頻率變高了很多。因此,我要嘛得用 git stash,要嘛得隨便弄個有點蠢的 wip commit,才能避免不同修改互相干擾。
有請我們的新英雄,jj!這裡的模型有點不一樣。我不會寫什麼長篇大論的手冊,因為網路上已經有很多了,而且都比我隨便塞進筆記裡的東西好得多。
簡單來說,最吸引我的地方在於,我的修改永遠都是已提交的狀態。每一次編輯都會自動 amend 到最新的 commit,而 push 就會覆蓋遠端(或者用 jj 的說法,就是把它「橫向移動」)。
編輯一個 change 非常輕鬆,不需要搞那套 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
開始一個新的 change
在開始工作之前,你應該先建立一個 change。接下來你做的所有編輯都會放在這裡
jj new main這會在 main(也就是帶有 main 書籤的那個 commit)之上建立你的 commit(剛開始接觸時,change 跟 commit 的差別真的很讓人困惑)。如果你想建立一個以當前 change 為父節點的新 change,只要執行 jj new 就好。
為 change 加上說明
你可能已經習慣先把一些修改加到 staging area,再用一段訊息把它們 commit 起來。不過在 jj 裡,你的修改已經自動被加入了。但你的 change 可能還沒有 description!(就像 commit message 一樣)
jj describe -m 'hello i am a message'你也可以在建立 change 的當下就幫它加上說明:
jj new -m "hello i am a message"把 commit 推送到新分支
如果你正在某個 change 上,對它很滿意,想把它推到 GitHub 上讓某個 agent 來吐槽你(Claude 寫)的程式碼呢?
很簡單。
jj git push -c @也就是「用 git 來推送當前的 commit」。它會自動建立一個分支並推送到遠端。你其實可以在修改過程中一再執行這個指令,它會自動把 jj 的魔法轉譯成 git 的 amend 和 force push。
不過我還是很期待 jj 能擁有自己的協定和託管平台。
編輯 commit
如果想跳回去編輯某個已有的 change?很簡單
jj edit <change-id>對我來說,從這裡開始就真的感覺到它的強大,同時也是我原本想套用的心智模型開始瓦解的地方。不用再去瞎搞什麼 checkout、rebase 之類的東西。
jj 同時有 change 和 commit。如果回想一下,它是不斷演進一個 commit,而不是有個 staging area,那麼我們可以把 change 想成是穩定的 ID,而 commit ID 則是每次編輯都會跟著變的那個
復原操作
在 jj 裡你做的幾乎任何事都會被記錄在 op log 裡。如果做了什麼結果搞砸了?jj undo 來救你。
更多 git 相關操作
jj 目前在很大程度上還是寄生在 git 之上。他們已經讓轉換現有 repo 變得很簡單,也能輕鬆跟 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)」,也就是你可以附加到某個 commit 上的字串。當你推送一個 change 時,它會自動幫你建立一個書籤——例如 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我目前最感到困擾的是,建立新 change 時書籤並不會跟著移動。
節錄自詞彙表:
跟 Git 不同,jj 沒有「當前書籤」的概念;當你建立新的 commit 時,書籤不會跟著移動。如果 commit 被重寫,書籤才會自動跟著它移動。
之後我會再另外寫一篇關於 rebase、編輯和其他有趣玩法的東西
註:用 Vim 寫這篇超級困擾,因為我把 jj 綁定成 <esc> 了。
隨機一篇部落格
留言
登入後參與討論