プル要求のターゲット ブランチを構成する
Azure DevOps Services
既定では、Azure DevOps は、既定のブランチに対して新しいプル要求を作成するよう提案します。 プル要求に複数のブランチが使用されているリポジトリでは、リポジトリの所有者が pull request ターゲット ブランチの一覧を構成して、これらの提案で適切なターゲット ブランチを選択できます。
この機能を有効にするには、リポジトリの既定のブランチに.azuredevops/pull_request_targets.yml
名前のファイルを作成します。
この YAML ファイルには、候補の分岐に一致するブランチ名またはプレフィックスを含む、 pull_request_targets
というタイトルの 1 つのリストが含まれている必要があります。
たとえば、次の内容を考えてみましょう。
pull_request_targets:
- main
- release/*
- feature/*
このターゲットの一覧では、最初に選択するターゲット ブランチとして main
を指定しますが、 release/
または feature/
で始まるブランチの方が適している場合は、代わりにそのブランチが選択されます。
pull request のガイドラインと管理に関する考慮事項の詳細については、「 プル要求についてを参照してください。
この構成はいつ使用されますか?
動的ターゲット ブランチを使用するには、複数のエントリ ポイントがあります。
Pull Request Suggestions。 ユーザーが Azure DevOps にブランチをプッシュすると、次に [Repos] ページにアクセスすると、そのブランチからのプル要求の作成が提案される場合があります。 この [Create New Pull Request]\(新しいプル要求の作成\) ボタンは、ターゲット ブランチを動的に選択します。
Pull Request URL。 ユーザーが
sourceRef
パラメーターを使用して pull request 作成ページに直接移動し、targetRef
パラメーターを省略すると、Azure DevOps はこの動的な選択に基づいてターゲット ブランチを選択します。
クライアント ツールには、この動的な選択を使用してプル要求を作成する機能がありますが、これらのクライアントは、ユーザーがターゲット ブランチを指定しなかったことを示すオプションのシグナルを追加する必要があります。 オプションが有効になっているかどうかを確認するには、選択したクライアント ツールを確認します。
ブランチ ターゲットに適した候補は何ですか?
構成されている候補ブランチの一覧には、プル要求ポリシーによって保護されているブランチのみが含まれていることをお勧めします。 このような分岐は、プル要求を完了することによってのみ変更される可能性があります。これにより、前の分岐位置がチップコミットの最初の親履歴に含まれることが保証されます。 マージ戦略が使用されている場合、2 番目の親はプル要求を完了することによってターゲット ブランチに導入されるコミットを表し、最初の親は前のヒントです。
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
リストでは、優先度順に次の 3 つの候補ターゲット ブランチがあります。
main
release/2024-September
feature/targets
ソース ブランチ ( topic
) は、これらのブランチと比較されます。
main
はB
でtopic
と交差し、G,I
はmain
ではなくtopic
に残ります。release/2024-September
は、release/2024-September
ではなくtopic
にB,G,I
を残すA
でtopic
と交差します。feature/targets
はG
でtopic
と交差し、I
はfeature/targets
ではなくtopic
に残ります。
したがって、この例では、 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
は、 main
が feature/targets
にマージされた時刻を表します。 コミット M
と J
の間のリンクは、 J
が M
の 2 番目の親であり、 L
が最初の親であることを強調する方法で描画されます。
この場合、完全なコミット履歴を考慮すると、main
とfeature/targets
の両方が、G
のtopic
の履歴と交差します。 ただし、最初の親履歴は、引き続き feature/targets
の優先設定を示しています。
タイを破る
2 つのブランチの最初の親の履歴の積集合が同じである場合、Azure Devops は、 pull_request_targets
の一覧の前に表示されたブランチを選択します。 プレフィックスの一致が原因で pull_request_targets
リストに基づいて複数の分岐が引き続き関連付けられている場合は、アルファベット順の最も早い方が優先されます。
新しい機能ブランチの開始やリリース ブランチのフォークなど、新しい候補ブランチが作成されるときに、これらの種類のタイが最も多く存在します。
,-E---F <-- release/2024-October
/
A---B---C---D <--- main
\
\
`G <--- topic
この例では、topic
が main
から分岐した後、main
ブランチから release/2024-October
ブランチが作成されました。 これは人間の読者には直感的ですが、pull_request_targets
リストのmain
カテゴリとrelease/*
カテゴリの順序は、Azure DevOps の優先順序を示します。
Azure DevOps が間違ったターゲット ブランチを選択した場合はどうなりますか?
動的な選択が期待値と一致しない場合は、pull request 作成ページにターゲット ブランチを調整するためのセレクターがあります。 プル要求の作成後にターゲット ブランチを調整することもできます。
さらに重要なのは、ヒューリスティックが "間違った" ターゲット ブランチを選択している理由を理解しておくことが重要な場合があります。
このヒューリスティックは、ターゲット ブランチとソース ブランチがどのように作成されたかに関するいくつかの前提条件に依存しています。 ヒューリスティックが機能しない可能性のある理由を次に示します。
ターゲット ブランチは、プル要求ポリシーによって保護されません。 ターゲット ブランチを任意にプッシュできる場合、最初の親履歴は、そのブランチの以前の場所の信頼できるインジケーターではありません。
ソース ブランチは、候補ブランチの前のヒントから作成されました。 ソースブランチが履歴で任意のコミットを選択した場合、それが依存していた最初の親履歴に関する保証はありません。
ソース ブランチは、
git commit
コマンドとgit merge
コマンドを使用して拡張されました。git reset --hard
やgit rebase
などのコマンドは、予測できない方法でブランチの履歴を変更する可能性があります。
このヒューリスティックによって選択されたターゲット ブランチに同意しない場合は、 git rebase --onto <new-target> <old-target> <source>
を使用して選択を更新することを検討してください。 git rebase
コマンドは、最初の親の履歴を書き換えて、ヒューリスティックが新しいターゲットを選択するようにします。
ユーザーが間違ったブランチに基づいていることが分かったときの一般的な間違いの 1 つは、 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)
文字列は、ターゲット ブランチとして使用する分岐を示します。