AI 生成聲明: 本文初稿由 Claude AI Sonnect 4.5 模型 生成, 再由個人手動修改而成。
前言:Git 工作流的痛點
當我們使用 Git 進行開發時, 經常會遇到這些情況:
- 想修改歷史 commit, 需要用
git rebase -i進入互動模式 - 管理多個相關的 feature branches, 需要手動追蹤分支間的依賴關係
- 不小心改錯了想回到之前的狀態, 得靠
git reflog救援 - Commit 之後才發現忘記加檔案, 又要
git commit --amend
這些操作雖然強大, 但往往需要記住複雜的命令組合, 對新手不友善。更重要的是, 它們打斷了開發者的思考流程, 讓人把注意力從「解決問題」轉移到「操作工具」。
對於追求高效工作流的開發者來說, 這些摩擦累積起來是不可忽視的時間成本。於是, 一些人開始探索更符合自己工作習慣的版本控制方式…
第一步:git-revise — 簡化歷史編輯
誕生背景
git-revise 是為了解決 git rebase -i 的複雜性而生。對於經常需要修改 commit 歷史的開發者來說, 互動式 rebase 的流程實在太繁瑣了。git-revise 提供了更直接的方式來達成同樣的目標。
核心特點
# 傳統 git rebase 的方式
git rebase -i HEAD~3 # 進入編輯器, 標記 edit/reword/squash...
# git-revise 的方式
# 1. 先修改檔案
vim some_file.py
# 2. Stage 你的修改
git add some_file.py
# 3. 應用到目標 commit
git revise <commit-hash> # 將 staged changes 應用到該 commit
優勢
- 更安全: 自動保留原始狀態,隨時可以恢復
- 更直覺: 直接操作目標 commit,不需要互動式編輯器
- 避免衝突: 智能處理 commit 間的依賴關係
限制
- 仍然基於 Git 的 branch 模型
- 無法徹底解決多分支管理的複雜性
第二步:git-branchstack — Branchless 工作流的個人實踐
為什麼需要它?
許多開發者發現, 傳統的「一個 feature 一個 branch」模式在實際工作中很不順手:
- 每次切換 branch 都要重新 build
- 多個相關的 PR 需要手動維護依賴關係
- 在不同 branch 間來回跳轉打斷思緒
git-branchstack 是一個個人效率工具, 讓你能用更自然的方式工作: 所有開發都在一個 branch 上進行, 只在需要提交 PR 時才生成對應的分支。
問題場景
你想在單一分支上開發多個功能, 每個功能對應一個 PR:
- 功能 A: 重構 authentication
- 功能 B: 新增 profile 頁面 (依賴 A)
- 功能 C: 一個無關的 bugfix
傳統做法需要:
- 為每個功能建立獨立分支
- 在分支間來回切換
- 每次切換都重新 build, 浪費時間
- 手動管理分支間的依賴關係
git-branchstack 的創新解法
git-branchstack 讓你留在本地分支, 用 commit message 的標籤來標記主題:
# 在本地分支上正常開發
git commit -m "[auth-refactor] Update login logic"
git commit -m "[auth-refactor] Add JWT support"
git commit -m "[profile-page:auth-refactor] Add profile component"
git commit -m "[bugfix-123] Fix memory leak"
# 一行命令生成所有分支
git branchstack
這會自動生成:
* local-branch (HEAD)
| - [bugfix-123] Fix memory leak
| - [profile-page:auth-refactor] Add profile component
| - [auth-refactor] Add JWT support
| - [auth-refactor] Update login logic
|
|-- bugfix-123 (branch)
| - Fix memory leak
|
|-- profile-page (branch)
| - Add profile component
| (based on auth-refactor)
|
|-- auth-refactor (branch)
- Add JWT support
- Update login logic
核心概念
-
標籤語法:
[topic]或[topic:dependency][auth-refactor]- 獨立主題[profile:auth-refactor]- profile 依賴 auth-refactor
-
Branchless 開發體驗:
- 所有工作在一個分支上進行
- 不需要切換分支, build 不會失效
- 修改任何 commit 後, 重跑
git branchstack更新所有分支
-
利用 git-revise:
- 底層使用 git-revise, 不碰工作目錄
- 速度快, 不影響正在進行的工作
實際工作流
# 1. 開發階段 - 在本地分支上自由開發
git commit -m "[feature-A] Implement part 1"
git commit -m "[feature-A] Implement part 2"
git commit -m "[feature-B:feature-A] Build on A"
# 2. 需要修改之前的 commit
git revise --interactive --edit # 編輯 commit message 加標籤
git revise <commit-hash> # 或直接修改內容
# 3. 生成/更新分支用於 PR
git branchstack
# 4. 推送到 GitHub
git push origin feature-A
git push origin feature-B
優勢與限制
優勢:
- 真正的 branchless 體驗, 留在本地分支工作
- 自動處理依賴關係
- 支援 git rerere 記住衝突解決方案
- 永不修改工作目錄, 不影響 build
限制:
- 需要在 commit message 中手動標記主題
- 依賴關係的改變需要修改 commit message
- 作者本人已轉向 Jujutsu (這說明了一些問題!)
革命性轉變:Jujutsu (jj) — 重新定義個人版本控制體驗
為什麼誕生?
即使有了 git-revise 和 git-branchstack 這些工具, Git 的基礎模型仍然存在根本性的摩擦。Jujutsu 的作者 Martin von Zweigbergk (同時也是 Google 內部版本控制系統的開發者) 決定: 與其不斷在 Git 上打補丁, 不如從頭設計一個真正符合現代工作流的版本控制系統。
這不是為了取代 Git 成為「標準」, 而是為追求極致效率的個人開發者提供更好的選擇。
核心理念轉變
Jujutsu 不是在 Git 上加工具, 而是重新思考版本控制該是什麼樣子:
-
Change-based, 而非 Commit-based
- 每個修改都是一個獨立的 “change”
- Change 可以隨時修改, 不需要 amend 或 rebase
-
Working Copy 即 Commit
- 你的工作目錄就是一個 commit
- 不需要
git add+git commit兩階段
-
真正的非線性歷史
- 不需要 branch 也能管理多條開發線
- 衝突作為一等公民存在於歷史中
實際操作對比
場景一:修改歷史 Commit
Git 方式:
git rebase -i HEAD~3
# 標記要修改的 commit 為 'edit'
# 進行修改
git add .
git commit --amend
git rebase --continue
git-revise 方式:
# 進行修改
vim some_file.py
# Stage 修改
git add some_file.py
# 應用到目標 commit
git revise <commit-hash> # 直接更新該 commit
Jujutsu 方式:
jj edit <change-id> # 直接切換到該 change
# 進行修改
jj commit -m "updated" # 自動更新該 change
場景二:管理多個功能開發
Git + branchstack 方式:
# 開發 feature-A
git commit -m "[feature-A] A"
# 開發 feature-B
git commit -m "[feature-B] B"
# 要修改 A 時
git commit -m "[feature-A] Update A"
# 生成/更新分支用於 PR
git branchstack
Jujutsu 方式:
# 不需要建立 branch
jj new -m "feature A" # 創建新 change
# 開發 feature A
jj new -m "feature B" # 基於當前創建新 change
# 開發 feature B
# 要修改 A 時
jj edit <change-A-id>
# 修改完自動處理依賴
Jujutsu 的核心特性
1. 自動追蹤所有歷史
jj op log # 查看所有操作歷史
jj op undo # 撤銷任何操作
jj op restore # 恢復到任何時間點
不需要 git reflog, 所有操作都可追溯和回復。
2. 衝突處理的新思路
# Jujutsu 讓你可以 commit 帶有衝突的狀態
jj new # 即使有衝突也能繼續開發
jj resolve # 稍後解決衝突
3. 與 Git 無縫協作
# Jujutsu 可以操作 Git repo
jj git clone <url>
jj git push
jj git fetch
# 現有 Git repo 也能用 jj
cd my-git-repo
jj init --git-repo .
為什麼 Jujutsu 是個人效率工具的終極形態?
心智模型更簡單
- Git: Branch → Stage → Commit → Push → Rebase → Merge
- Jujutsu: Change → Edit → Evolve
對於個人開發者來說, 這意味著更少的認知負擔, 更多的時間專注在實際問題上。
更安全的實驗
- 所有操作都可以輕鬆撤銷
- 不需要擔心「搞壞」歷史
- 鼓勵更頻繁的實驗和重構
更適合現代個人工作流
- Code Review 驅動的開發
- 頻繁的 Commit 修改
- 多個 PR 同時進行
- 不需要團隊統一工具 (可以單人使用 jj, 推送時轉為 Git)
實戰案例:用 Jujutsu 管理 Feature Stack
# 初始化
jj git clone https://github.com/user/repo.git
cd repo
# 創建第一個功能
jj new -m "Add user authentication"
# 開發...
jj describe -m "Add login form and validation"
# 基於此創建第二個功能
jj new -m "Add user profile page"
# 開發...
# 創建第三個功能
jj new -m "Add profile editing"
# 開發...
# 查看當前狀態
jj log
# 發現第一個功能需要修改
jj edit <auth-change-id>
# 修改...
jj describe -m "Updated authentication logic"
# 自動處理後續依賴, 不需要手動 rebase!
# 推送到 GitHub
jj git push --change <change-id> # 為每個 change 推送對應分支
學習曲線
- 現有 Git 用戶: 可以繼續在 Git repo 中使用
jj, 逐步適應 - 新專案: 直接用
jj git init開始, 享受完整體驗 - 團隊協作: 個人可以用 jj 提升效率, 推送時轉換為 Git, 不影響團隊其他成員
這是一個個人選擇, 不需要說服整個團隊改變工作流程。
結語:效率工具的個人化旅程
從 git-revise 到 git-branchstack, 再到 Jujutsu, 這是一段持續追求更高效率的旅程。每個工具都代表了開發者對「版本控制應該如何輔助我的工作」的不同思考。
這些工具的共同點是:
- 它們都是個人效率工具, 不需要整個團隊採用
- 它們都在挑戰 Git 的既有模式
- 它們都專注於減少摩擦, 讓開發者更專注於解決問題
Jujutsu 的特別之處在於, 它不只是改善 Git 的某個面向, 而是重新思考了整個版本控制的心智模型。對於願意投資學習新工具來提升長期效率的開發者來說, 它可能是最佳選擇。
最重要的是: 這是一個個人選擇。你不需要等待團隊共識, 不需要說服所有人。如果 Git 的複雜性讓你感到疲憊, 如果你想要更流暢的開發體驗, 那就試試這些工具吧。
或許你會發現, 提升效率的關鍵不是更努力地使用現有工具, 而是找到更適合你的工具。
延伸資源
試試看,你可能再也回不去 Git 了! 🚀