合併策略和壓縮合併

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

當您完成提取要求時,通常會將主題分支合併至預設分支。main 此合併會將主題分支的認可新增至主要分支,並建立合併認可來協調預設與主題分支之間的任何衝突。 提取要求中的批注和討論會提供主題分支中所做的變更的其他內容。

提取要求中的一般合併範例。

分支main上的認可歷程記錄(或其他預設分支)不會遵循直線,因為相關的主題分支歷程記錄。 當專案變大時,同時處理的主題分支數目會增加,使得預設分支歷程記錄越來越難以遵循。

默認分支是每個主題分支歷程記錄的準確表示法,但很難用來回答有關您專案開發的廣泛問題。

Squash merge

Squash 合併是一個合併選項,可讓您在完成提取要求時壓縮主題分支的 Git 歷程記錄。 squash merge 會將主題分支上的每個認可新增至預設分支的歷程記錄,而是會將所有檔案變更新增至預設分支上的單一新認可。 Squash 合併認可沒有主題分支的參考,它會產生包含 主題分支中所有變更的新認可 。 此外,建議您刪除主題分支,以避免發生任何混淆。

Azure Repos 中提取要求中的壁球合併圖表。

一個簡單的思考方式是,壁球合併可讓您只提供檔案變更,而一般合併會提供檔案變更和認可歷程記錄。

壁球合併如何有説明?

Squash 合併會讓您的預設分支歷程記錄保持乾淨且易於遵循,而不需要對小組進行任何工作流程變更。 主題分支的參與者在主題分支中的運作方式,而預設分支會透過使用 squash 合併來保留線性歷程記錄。 使用 squash 合併更新之分支的認可 main 歷程記錄,每個合併分支都有一個認可。 您可以逐步執行此歷程記錄,以找出工作完成時間。

壁球合併時的考慮

Squash 合併會壓縮預設分支中變更的歷程記錄,因此請務必與小組合作,決定何時應壓縮合併,或當您想要保留主題分支的完整認可歷程記錄時。 當壓縮合併時,最好刪除來源分支。 刪除來源分支可防止混淆,因為主題分支本身沒有將它合併至預設分支的認可。

使用 squash merge 完成提取要求

在 Azure Repos 中完成提取要求時,您可以選擇將合併壓縮。

在 [完成提取要求] 對話框中,選擇 [合併類型] 下的 [Squash 認可],以壓縮主題分支。

在 Azure Repos 中關閉具有 squash 合併之提取要求的螢幕快照。

多個合併基底

提取要求中的 [ 檔案 ] 索引卷標會透過三端比較來偵測差異。 演算法會考慮目標分支中的最後一個認可、來源分支中的最後一個認可,以及其 通用合併基底 (也就是最佳通用上階)。 此演算法是偵測變更的快速、符合成本效益且可靠的方法。 不幸的是,在某些情況下,有一個以上的真實基礎。 在大部分的存放庫中,這種情況很少見,但在具有許多作用中使用者的大型存放庫中,可能很常見。 您可以手動檢查分支之間的多個合併基底是否存在。 若要這樣做,請執行 git merge-base --all feature master 命令。 Azure DevOps 會偵測每個 PR 有多個合併基底存在。 偵測到這些專案時,Azure DevOps 會顯示「偵測到多個合併基底」訊息。 PR 顯示的認可清單可能不完整。 雖然 Azure DevOps 正在執行多個合併基底的偵測,但不會檢查潛在的合併基底是否已合併。 這類檢查是由 git merge-base完成。 這就是為什麼即使只報告一個合併基底, git merge-base Azure DevOps 仍可能會顯示訊息。

注意

如果您在PR檢閱期間遺失變更,請確定多個合併基底不是根本原因。

Azure DevOps 偵測到下列案例為多個基底(合併基底以數位 1 和 2 表示):

  • 不同分支之間的交叉合併(也稱為交叉)(由 Azure DevOps 報告,以及 git merge-base
---1---o---A
    \ /
     X
    / \
---2---o---o---B
  • 將一個分支合併至其他兩個分支(由 Azure DevOps 回報,但不會由 git merge-base 合併基底 2 所報告)
---1---o---o---o---A
    \         /
     \-------2
      \       \
       \---o---o---o---B
  • 處理主要分支的後置處理會還原,例如修改合併認可
*   42bb2d2 (HEAD, A) Amended merge commit
|\  
| | *   67c9bb8 (other) Merge branch 'A' into B
| | |\  
| |/ /  
|/| /   
| |/    
| * fa78e32 add second commit
* | 15845c9 add first commit
|/  
* 6a52130 add init
  • 主動重複使用功能分支
  • 還原、櫻桃挑選和合併的其他非直覺式和卷積操作

多重合併基底偵測是安全性感知的一部分。 如果有多個合併基底,使用者介面的檔案差異演算法可能無法正確偵測檔案變更,視它選擇的合併基底而定。 如果提取要求中的檔案在合併基底之間有不同的版本,就會發生多個合併基底警告。

如需詳細資訊,請檢閱 官方 Git 檔

從多個基底合併的潛在安全性風險

  • 惡意使用者可能會濫用 UI 演演算法來認可 PR 中不存在的惡意變更。
  • 如果 PR 中提議的變更已經在目標分支中,它們會顯示在 [檔案] 索引標籤中,但可能不會觸發對應至資料夾變更的分支原則。
  • 來自多個合併基底之相同檔案的兩組變更可能不會出現在PR中。 這種情況可能會造成危險的邏輯差距。

如何解決多個合併基底問題

有多個合併基底不一定不好,但您應該仔細檢查一切是否正常。 若要擺脫多個合併基底,請將分支系結至單一通用上階,方法是將分支重新放入目標上,或將目標合併至您的分支。 這些動作會清除警告訊息,並協助您檢查實際變更是否正常。

其中一種方法是在重新重設或合併之前,先將進度虛設並隱藏。 然後,您可以建立新的分支或重新建立空白分支,並從清除點套用變更。 如果您的變更已經存在,此程式可能需要強制推送至遠端。

如何避免多個合併基底問題

以下是避免多個合併基底問題的一般秘訣:

  • 準備提取要求時,請從最新版的主要或發行分支建立功能分支。
  • 除非必要,否則請避免建立不會直接源自存放庫穩定分支的分支。

如果多個合併基底問題再次出現,該怎麼辦

在具有許多作用中參與者的大型存放庫中,此問題特別不方便。 即使您透過合併擺脫多個基底,這種情況也可能重新出現。 如果有人關閉長期提取要求,則可以重新建立情況。 即使建置原則和測試正在執行,您也沒有任何方法可以完成提取要求。 重設和啟動新分支可能會有所説明。 如果沒有任何變更,即使情況重複,您的變更可能也很清楚。

下一步