← 返回文章列表

不懂 git,也能管住十幾個 worktree

先承認一件事:git 是我的短板。

多分支、遠端、rebase、merge、衝突、讀提交圖、force-push——這些我都不熟。我也闖過真實的禍:歷史被縫亂,好幾天的改動要一條條找回來。

但現在的局面是:一台機器上同時開着十幾個 worktree,幾個 agent 在不同分支上並行幹活,PR 一天開好幾個。按理説這是 git 最容易出事的場景,實際上反而比我自己手動操作的時候清楚。

辦法不是先把 git 學透。是讓 AI 管 git,我只管幾條它必須遵守的紀律,以及幾個我隨時能問的問題。

一、我會問的四個問題

我不讀提交圖,但我會問問題。最常用的四個:

「列出這個倉庫本機所有的 worktree 和分支:創建人、創建時間、落後主分支多少、遠端有沒有。」 這一句話能把局面攤開。哪些是我的、哪些是別人的,哪些已經合併、哪些落後很多、哪些只在本地沒推——一張表全看清。

「由我創建的、已經合併的 worktree 和分支,都刪掉。」 清理是最容易被忽略的。分支不刪,幾周後就是幾十個不知道是誰的、不知道還要不要的指針。我現在每次合併完都會説一句。

「這個 PR 合併了嗎?我剛推的提交進 main 了嗎?」 這一條是吃過虧換來的。我在網頁上隨手合併了一個 PR,agent 不知道,又往同一個分支推了兩個提交,還告訴我「PR 已更新」——實際上那兩個提交根本沒進主分支。現在的規則是:往已有 PR 追加提交之前,先查它的狀態;已經合併了,就從當前位置切一個新分支、開新 PR。

「誰創建的?」 看到一個陌生的分支或者一個不是我寫的提交,先問歸屬。別人的東西不刪、不改、不順手合。

二、AI 必須遵守的紀律

這些規則寫在一份跨機器同步的記憶裏,任何 agent 做 git 操作前都要讀。每一條都對應一次真實的事故。

分支名要能看出是誰、在哪台機器上建的。 我的約定是 <機器名>/<agent>/<描述>。多台機器、多個 agent 同時幹活時,看名字就知道歸屬,不用翻日誌。

共享目錄裏,「切分支」不是本地操作。 未提交的改動會跟着 HEAD 走。有一次一個 agent 在共享目錄裏切分支,把另一個會話正在改的 41 個文件搬到了自己的分支上。所以每個任務一個獨立 worktree,不在共享目錄裏切來切去。

禁止裸用 git stash。 stash 棧是整個倉庫共享的,不屬於任何分支。在乾淨的工作樹上 stash 什麼都不存,隨後的 pop 會彈出另一個並行會話存的東西。臨時回退一個文件用 git checkout <ref> -- <path>,要對比基線就開一個臨時 worktree。

管道會吞掉退出碼。 git push | tail 返回的是 tail 的退出碼。推送失敗、鈎子攔截,看起來都和成功一模一樣。要看完整輸出就寫進文件再讀,或者開 pipefail。

rebase 之後用 --force-with-lease,不要再 pull。 pull 會把舊的遠端歷史合回來,歷史就這樣被縫亂。而且 force 永遠不碰主分支。

合併是人的動作。 agent 可以推自己的分支、開 draft PR,不能 merge、不能推主分支、不能改分支保護。對我自己的私人記憶倉庫例外:那裏我授權 agent 自己快進合併,但遇到真衝突必須停下來報告。

三、並行太多是淨虧

我也有過過頭的時候:同時掛着七個 worktree 和三條自動循環。結果是髒代碼要逐個 diff 才分得清歸屬,未推送的提交從一百多漲到四百多。

根因不是懶,是評審預算守恆:AI 把「寫」的成本壓到接近零,但「驗、收、推、合、上線」一點沒變便宜,全堵在人這一環。所以現在我會給並行設一條收斂線,定期收口:每做完一批,先合、先刪,再開下一批。

四、長任務被殺後,先收拾現場

還有一類問題不是 git 本身,是 git 周圍的殘留。長任務被中途殺掉時,常見的殘留有:

  • 被臨時隔離的配置文件沒有還原,後續的 rebase 因為「有未暫存的改動」被拒;
  • 測試中途停掉,留下一個還在佔端口的孤兒服務;
  • 被強殺的腳本留下鎖文件;
  • shell 被回收了,但從 worktree 裏啓動的開發服務還活着,刪 worktree 之前要先停。

還有一條判斷:後台包裝進程被殺,不等於裏面的串行腳本停了。 判斷進度看 git log,不看進程列表。

五、我學到的 git,剛好夠用

這樣用了幾個月,我對 git 的理解反而比以前好了——不是因為讀了教程,而是因為每次出事,AI 都會用幾個簡單的心智模型給我解釋:

  • 分支就是一個指針,刪分支不刪提交;
  • rebase 會改提交的 hash,所以別人已經拿到的提交不能 rebase;
  • 合併沒合進去,就看這個提交是不是主分支的祖先(git merge-base --is-ancestor)。

這三條,夠我判斷 agent 説的話是不是真的了。

收束

短板不一定要先補齊才能往前走。git 我仍然不熟,但我知道該問什麼、該禁止什麼、出了事去哪看。

問題我來問,命令 AI 來敲,紀律寫成規則,合併按鈕留在自己手裏。 對一個不熟 git 的人來説,這比背下所有命令要可靠得多。