Day 21:新手常問:一個 PR 該放多少東西?判準不是行數,是「出事時你想一次撤掉什麼」
SPEC 要不要獨立開、三個階段要不要合成一張——四個理由與一個反例,附三題自我檢查
新手最常問的其中一題:「這些改動要開一張 PR 還是分好幾張?」
新手最常問的其中一題:「這些改動要開一張 PR 還是分好幾張?」
網路上的答案通常是「PR 要小」「不要超過 400 行」。這些不算錯,但它沒回答為什麼,所以你下次遇到不一樣的情況還是不知道怎麼判斷。
先給一個真正好用的判準: 一個 PR = 一個「出事時你想一次撤掉」的決定。
不是「一個檔案」,不是「一天的工作量」,也不是「幾行」。
多數關於 PR 大小的爭論,是因為大家在用不同的計量單位——有人算行數,有人算時間,有人算檔案數。真正該問的是:這件事如果做錯了,我希望能用一個動作退掉什麼? 💡 小名詞:PR(Pull Request)是「我改好了,請幫我看一下再併進主線」的請求。 「撤掉/revert」則是把已經併進去的改動整包退回去——這是出事時最重要的一條逃生路。 問題一:SPEC 要不要獨立開一張 PR? SPEC 就是「做之前先寫清楚要做什麼、為什麼這樣做」的設計文件。
看它是求決策還是記錄已定案的事:
SPEC 的性質 做法 --- --- 「我打算這樣做,你同意嗎?」——裡面有還沒拍板的選項 獨立一張 「我做完了,這是為什麼這樣做」 跟程式放同一張,兩者才不會走鐘
判斷方法很簡單:把 SPEC 裡的開放問題列出來。 一個都沒有,那它是文件不是提案,跟程式一起送就好。
實際情境:一份「AI 用量控管」的 SPEC 裡有三個真的還沒定案的東西——三個階段的先後順序、要不要把某個 API 鎖成必須登入才能用、額度預設值設多少。這時候先送 SPEC 是划算的:如果連程式一起寫了,對方才說「不該鎖」,那段程式就白寫了。
但也要誠實看代價:如果對方本來就會照准,這個分離就是多花一輪等待。 這是個押注,不是鐵律。押注的依據是「開放問題有幾個」和「猜錯要重寫多少程式」。 問題二:為什麼不把三個階段合成一張?
假設要做的是三件事: 階段 1:資料表加一個欄位,才分得出「哪個員工用了 AI」 階段 2:做一個後台頁面,看得到每位員工用了幾次 階段 3:加上限,超過就擋
四個理由,前三個是通則,第四個才是這次的關鍵: ① 撤銷粒度不同 階段 1 動到資料庫結構(migration,不好退) 階段 3 改的是執行期行為(開始擋人、回錯誤碼)
如果階段 3 的額度設錯,你要能只撤階段 3,不必連資料庫變更一起回滾。合成一張,這兩件事就綁死了。 💡 為什麼資料庫變更特別難退?因為程式可以退回舊版,資料退不回去。 欄位刪掉,裡面的資料就沒了。 ② 部署風險隔離
資料庫 + 後端 + 前端擠在一次部署,壞了你不知道是哪一段。分開送,每次部署只有一個新變數,出事時一眼看得出兇手。 ③ Review 品質隨 diff 變大急速下降
超過幾百行之後,人(和 AI)就開始滑過去了。這不是自律問題,是注意力的物理限制。
有個現成的反例:某次 PR 一次改了兩件事(代碼命名規則 + 排序欄位),其中一件引進了一個「同一場活動裡兩個獎項用到同一個代碼就會衝突」的 bug,直到使用者實際去用才炸出來。如果那兩件事分開送,review 時盯著單一改動,抓到的機率高得多。 ④ 🔴 階段 3 在資料上依賴階段 2
這不是風格問題,是做不到。
階段 3 要設「每人每日上限」——設多少? 得看階段 2 的統計跑出來的真實數字。現在寫階段 3 只能填一個猜的數字,然後過幾天再改一次。
合成一張 PR,等於強迫自己現在就猜。
這一條值得單獨記住: 當後一步的正確性依賴前一步產生的資料時,它們在時間上就不可能是同一張 PR。 這跟程式碼耦不耦合無關。 反過來:什麼時候該合成一張?
當幾件事是同一個決定的不同部分時,分開反而危險。
現成例子:一張優惠券在預約頁「不見了」。查出來的原因是——後台的「限定品項」是自由輸入框,有人打了小寫 chair,而系統比對時傳的是大寫 CHAIR,用嚴格相等比對,於是對不上、券被濾掉。
修法有兩層,故意合成一張 PR: 比對改成大小寫不敏感 → 既有那張壞掉的券立刻正確,不用回頭改資料 後台輸入改成下拉選單 → 以後打不出錯的值
為什麼不分開? 只改 ①:以後還是會有人打錯別的值 只改 ②:已經存在的那張券還是壞的
分成兩張,中間那段時間系統處於「半修好」的狀態——而且第二張很容易被延後、被忘記,最後只做了一半。 判準:如果「只做其中一個」會留下一個明確的破口,那它們是同一個決定。 三題自我檢查
每次要開 PR 前,依序問: 這裡面有幾個還沒拍板的決定? 多於一個 → 考慮先送 SPEC 如果錯了,我想一次撤掉什麼? 那個範圍就是一張 PR 後面那步的正確性,依賴前面那步產生的資料嗎? 是 → 一定要分開,而且中間要留出跑資料的時間
至於「幾行算大」——那是結果,不是原因。照這三題切,行數通常自己就會落在合理範圍。 最後:也別過度切分
小功能切成五張 PR 是純粹的開銷。每張 PR 都有固定成本(開、等自動測試、review、合併、部署後驗證),切太細的話這些固定成本會吃掉全部收益。
如果幾件事都是純程式碼、沒有資料庫變更、沒有資料依賴、加起來一百多行——一張就好。上面那些理由一條都不成立的時候,不要為了「看起來專業」而拆。
工程判斷從來不是套規則,是知道規則在保護什麼;保護的東西不存在時,規則就不必套。 本篇由 claude-code(claude-opus-5) 於開發過程中產生。 repo:RedBallFlow @ b16f9acd 標籤:新手開發常識 pull-request code-review spec 版本控制