繁體中文

工作樹

在 ChatGPT 桌面 App 中使用 Git worktrees,讓 Codex 並行執行聊天

在 ChatGPT 桌面 App 中,工作樹讓 Codex 可以在同一專案內執行多個互不干擾的獨立聊天。對於 Git 儲存庫,定時任務可以在專用後臺工作樹中執行,避免與當前工作衝突;未使用版本控制的專案則直接在專案目錄中執行。你也可以手動在工作樹中開始聊天,並通過 Handoff(交接)在本機檢出與工作樹之間移動聊天。

什麼是工作樹

工作樹只適用於 Git 儲存庫,因為底層使用 Git worktree。工作樹會建立儲存庫的第二份檢出副本。每個工作樹都有完整檔案副本,但共享提交、分支等 .git 後設資料,因此可以並行檢出和處理多個分支。

術語

  • Local checkout(本機檢出):你建立的儲存庫,在 ChatGPT 桌面 App 中有時簡稱 Local
  • Worktree(工作樹):ChatGPT 桌面 App 從本機檢出建立的 Git worktree
  • Handoff(交接):在本機檢出與工作樹之間移動聊天的流程。Codex 會處理安全遷移工作所需的 Git 操作。

為什麼使用工作樹

  1. 與 Codex 並行工作,而不影響當前 Local 設定。
  2. 讓後臺工作排隊執行,同時繼續專注於前臺工作。
  3. 準備好檢查、測試或更直接協作時,再把聊天移動到 Local。

開始使用

工作樹要求專案位於 Git 儲存庫中。

  1. 選擇 Worktree(工作樹)

    在新聊天檢視的 composer(輸入框)下方選擇 Worktree(工作樹)。也可以選擇本機環境,為工作樹執行初始化指令碼。

  2. 選擇起始分支

    在 composer 下方選擇工作樹的基準 Git 分支。它可以是 mainmaster、功能分支,也可以是當前帶有未暫存改動的分支。

  3. 提交提示詞

    Codex 會根據所選分支建立 Git 工作樹。預設情況下,Codex 在 detached HEAD 狀態下工作。

  4. 選擇繼續工作的地方

    之後可以繼續在工作樹中工作,也可以把聊天交接到本機檢出。無論移入還是移出 Local,Handoff 都會同時移動聊天和程式碼。

在本機檢出與工作樹之間工作

工作樹的體驗與本機檢出很接近,區別在於它們在流程中的位置。可以把本機檢出看作前臺,把工作樹看作後臺;Handoff 用於在兩者之間移動聊天。

Handoff 會處理在兩個檢出目錄之間安全移動工作所需的 Git 操作。這裡有一個關鍵限制:Git 只允許一個分支同時在一個位置被檢出。分支已經在工作樹中檢出時,不能同時在本機檢出中使用,反之亦然。

常見路徑有兩種:

  1. 始終在工作樹中工作。當你可以直接在工作樹中驗證改動時最合適,例如已通過本機環境初始化指令碼安裝依賴和工具。
  2. 把聊天交接到 Local。需要在常用 IDE 中檢查改動,或應用只能執行一個例項時使用。

方案 1:始終在工作樹中工作

如果要把改動留在工作樹中,請使用聊天標題欄的 Create branch here(在此建立分支) 按鈕,把工作樹轉換成分支。

之後可以提交改動、把分支推送到遠端儲存庫,並在 GitHub 上建立 pull request。

使用標題欄中的 Open(開啟) 按鈕,可以讓 IDE 開啟該工作樹;也可以使用整合終端或其他需要從工作樹目錄執行的工具。

帶有分支控制項和工作樹詳情的工作樹聊天檢視(淺色模式)

請注意,在工作樹中建立分支後,不能在任何其他工作樹或本機檢出中同時檢出該分支。

方案 2:把聊天交接到 Local

要把聊天帶回前臺,請在聊天標題欄選擇 Hand off(交接),然後移動到 Local

當你想在日常使用的 IDE 視窗中檢視改動、執行已有開發伺服器,或在常用本機環境中驗證工作時,這種路徑很合適。

Codex 會處理在工作樹與本機檢出之間安全移動聊天所需的 Git 步驟。

每個聊天始終關聯同一個工作樹。如果之後把聊天再次交接到工作樹,Codex 會回到同一個後臺環境,從上次停下的位置繼續。

把聊天從工作樹移動到 Local 的 Handoff 對話方塊(淺色模式)

也可以反向操作:已經在 Local 中工作時,使用 Hand off 把聊天移動到工作樹,讓 Codex 在後臺繼續工作,同時釋放本機前臺。

Handoff 使用 Git 操作,因此 .gitignore 中的檔案不會隨聊天移動,除非 Codex 通過 .worktreeinclude 把它們複製到本機託管工作樹。

高階細節

