介紹
Git 歷史記錄是您的團隊和未來的您的溝通工具。乾淨、可讀的歷史記錄使調試、程式碼審查和發布管理變得更加容易。擠壓合併是維護乾淨歷史的主要策略之一,但了解何時以及如何使用它以及何時選擇替代方案需要了解所涉及的權衡。本文提供了團隊壓縮合併策略的綜合指南。
壁球合併機制
擠壓合併將來自功能分支的所有提交合併到目標分支上的單一提交。考慮一個具有提交 C、D 和 E 的功能分支,需要將其合併到主分支中:
Before squash:
main: A---B---F---G
/
feature: C---D---E
After squash merge:
main: A---B---F---G---H
(H contains changes from C, D, and E as one commit)
執行擠壓合併的命令:
git merge --squash feature-branch
git commit -m "feat: add user authentication"
擠壓合併的主要特徵:
- 所有單獨的提交都被折疊成一個新的提交
- 功能分支本身不合併(不建立合併提交)
- 原始提交歷史記錄保留在功能分支上
- 新提交會收到您提供的訊息
擠壓、合併、變基
每種策略都有不同的目的,了解何時使用每種策略對於團隊協調至關重要。
| 戰略 | 歷史影響 | 溯源 | 最適合 |
|---|---|---|---|
| 合併 | 保留所有提交+合併提交 | 完整,按時間順序 | 標準協作 |
| 壁球 | 每個功能單次提交 | 乾淨、線性 | 面向發布的工作流程 |
| 變基 | 線性化、改寫歷史 | 乾淨但丟失時間戳 | 單獨提交清理 |
當單一提交未完成或混亂時,使用擠壓合併,每個功能都應該是一個邏輯單元,並且您不需要主分支上的每次提交歸因。 當每次提交都是有意義且原子的,您需要保留時間順序,或者多個貢獻者在一個分支上協作時,請使用常規合併。 當您想要在共享之前清理提交或需要一次解決一個提交的衝突時,請使用變基。
GitHub Squash 合併設置
GitHub 在「設定」→「合併」按鈕下的儲存庫層級提供了可設定的壓縮合併選項。預設的壓縮訊息可以配置為拉取請求標題加描述、拉取請求標題加提交清單或自訂格式。分支保護規則可以透過要求壓縮合併和防止合併提交來強制執行線性歷史記錄,確保主分支始終保持乾淨的線性歷史記錄。
互動式變基替代方案
在透過合併進行壓縮之前,開發人員可以使用互動式變基來更好地控制提交歷史記錄:
git rebase -i HEAD~5
互動式 rebase 介面提供了幾個命令:
| 命令 | 行動 |
|---|---|
| 佔位符_0 | 原樣使用提交 |
| 佔位符_0 | 更改提交訊息 |
| 佔位符_0 | 與先前的提交結合,合併訊息 |
| 佔位符_0 | 與先前的提交合併,丟棄訊息 |
| 佔位符_0 | 完全刪除提交 |
| 佔位符_0 | 停止修改commit內容 |
最佳實踐包括在推送到共享分支之前進行變基,永遠不要對遠端共享分支上存在的提交進行變基,以及在開發過程中使用 fixup 進行細微修正。
提交訊息約定
無論合併策略如何,精心設計的提交訊息都是必不可少的。常規提交格式已被廣泛採用:
feat(api): add user authentication endpoint
Implement OAuth 2.0 authentication with refresh token support.
- Add login endpoint with email/password validation
- Implement JWT token generation and verification
- Add refresh token rotation for security
Closes #123
常見類型包括用於新功能的 feat:、用於錯誤修復的 fix:、用於維護的 chore:、用於文件的 docs:、用於程式碼重組的 refactor: 以及用於測試新增的 test:5__。透過擠壓合併,最終的提交訊息變得至關重要,因為各個提交訊息被合併為一個。
團隊工作流程整合
成功的擠壓合併採用需要團隊在多個維度上保持一致:
- 定義分支策略:在 Git Flow、GitHub Flow 或基於主幹的開發之間進行選擇
- 設定合併策略:為所需策略配置儲存庫設置
- 文件約定:建立提交訊息格式和 PR 標題標準
- 自動執行:使用 CI 檢查提交訊息格式和分支規則
- 培訓團隊:為壓縮、變基和衝突解決提供入職指導
在典型的 GitHub Flow 整合中,功能分支是從 main 創建的,開發人員變基以維護乾淨的 WIP 歷史記錄,並且拉取請求被壓縮合併到 main。這確保了 main 始終具有線性、原子提交。
常見陷阱
擠壓合併並非沒有風險。 遺失上下文是最常見的問題 - 單一提交詳細資訊在壓縮後遺失,因此 PR 描述必須捕獲完整的上下文。 惰性壓縮 將不相關的變更合併到一次提交中,從而使偵錯變得更加困難。 先變基然後壓縮是多餘的並且浪費精力。 合併衝突在壓縮前解決,失去衝突解決上下文。團隊應該意識到這些陷阱並建立實踐來緩解它們。
結論
Squash merge 是一個強大的工具,用於維護乾淨的 git 歷史記錄,但它作為深思熟慮的工作流程策略的一部分效果最好。團隊應該討論並商定他們的方法:何時壓縮、何時合併以及哪些資訊必須保留在提交訊息中。正確的策略取決於您的團隊規模、發布節奏以及調試和審計追蹤所需的詳細程度。

