Lesstep
Azure DevOps Services・Server・プルリクの差分・2026年11月2日に確認

Azure DevOps のプルリクに、ターゲットブランチへもう入った変更が出る

Azure Repos のプルリクの Files タブは、ソースブランチを「今のターゲットブランチ」と比べてはいません。比べる相手はマージベース、つまり2つのブランチが共有している最後のコミットです。別の道でターゲットに入った変更は、この共有の履歴に入らないので、もう一度出てきます。いちばん多いのは、同じブランチからの前のプルリクをスカッシュマージした場合です。完了して変わるのは新しい分だけです。下に、完了で本当に何が変わるかの見方と、プルリクにそれだけを出す直し方を書きます。

Azure DevOps が比べているもの

Microsoft の マージ戦略とスカッシュ マージのページによると、Files タブは3点の比べ方で変更を見つけます。ターゲットブランチの最後のコミット、ソースブランチの最後のコミット、その2つの共通のマージベースです。ファイルの一覧は、そのマージベースからソースが変えた分です。

完了で実際に何が変わるかは、別の画面にあります。プルリクの Overview で右上の More options(…)を開き、View merge changes を選ぶと、試しに作ったマージコミットの差分が出ます。その後にターゲットブランチが進んでいたら、Restart merge で作り直します(Microsoft のpull request を完了、破棄、または元に戻す)。

手元で同じ2つを見るには:

git fetch
git diff --stat origin/main...origin/feature
git diff --stat origin/main $(git merge-tree --write-tree origin/main origin/feature | head -1)

1つ目が Files タブの一覧、2つ目(git 2.38 以降)がマージで変わる分です。1つ目のほうが多くのファイルを出すなら、その差の分はターゲットにもう入っています。

前にスカッシュマージしたブランチ

スカッシュマージはターゲットに新しいコミットを1つ足すだけで、そのコミットはソースブランチを指していません。そのためマージベースは元の位置に残ります。Microsoft は、スカッシュマージの後はソースブランチを消すよう勧めていて、Complete pull request の画面の Delete <ブランチ> after merging がそのための選択です。ブランチを残してコミットを足すと、そのブランチからの次のプルリクに、スカッシュした変更がまた出ます。11月2日の試し(git 2.53)では、5つのファイルをスカッシュマージしてから1つ足すと、3点の diff は6ファイル、本当のマージは1ファイルでした。

そのブランチを一度直すには、ターゲットをブランチにマージして push します。Microsoft も、ブランチを1つの共通の祖先に結び直す方法として、ターゲットの上へのリベースか、ターゲットのマージの2つを挙げています。

git switch feature
git merge origin/main
git push

これでターゲットの最新のコミットがマージベースになり、プルリクには新しいコミットの分だけが出ます(同じ試しで6ファイルが1ファイルに)。スカッシュしたファイルをその後ブランチでまた変えていると、このマージはそのファイルで止まります(試しでは CONFLICT (add/add))。そのファイルはブランチの側を残します。このマージの間は git checkout --ours <ファイル> でブランチの側になります。続けて git add と git commit。根本から避けるなら、スカッシュマージは後で消すブランチだけに使い、長く使うブランチはマージコミットでマージします(Azure DevOps のマージの種類)。

スカッシュマージしたブランチの上に作ったブランチ

feature-b を feature-a から作り、feature-a を main へスカッシュマージしたら、feature-b のプルリクに feature-a の変更まで出るようになった場合です。ターゲットを main に変えても直りません。マージベースが古いままだからです。feature-b 自身のコミットだけを main の上へ移します:

git switch feature-b
git rebase --onto origin/main {feature-a の最後のコミット} feature-b
git push --force-with-lease

feature-a の最後のコミットは、完了したプルリクの Commits タブのいちばん新しいコミットです。試しでは、差分が2ファイルから1ファイルになりました。この push はブランチを書き換えるので、Force push (rewrite history, delete branches and tags) の権限が要ります。無ければ Azure DevOps は TF401027 で断ります。

「Multiple merge bases detected」

マージベースが2つ以上見つかると、プルリクに「Multiple merge bases detected. The list of commits displayed might be incomplete.」(マージベースが複数ある。出ているコミットの一覧は欠けているかもしれない)と出ます。Microsoft が挙げる主な原因は、ブランチどうしの交差したマージ、1つのブランチをほかの2つへマージすること、リバート、機能ブランチの使い回しです。この確かめ方は、候補のマージベースがもうマージ済みかどうかを見ません。そのため git merge-base --all origin/main origin/feature が1行しか出さなくても、この文が出ることがあります。

Microsoft はこれを、見え方だけでなく安全の問題として扱っています。ターゲットにもう入った変更は Files タブには出ますが、フォルダーに結びつけたブランチポリシー(あるパスの必須レビュー担当者など)を動かさないことがあります。直し方は上と同じで、ターゲットをブランチにマージするか、ターゲットの上へリベースし、Files タブを見直します。

IntelliJ IDEA と Rider で Azure DevOps のプルリクを

Azure DevOps Pull Requests は、Lesstep が作っている JetBrains IDE(2024.1 以降)と Android Studio のプラグインです。プルリクのファイルを IDE の差分ビューアーに、Files タブと同じくマージベースから比べて出します(Azure DevOps Services・Azure DevOps Server)。プルリクのブランチをチェックアウトでき(Checkout)、上のコマンドはそこで打てます。push の後は、前回のレビューから変わったところを出します。レビューの受信箱と差分は無料、投票・コメント・完了・作成は Pro(月 US$1・30日間の無料試用つき)です。画面は日本語です。

JetBrains Marketplace で入れる

Azure DevOps と Azure Repos は Microsoft Corporation の商標、IntelliJ IDEA と Rider は JetBrains s.r.o. の商標です。このページは Microsoft・JetBrains のいずれとも提携しておらず、承認も受けていません。

ほかに:Azure DevOps のマージの種類 · 前回のレビューからの変更 · マージ競合 · English