Codex 託管工作樹與永久工作樹

預設情況下,聊天使用 Codex 託管工作樹。這類工作樹輕量且可丟棄,通常只服務一個聊天;如果聊天之後被交接回來,Codex 會讓它回到同一個工作樹。

需要長期環境時,從側邊欄專案的三點選單建立永久工作樹。它會作為獨立專案存在,不會自動刪除,並且允許從同一工作樹啟動多個聊天。

Codex 如何管理工作樹

Codex 在 $CODEX_HOME/worktrees 中建立工作樹。起始提交是啟動聊天時所選分支的 HEAD。如果該分支帶有本機改動,Codex 也會把未提交改動應用到工作樹。工作樹不會作為分支檢出,而是處於 detached HEAD 狀態,因此 Codex 可以建立多個工作樹而不汙染分支列表。

把被忽略的本機檔案複製到託管工作樹

本機 Codex 託管工作樹從 Git checkout 開始,因此已跟蹤檔案已經存在。如果儲存庫忽略了新工作樹需要的本機設定檔案,請在儲存庫根目錄新增 .worktreeinclude,列出 Codex 建立託管工作樹時應複製的被忽略路徑或 .gitignore 風格模式。

它適合 Git 有意忽略的檔案,例如 .env.env.localconfig/secrets.json。Codex 只複製匹配 .worktreeinclude 的被忽略檔案,不復制其他未跟蹤檔案。不要列出已跟蹤檔案。

Codex 會自動把被忽略的 AGENTS.override.md 複製到本機託管工作樹,因此無需在 .worktreeinclude 中列出。

# .worktreeinclude
.env
.env.local
config/secrets.json

Codex 會跳過源符號連結,也不會覆蓋新檢出目錄中已經存在的檔案。此行為只適用於 ChatGPT 桌面 App 的本機託管工作樹,不適用於遠端工作樹或你從命令列建立的 Git 工作樹。

分支限制

假設 Codex 在工作樹中完成了一些工作,你使用 Create branch here 建立 feature/a。如果隨後嘗試在本機檢出中檢出同一分支,會看到:

fatal: 'feature/a' is already used by worktree at '<WORKTREE_PATH>'

要解決問題,需要讓工作樹檢出 feature/a 以外的分支。

如果計劃在本機使用該分支,請通過 Handoff 把聊天移動到 Local,不要讓同一分支同時在兩個位置保持檢出。

為什麼會有這個限制

Git 會阻止同一分支同時在多個工作樹中檢出,因為分支是單一的可變引用(refs/heads/<name>),代表一個工作樹的“當前檢出狀態”。

分支被檢出後,Git 會把其 HEAD 視為由該工作樹擁有,並要求 commit、reset、rebase、merge 等操作以明確、序列的方式推進該引用。如果多個工作樹同時檢出同一分支,就會產生哪個工作樹負責更新引用的歧義和競態,可能導致 commit 丟失、index 不一致或衝突處理不明確。

通過一條分支只對應一個工作樹,Git 確保每個分支只有一個權威工作副本,同時仍允許其他工作樹通過 detached HEAD 或獨立分支安全引用相同 commit。

工作樹清理

每個工作樹都有自己的儲存庫檔案、依賴和建置快取,可能佔用大量磁碟空間。ChatGPT 桌面 App 會盡量把數量控制在合理範圍內。

預設情況下,Codex 保留最近 15 個託管工作樹。你可以在設定中調整上限或關閉自動刪除,自行管理磁碟佔用。

以下工作樹不會自動刪除:

  • 有已固定聊天與之關聯。
  • 聊天仍在進行。
  • 它是永久工作樹。

以下情況下會自動刪除:

  • 你歸檔了關聯聊天。
  • Codex 需要刪除較舊工作樹,才能維持設定的數量上限。

刪除託管工作樹前,Codex 會儲存工作快照。如果重新開啟一個工作樹已被刪除的聊天,介面會提供恢復選項。

常見問題

可以控制工作樹建立位置嗎?

可以。Codex 預設在 $CODEX_HOME/worktrees 中建立託管工作樹。需要更改位置時,開啟 Settings > Worktrees(設定 > 工作樹),修改 Worktree root(工作樹根目錄)

可以在本機檢出與工作樹之間移動聊天嗎?

可以。在聊天標題欄使用 Hand off,可以在本機檢出和工作樹之間移動聊天。Codex 會處理安全遷移所需的 Git 操作。之後把聊天再次交接到工作樹時,Codex 會讓它回到關聯的同一工作樹。

工作樹被刪除後,聊天會怎樣?

即使底層工作樹目錄被刪除,聊天仍可保留在歷史記錄中。對於 Codex 託管工作樹,Codex 會在刪除前儲存快照;重新開啟關聯聊天時,可以恢復該工作樹。歸檔聊天不會自動刪除永久工作樹。