:用 Git Worktree 實現(xiàn)多任務同時開發(fā))
1. 單會話串行到底卡在哪里用 Claude Code 寫代碼的人大概都經(jīng)歷過這種節(jié)奏一個會話里讓它改 A 模塊等它讀完文件、想完、寫完再讓它改 B 模塊再等一輪。中間你只能干看著或者切出去刷會兒別的。一天下來真正推進的事情沒幾件時間全耗在等 AI 想上了。這個瓶頸的本質(zhì)不是模型慢而是會話是串行的。一個 Claude Code 會話在任意時刻只能處理一個任務流它的上下文、它的工具調(diào)用、它的文件讀寫全都綁在這一條線上。你讓它同時干三件事它做不到——它只會一件一件來。那一個人干三個人的活是怎么實現(xiàn)的答案不是讓單個會話變快而是同時開多個會話每個會話負責一條獨立的工作線。這就像你從一個人排隊辦事變成開三個窗口同時辦事。窗口之間互不干擾各自推進你只需要在它們之間做調(diào)度。但這里有個繞不開的問題多個會話如果都在同一個工作目錄里改文件會互相踩踏。A 會話正在改utils.pyB 會話也去改utils.py兩邊一保存沖突就來了。所以并行多會話的前提是每個會話有自己獨立的工作副本。這就是 Git Worktree 出場的地方。下面我會把整套東西拆開講為什么是 Worktree 而不是別的方案、怎么把環(huán)境搭起來、多個會話怎么分工、實際跑起來會遇到哪些坑。內(nèi)容偏實操假設你已經(jīng)裝好了 Claude Code也對 Git 有基本概念。2. 為什么是 Git Worktree而不是復制目錄或另開分支先說結(jié)論并行多會話的物理基礎是每個會話一個獨立工作目錄而 Git Worktree 是目前最干凈的實現(xiàn)方式。但很多人第一反應不是 Worktree而是我復制一份項目目錄不就行了或者我開個新分支不就行了。這兩種做法都能跑但都有硬傷值得掰開說。2.1 復制目錄方案簡單但會埋雷復制整個項目目錄最直觀。cp -r project project-b然后在project-b里開第二個會話。聽起來沒問題但實際用起來有幾個坑。第一依賴和構(gòu)建產(chǎn)物會重復。一個中等規(guī)模的 Node 項目node_modules動輒幾百 MB 到幾個 GB。復制一份磁盤直接翻倍。Python 項目的虛擬環(huán)境、Java 項目的target目錄同理。你要是開三個會話就是三份依賴磁盤和內(nèi)存都吃不消。第二Git 狀態(tài)是割裂的。復制出來的目錄它的.git是獨立的一份和原目錄沒有關聯(lián)。你在副本里提交的代碼原目錄看不到你想把副本的改動合并回去得手動git remote add或者干脆復制文件。這就失去了版本控制的意義。第三容易忘記清理。臨時復制的目錄用完經(jīng)常忘了刪越積越多最后自己都分不清哪個是哪個。2.2 另開分支方案共享目錄必然打架我開個新分支不就行了——這個思路的問題在于分支切換是全局的。Git 的分支是綁在工作目錄上的你git checkout feature-b整個工作目錄就切到 feature-b 了。這時候你原來的會話還在跑它讀到的文件已經(jīng)變成另一個分支的內(nèi)容了。換句話說同一個工作目錄同一時刻只能處于一個分支。你想讓兩個會話同時工作在兩個分支上物理上做不到。除非你不停地切來切去但那樣兩個會話都會讀到錯亂的文件狀態(tài)比串行還糟。2.3 Worktree 方案一個倉庫多個工作目錄Git Worktree 解決的正是這個問題。它允許同一個 Git 倉庫掛載出多個工作目錄每個目錄可以 checkout 不同的分支。這些目錄共享同一個.git對象庫所以磁盤上不重復存儲歷史對象只多出工作區(qū)的文件每個 worktree 有獨立的分支、獨立的暫存區(qū)、獨立的工作狀態(tài)在任意一個 worktree 里的提交其他 worktree 都能通過 Git 看到。用一句話概括Worktree 讓你用一份倉庫的代價換來多個互不干擾的工作現(xiàn)場。這正好對應并行多會話的需求——每個會話一個 worktree各改各的互不踩踏。方案磁盤開銷Git 狀態(tài)會話隔離合并回主線的難度復制目錄高依賴重復割裂需手動同步好高另開分支低共享但會互相切換差同一目錄低Git Worktree低共享對象庫共享且各自獨立好低從表里能看出來Worktree 是唯一同時滿足低開銷 好隔離 易合并的方案。這也是為什么現(xiàn)在聊 Claude Code 并行多會話幾乎都會提到 Git Worktree。提示W(wǎng)orktree 不是新東西Git 2.5 就有了只是一直不溫不火。它真正被大規(guī)模用起來恰恰是因為 AI 編程助手需要多個獨立工作現(xiàn)場這個場景。3. 把并行環(huán)境搭起來從安裝到第一個 Worktree這一節(jié)講具體怎么落地。假設你已經(jīng)在用 Claude CodeGit 也裝好了。如果你還沒裝 Claude Code先把它裝上——不同系統(tǒng)的安裝方式不一樣裝完之后確認claude命令能在終端里跑起來這是后面所有操作的前提。3.1 確認 Git 版本和基礎配置Worktree 需要 Git 2.5 以上現(xiàn)在基本都滿足。先確認一下git --version然后確認你的主倉庫是干凈的沒有未提交的改動。這點很重要因為 Worktree 是從當前倉庫狀態(tài)派生的如果主目錄一團亂派生出來的 worktree 也會帶著問題。git status如果有未提交的改動先提交或者 stash 掉。我個人的習慣是在開并行會話之前先把主分支整理干凈這樣每個 worktree 都有一個明確的起點。3.2 創(chuàng)建第一個 Worktree假設你的項目在~/projects/myapp你想開一條新工作線做用戶認證模塊重構(gòu)。先建一個分支再基于它建 worktreecd ~/projects/myapp git worktree add ../myapp-auth -b feature/auth-refactor這條命令做了兩件事創(chuàng)建一個新分支feature/auth-refactor并在../myapp-auth目錄里把它 checkout 出來?,F(xiàn)在~/projects/myapp-auth就是一個獨立的工作目錄和主目錄共享同一個.git。進去看看cd ../myapp-auth git branch你會看到當前在feature/auth-refactor上。在這個目錄里改任何東西都不會影響主目錄。3.3 在 Worktree 里啟動 Claude Code這是關鍵一步。每個 worktree 目錄里單獨啟動一個 Claude Code 會話cd ~/projects/myapp-auth claude現(xiàn)在這個會話的所有文件操作都局限在myapp-auth這個目錄里。你再開一個終端進另一個 worktree啟動第二個會話兩個會話就完全隔離了。我一般會開三個終端窗口或者用 tmux 分屏每個窗口對應一個 worktree。這樣一眼就能看到三個會話各自在干什么。3.4 查看和管理所有 WorktreeWorktree 多了之后需要能隨時看到全貌git worktree list輸出大概是這樣~/projects/myapp abc1234 [main] ~/projects/myapp-auth def5678 [feature/auth-refactor] ~/projects/myapp-api ghi9012 [feature/api-redesign]用完的 worktree 要記得清理否則會越積越多git worktree remove ../myapp-auth如果這個 worktree 里還有未提交的改動remove會拒絕執(zhí)行防止你誤刪。確認不要了可以加--force。分支本身不會因為 worktree 刪除而消失需要的話再單獨git branch -d。注意刪除 worktree 之前務必確認里面的改動已經(jīng)提交或者合并。我踩過一次坑一個 worktree 里改了半天沒提交直接 remove 掉了雖然理論上能從 Git 對象里撈回來但過程很折騰。養(yǎng)成離開 worktree 前先 commit的習慣。4. 多會話怎么分工三條并行的真實工作線環(huán)境搭好了接下來是更實際的問題三個會話到底怎么分工才能真的干三個人的活。不是隨便開三個會話就叫并行分工不合理反而會互相制造麻煩。下面用三個典型場景說明。4.1 場景一功能開發(fā) 測試編寫 文檔更新這是最經(jīng)典的三線并行。假設你要做一個新功能訂單導出會話 A功能線在myapp-featureworktree 里讓 Claude Code 實現(xiàn)導出邏輯改業(yè)務代碼。會話 B測試線在myapp-testworktree 里基于功能線的接口約定寫單元測試和集成測試。會話 C文檔線在myapp-docsworktree 里更新 API 文檔和使用說明。這三條線的依賴關系是測試和文檔都依賴功能線的接口定義。所以開工前要先約定好接口——函數(shù)簽名、參數(shù)、返回值。約定好了三條線就能真正并行沒約定好測試線寫出來的測試對不上功能線的實現(xiàn)最后還得返工。我的做法是先在主目錄里花十分鐘把接口定義寫成一個簡單的 markdown 或者注釋然后三個 worktree 都基于這個約定開工。這十分鐘的投入能省掉后面大量的對齊成本。4.2 場景二主分支修 bug 分支做重構(gòu)有時候你手上有個緊急 bug 要修同時又在推進一個大重構(gòu)。這兩件事如果在一個會話里做上下文會互相污染——重構(gòu)的改動還沒穩(wěn)定修 bug 時讀到的代碼可能是半成品。用 Worktree 就清爽了會話 A主目錄main分支專門修緊急 bug改完直接提交、推送。會話 Bmyapp-refactorworktree慢慢做重構(gòu)不受 bug 修復的干擾。這樣緊急 bug 的修復可以快速上線重構(gòu)線繼續(xù)按自己的節(jié)奏走。等重構(gòu)完成再合并回主分支。4.3 場景三同一功能的多方案對比這個場景比較進階但很實用。有時候你不確定某個功能該怎么實現(xiàn)想試試兩種不同的技術(shù)方案。傳統(tǒng)做法是試完 A 再試 B串行對比。用 Worktree 可以同時試會話 Amyapp-approach-aworktree用方案 A 實現(xiàn)。會話 Bmyapp-approach-bworktree用方案 B 實現(xiàn)。兩個會話同時跑跑完你直接對比兩邊的代碼和效果選好的那個合并。這比串行試快一倍而且對比更直觀——兩邊的代碼都還在隨時能翻。場景會話 A會話 B會話 C關鍵前提功能開發(fā)業(yè)務代碼測試代碼文檔先約定接口修 bug 重構(gòu)主分支修 bug分支重構(gòu)—分支獨立多方案對比方案 A方案 B—目標明確4.4 分工的核心原則減少跨會話依賴不管哪種場景分工的核心原則都是一條盡量讓每個會話的工作自包含減少跨會話的依賴。依賴越少并行度越高。如果會話 A 的每一步都要等會話 B 的輸出那本質(zhì)上還是串行只是換了個形式。真正高效的并行是三條線各自能獨立推進只在關鍵節(jié)點做一次對齊。我一般會在開工前畫一個簡單的依賴圖腦子里過一遍就行哪些是獨立的哪些有先后。獨立的并行有先后的串行或者先約定接口再并行。5. 實測中繞不開的坑沖突、上下文與資源并行多會話聽起來很美但實際跑起來有幾個坑幾乎一定會遇到。這一節(jié)把踩過的坑和排查過程完整寫出來方便你復現(xiàn)排查思路。5.1 合并沖突并行改動的必然代價只要多個會話改了同一批文件合并時就會有沖突。這不是 Worktree 的問題是并行開發(fā)的固有代價。Worktree 只是讓沖突在合并時暴露而不是在編輯時互相覆蓋。排查和處理的思路先看沖突范圍。git merge feature/auth-refactor之后git status會列出沖突文件。判斷沖突類型。如果是同一函數(shù)的不同實現(xiàn)需要人工決策保留哪個如果是格式差異比如縮進、換行可以用工具自動處理。優(yōu)先在 worktree 里解決。我習慣在 worktree 里先git rebase main把主分支的最新改動拉進來在 worktree 里解決沖突解決完再合并回主分支。這樣主分支始終保持干凈。減少沖突的根本辦法還是分工時盡量讓不同會話改不同的文件。如果兩個會話注定要改同一個文件那就要么串行要么提前約定好各自改哪部分。5.2 上下文隔離每個會話都是失憶的這是很多人忽略的一點。每個 Claude Code 會話的上下文是獨立的。會話 A 里你跟它聊了半天的項目背景、架構(gòu)決策會話 B 完全不知道。這意味著如果你在會話 A 里讓 Claude Code 理解了某個復雜的設計意圖然后切到會話 B 讓它做相關的事你得重新把背景講一遍。否則會話 B 會基于它自己讀到的代碼做判斷可能和會話 A 的決策不一致。我的應對辦法是把重要的項目背景和約定寫成一個文件比如PROJECT_CONTEXT.md放在倉庫里。每個會話開工前先讓它讀這個文件。這樣背景只需要維護一份所有會話共享。# 在每個 worktree 的會話里第一件事 先讀一下項目根目錄的 PROJECT_CONTEXT.md了解當前的架構(gòu)約定5.3 資源占用三個會話不等于三倍開銷開三個會話內(nèi)存和 CPU 占用會上升但不是簡單的三倍。Claude Code 本身是個客戶端主要的計算在服務端本地占用主要是文件監(jiān)聽和一些輔助進程。真正吃資源的是每個 worktree 的依賴和構(gòu)建。如果你在三個 worktree 里都跑了npm install那就是三份node_modules。這時候磁盤和內(nèi)存的壓力就上來了。我的做法是能用軟鏈接共享的依賴就共享比如把node_modules軟鏈到主目錄的構(gòu)建產(chǎn)物按需生成不用的 worktree 不跑構(gòu)建定期清理不用的 worktree。提示軟鏈接共享依賴有風險如果不同分支的依賴版本不同會出問題。只在確認依賴一致時用。5.4 會話跑飛如何及時發(fā)現(xiàn)和止損并行跑三個會話最大的風險是某個會話跑偏了你還不知道。比如會話 B 理解錯了需求寫了一堆沒用的代碼等你發(fā)現(xiàn)時已經(jīng)改了很多文件。我的做法是定期巡檢。每隔一段時間切到每個 worktree 看一眼git diff確認改動方向是對的。發(fā)現(xiàn)跑偏立刻在那個會話里糾正別等它跑完。# 在 worktree 里快速看改動概況 git diff --stat如果改動量異常大或者改的文件不在預期范圍內(nèi)就要警惕了。6. 讓并行真正提速的幾個實操技巧前面講了原理和坑這一節(jié)分享幾個讓并行多會話真正跑出效率的技巧。這些是我用下來覺得最有價值的常規(guī)文檔里不太會寫。6.1 用 tmux 或分屏管理多個會話開三個終端窗口來回切效率很低。用 tmux 分屏三個會話并排顯示一眼看全tmux new-session -s claude-parallel # 然后 Ctrlb % 垂直分屏Ctrlb 水平分屏每個 pane 里進一個 worktree啟動一個 Claude Code。這樣你隨時能看到三個會話的狀態(tài)哪個在等你輸入哪個在跑一目了然。6.2 給每個 worktree 起有意義的名字myapp-1、myapp-2這種名字過兩天你自己都忘了哪個是哪個。用任務相關的名字myapp-auth、myapp-api、myapp-docs。分支名也一樣feature/auth-refactor比feature/branch1清楚得多。6.3 主分支保持隨時可發(fā)布狀態(tài)并行開發(fā)時主分支很容易被各種半成品污染。我的原則是主分支永遠保持可發(fā)布狀態(tài)。所有實驗性的、未完成的工作都在 worktree 的分支里做。只有確認完成、測試通過的功能才合并回主分支。這樣即使并行線出了問題主分支也不受影響隨時能發(fā)版。6.4 定期同步主分支到各 worktree并行跑久了各 worktree 會落后于主分支。定期把主分支的最新改動同步進來能減少最后合并時的沖突量# 在 worktree 里 git fetch origin git rebase origin/main我一般每天開工前做一次同步讓所有工作線都基于最新的主分支。6.5 別貪多兩到三條線是甜點區(qū)理論上你可以開十個 worktree、十個會話。但實際用下來兩到三條并行線是效率最高的。超過三條你的注意力會被分散巡檢成本上升反而容易出錯。人的精力是有限的。三個會話同時跑你還能跟得上每個的進度五個以上你就只能被動地等它們報錯失去了調(diào)度的意義。所以別追求數(shù)量追求的是每條線都能被你有效管理。7. 從串行到并行真正改變的是什么用了一段時間并行多會話之后我最大的感受不是快了多少倍而是工作方式變了。以前串行的時候我的節(jié)奏是被 AI 帶著走的——它想的時候我等著它寫完我看一眼再給下一個指令。一天下來我更像一個監(jiān)工盯著一個工人干活。并行之后我變成了調(diào)度者。三個會話各自推進我的工作是分配任務、巡檢進度、處理沖突、做關鍵決策。等待的時間被填滿了——會話 A 在跑的時候我去看會話 B 的產(chǎn)出或者給會話 C 補充背景。這種轉(zhuǎn)變的前提是你得提前想清楚要做什么。串行的時候可以走一步看一步并行的時候不行——三條線同時開工你必須先把任務拆清楚、接口約定好否則就是三倍的混亂。所以并行多會話真正考驗的不是工具用得多熟而是你能不能把一個任務拆成幾條獨立的工作線。這個能力比任何工具配置都重要。工具只是放大器拆得好它放大效率拆不好它放大混亂。最后分享一個我自己的習慣每次開并行會話之前花五分鐘在紙上或者文檔里寫下三條線各自要做什么、依賴什么、預期產(chǎn)出是什么。這五分鐘的規(guī)劃決定了接下來幾個小時是高效推進還是反復返工。