Jj 基礎練習:Squash vs Edit Workflow

Jj 基礎練習:Squash vs Edit Workflow

部分內容由 LLM 生成,尚未經過人工驗證。

本文記錄 Jj 版本控制的實際練習過程,重點對比兩種主要工作流:Squash WorkflowEdit Workflow

兩種工作流概述

Edit Workflow

核心概念:直接切換到目標 commit 進行編輯。

jj edit <revision>  # 切換 working copy 到指定 commit
# 進行修改...
# 修改會自動 amend 到該 commit

特點

  • Working copy (@) 直接移動到要編輯的 commit
  • 修改會自動併入當前 commit(auto-amend)
  • 適合在不同 commit 間快速切換

Squash Workflow

核心概念:建立新 change 進行修改,再將修改合併到 parent。

jj new              # 建立新 change (working copy 移到新 change)
# 進行修改...
jj squash           # 將當前 change 的修改合併到 parent

特點

  • 每次 jj new 都建立新的 change
  • Working copy 始終在最新的 change 上
  • 使用 jj squash 將修改向下合併

實際練習過程

練習環境: D:\..\..\vcs-practice 練習時間: 2026-02-12

環境設定

初始化 Jj repository 並設定用戶資訊:

jj git init
jj config set --user user.name "Tester"
jj config set --user user.email "12345678+Tester@users.noreply.github.com"
jj describe -m "hello world"
jj describe 用於設定或修改 change 的 description(類似 Git commit message)。

Squash Workflow 練習

步驟 1: 建立新 change

jj new
jj describe -m "print goodbye as well as hello"

此時 repository 狀態:

@  mzvwutvl  print goodbye as well as hello  # <- working copy
○  qpvuntsm  hello world

步驟 2: 修改檔案並建立下一個 change

修改 program.txt 後:

jj new

此時會建立新的 change,前一個 change 的修改已被保存:

@  yostqsxw  (empty)
○  mzvwutvl  print goodbye as well as hello  # <- 修改已保存
○  qpvuntsm  hello world

步驟 3: 使用 squash 合併

jj squash

將當前 change (yostqsxw) 的修改合併到 parent (mzvwutvl)。

jj squash 會將當前 change 的內容合併到 parent,當前 change 會被移除(如果沒有其他內容)。

Edit Workflow 練習

步驟 1: 建立新 commit

jj new -m "only print hello world"

使用 -m 參數可在建立 change 時直接設定 description。

步驟 2: 插入 commit 到特定位置

jj new -B @ -m "add more comments"

-B @ 表示在當前 change (@) 之前插入新 change:

@  zsuskuln  add more comments        # <- 新建立的 change
○  royxmykx  only print hello world   # <- 原本的 @
○  qpvuntsm  hello world
-B (before) 和 -A (after) 可用於控制新 change 的插入位置。

步驟 3: 移除不需要的 commit

jj abandon qr

使用 jj abandon 移除指定的 change(可使用 change ID 前綴)。

jj abandon 會移除 change,但修改會保留在 child change 中(如果有的話)。

步驟 4: 切換到不同 commit 進行編輯

jj edit q

切換 working copy 到 change ID 為 q 開頭的 commit。此時:

  • Working copy (@) 移動到該 commit
  • 所有修改會自動 amend 到該 commit

步驟 5: 查看狀態

jj log   # 查看 commit 歷史
jj st    # 查看工作目錄狀態

工作流選擇指南

多 AI Agent 並行開發 → Edit Workflow

適用情境:同一目錄有多個 AI agent 同時工作在不同的 ticket/feature。

# Agent A 工作在 feature-1
jj edit feature-1-branch

# Agent B 切換到 feature-2
jj edit feature-2-branch

# 快速在不同 ticket 間切換
jj edit ticket-123

優勢

  • 無需建立多個 working copy(不像 Git worktree)
  • 切換速度快(只移動 working copy 指標)
  • 每個 change 保持獨立,容易管理

整理 AI 輸出 → Squash Workflow

適用情境:AI 產生的 commit 歷史混亂,需要整理成有意義的 change。

# 建立實驗性修改
jj new -m "experiment: try approach A"
# ... 修改 ...

jj new -m "experiment: try approach B"
# ... 修改 ...

# 決定保留哪些修改並合併
jj squash  # 合併到 parent

優勢

  • 可以安全地實驗(隨時可以 abandon)
  • 整理前可以先建立多個小 change
  • 使用 jj squash 逐步組織成有意義的 commit

實驗性修改 → Squash Workflow

jj new -m "try optimization idea"
# ... 實驗 ...

# 如果效果不好
jj abandon @

# 如果效果好
jj squash  # 合併到 main change

在不同 ticket 間切換 → Edit Workflow

jj edit ticket-456   # 切換到 ticket-456
# ... 工作一陣子 ...

jj edit ticket-789   # 切換到另一個 ticket
# ... 工作一陣子 ...

jj edit ticket-456   # 回到 ticket-456 繼續工作

關鍵指令速查

基礎操作

指令說明工作流
jj new建立新 change(working copy 移動到新 change)Squash
jj new -m "msg"建立新 change 並設定 descriptionBoth
jj new -B @在當前 change 之前插入新 changeEdit
jj new -A @在當前 change 之後建立新 changeBoth
jj edit <rev>切換 working copy 到指定 changeEdit
jj describe -m "msg"設定或修改 change 的 descriptionBoth

Change 管理

指令說明工作流
jj squash將當前 change 的修改合併到 parentSquash
jj squash -r <rev>將指定 change 的修改合併到 parentSquash
jj abandon <rev>移除指定 change(修改保留在 child)Both
jj abandon @移除當前 changeBoth

查看狀態

指令說明
jj log查看 commit 歷史圖
jj st查看工作目錄狀態
jj diff查看當前修改
jj show <rev>查看指定 change 的內容

常用符號

符號說明
@當前 working copy(當前所在的 change)
@-當前 change 的 parent
@--當前 change 的 grandparent
<change-id>完整或部分 change ID(如 kmkuslswkm

核心概念

Working Copy (@)

  • Jj 的 working copy 是一個指標,指向當前正在編輯的 change
  • jj new 會移動 working copy 到新建立的 change
  • jj edit 會移動 working copy 到指定的 change

Auto-amend

  • 在 Edit Workflow 中,修改會自動 amend 到當前 change
  • 不需要手動執行 jj commit(Jj 沒有這個指令)
  • 所有修改隨時都被追蹤

Change vs Commit

  • Change: Jj 的基本單位,類似 Git 的 commit 但更靈活
  • Change ID: 每個 change 的唯一識別碼(如 kmkuslsw
  • Commit Hash: 底層 Git commit 的 SHA-1 hash

相關主題