閱讀英文

共用方式為


設定提取要求的目標分支

Azure DevOps Services

根據預設,Azure DevOps 會建議針對預設分支建立新的提取要求。 在有多個分支用於提取要求的存放庫中,存放庫擁有者可以設定提取要求目標分支的清單,因此這些建議會選取適當的目標分支。

若要啟用此功能,請在存放庫的預設分支中建立名稱 .azuredevops/pull_request_targets.yml 為的檔案。 此 YAML 檔案應該包含標題 pull_request_targets為 的單一清單,其中包含符合候選分支的分支名稱或前置詞。

例如,請考慮下列內容:

pull_request_targets:
  - main
  - release/*
  - feature/*

此潛在目標清單會指定要main先選取的目標分支,但如果以 或 feature/ 為較佳選擇的分支release/,則會改為選擇該分支。

如需更多提取要求指導方針和管理考慮,請參閱 關於提取要求

何時使用此組態?

使用動態目標分支有多個進入點。

  • 提取要求建議。 當使用者將分支推送至 Azure DevOps 時,其下一次造訪 Repos 頁面可能會建議從該分支建立提取要求。 這個 [建立新的提取要求] 按鈕會動態選擇目標分支。

  • 提取要求URL。 當使用者使用 sourceRef 參數直接流覽至提取要求建立頁面,但省略 targetRef 參數時,Azure DevOps 會根據這個動態選擇選取目標分支。

用戶端工具可以使用這個動態選擇來建立提取要求的功能,但這些用戶端需要新增選擇性訊號,指出使用者未指定目標分支。 請檢查您選擇的用戶端工具,以查看選項是否已啟用。

分支目標有哪些好候選專案?

建議已設定的候選分支清單只包含受提取要求原則保護的分支。 這類分支可能只會藉由完成提取要求來變更,這可確保先前的分支位置位於提示認可的第一個父代歷程記錄中。 如果使用合併策略,則第二個父代代表藉由完成提取要求,而第一個父系是先前的提示來導入目標分支的認可。

Azure DevOps 如何挑選分支?

Git 不會追蹤建立分支的元數據。 無法確切判斷建立主題分支時所使用的分支。 相反地,Azure DevOps 會根據分支的第一個父代歷程記錄來使用啟發學習法。

在可能的目標分支中,Azure DevOps 會選取其第一個父系歷程記錄與來源分支第一個父系歷程記錄相交的分支。

範例:沒有合併認可

請考慮下列分支結構,因為沒有合併認可,因此會比平常簡化。 在此範例中,整個歷程記錄是由第一個父代歷程記錄表示。

  ,-E---F <-- release/2024-September
 /
A---B---C---D <--- main
     \
      `-G---H <--- feature/targets
         \
          `-I <--- topic

在此歷程記錄和先前使用的範例 pull_request_targets 清單中,我們有三個候選目標分支,優先順序如下:

  • main
  • release/2024-September
  • feature/targets

然後,來源分支 topic會與這些分支進行比較。

  • maintopic at B交集,留在 G,Itopic ,而不是 在 中 main
  • release/2024-Septembertopic A 在 離開 B,G,Itopic 相交,而不是 在 中 release/2024-September
  • feature/targetstopic at G交集,留在 Itopic ,而不是 在 中 feature/targets

因此,在此範例中,會 feature/targets 選擇分支做為提取要求的目標分支,並 topic 做為來源分支。

範例:合併認可

在更複雜的範例中 feature/targets ,當分支合併並 main 合併 main 到本身時,認可歷程記錄會考慮更多案例:

  ,-E---F <-- release/2024-September
 /
A---B---C---D---J---K <--- main
     \    _/     \
      \  /        \
       `G---H---L--\--M <--- feature/targets
         \          \/
          \
           `I <--- topic

在這裡,中的main認可D代表feature/targets合併到 main的時間。 認可M代表合併到 feature/targets的時間main。 認可 MJ 之間的連結是以強調 J 為第二個父系 M 的方式繪製,而 L 是的第一個父系。

在這裡情況下,當您考慮完整認可歷程記錄, mainfeature/targets 兩者都與 的歷程記錄 topic 交集於 G。 不過,第一個父系歷程記錄仍然示範 的 feature/targets喜好設定。

中斷系結

如果兩個分支具有相同的第一個父代歷程記錄交集,則 Azure Devops 會選取先前出現在 pull_request_targets 清單中的分支。 如果由於前置詞相符而仍根據 pull_request_targets 清單系結多個分支,則最早的依字母順序獲勝。

建立新的候選分支時,通常會有這類關聯性,例如新功能分支的開頭或發行分支的分支。

          ,-E---F <-- release/2024-October
         /
A---B---C---D <--- main
     \
      \
       `G <--- topic

在此範例中,release/2024-October分支是在 分支關閉 main之後topicmain 分支建立的。 雖然這是人類讀者的直覺式,但清單中的 和 release/* 類別pull_request_targets順序main表示 Azure DevOps 慣用的順序。

如果 Azure DevOps 選擇錯誤的目標分支,該怎麼辦?

如果動態選擇不符合預期,提取要求建立頁面具有調整目標分支的選取器。 建立提取要求之後,也可以調整目標分支。

更重要的是,瞭解啟發學習法可能選取「錯誤」目標分支的原因可能很有價值。

此啟發學習法依賴一些關於如何建立目標分支和來源分支的假設。 以下是啟發學習法無法運作的一些可能原因:

  • 目標分支不受提取要求原則保護。 如果可以任意推送目標分支,則第一個父系歷程記錄不是該分支先前位置的可靠指標。

  • 來源分支是從候選分支的前一個秘訣建立。 如果來源分支在歷程記錄中選擇任意認可,則不保證其相依的第一個父代歷程記錄。

  • 來源分支已使用 git commitgit merge 命令進行進階。 例如或 git rebase 之類的git reset --hard命令可能會以無法預測的方式變更分支的歷程記錄。

如果您不同意此啟發學習法選擇的目標分支,請考慮使用 git rebase --onto <new-target> <old-target> <source>更新選擇。 命令會 git rebase 重寫第一個父代歷程記錄,讓啟發學習法選擇新的目標。

用戶在意識到其以錯誤的分支為基礎時所犯的一個常見錯誤,就是使用 git merge 將正確的分支帶入其歷程記錄。 合併不會變更第一個父系歷程記錄,因此不會變更目標分支的選擇。

如何在本機測試此決策?

Azure DevOps 所使用的啟發學習法會參與核心 Git 用戶端,並可在 Git 2.47.0 版和更新版本中取得。

若要在您自己的存放庫中測試此邏輯,請先執行 git fetch origin 以確定您有最新版的目標分支。 然後,執行下列 git for-each-ref 命令,並調整以符合候選分支清單:

$ git for-each-ref --format="%(is-base:HEAD) %(refname)" \
           refs/remotes/origin/main \
           "refs/remotes/origin/release/*" \
           "refs/remotes/origin/feature/*"
 refs/remotes/origin/main
 refs/remotes/origin/release/2024-September
(HEAD) refs/remotes/origin/feature/targets

在此命令中,認可 HEAD 會當做來源使用,並以相同方式比較目標分支的第一個父代歷程記錄。 雖然每個候選分支都會列在輸出中,但字串 (HEAD) 會指出應該使用哪一個分支作為目標分支。

下一步