Private/Resolve-DiffRange.ps1

function Resolve-DiffRange {
    <#
    .SYNOPSIS
    Resolves the two commits the review diffs: the base and the commit that was built.

    .DESCRIPTION
    Single source of truth for the diff base of Get-ChangedFiles and Get-FileDiff, so the file list
    and the per-file diff sent to the model can never use different ranges.

    - PR build (BUILD_REASON = PullRequest) on a merge commit (refs/pull/<id>/merge): base = the
      merge commit's first parent, i.e. the target branch exactly as it was when the build's merge
      was made - what the build compiled. The target branch's current tip is irrelevant, so commits
      merged into the target while the build runs never enter the review. The first parent is
      always in the clone once the merge commit is (a shallow merge-base is not needed).
    - Anything else: base = merge-base of the target branch and the compare commit (three-dot).
      Missing merge-base (shallow clone): deepen once; still missing: skip.
    - Never a two-dot range against a branch tip, and never another commit than the one built:
      if the compare commit or the base cannot be resolved, the result is Skip with a reason.

    .PARAMETER BaseBranch
    Target branch for the non-merge fallback (e.g. 'origin/master' or 'master'). In a PR build
    SYSTEM_PULLREQUEST_TARGETBRANCH overrides it.

    .PARAMETER CompareRef
    The commit to review. Default: BUILD_SOURCEVERSION, else HEAD.

    .PARAMETER Fetch
    Allow fetching the target branch when it is missing (fallback path only). Get-ChangedFiles
    passes it; Get-FileDiff runs after it and only reads what is already there.

    .OUTPUTS
    PSCustomObject: Skip, Reason, Base, Compare, Mode ('MergeParent' | 'MergeBase'), Label, BaseBranch

    .NOTES
    Author: waldo
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $false)]
        [string]$BaseBranch = 'origin/master',

        [Parameter(Mandatory = $false)]
        [string]$CompareRef = '',

        [Parameter(Mandatory = $false)]
        [switch]$Fetch
    )

    $result = [pscustomobject]@{
        Skip       = $false
        Reason     = ''
        Base       = $null
        Compare    = $null
        Mode       = $null
        Label      = ''
        BaseBranch = $BaseBranch
    }

    if (-not $CompareRef) {
        $CompareRef = if ($env:BUILD_SOURCEVERSION) { $env:BUILD_SOURCEVERSION } else { 'HEAD' }
    }

    # The commit that was built must be in the clone - never review another commit instead.
    $compareSha = git rev-parse --verify --quiet "$CompareRef^{commit}" 2>$null
    if ($LASTEXITCODE -ne 0 -or -not $compareSha) {
        $result.Skip = $true
        $result.Reason = "Compare commit $CompareRef is not present in the clone"
        return $result
    }
    $compareSha = "$compareSha".Trim()
    $result.Compare = $compareSha

    if ($env:BUILD_REASON -eq 'PullRequest') {
        # A shallow boundary hides the parents of the merge commit: deepen once.
        $parents = @((git rev-list --parents -n 1 $compareSha 2>$null) -split ' ' | Select-Object -Skip 1)
        if ($parents.Count -eq 0 -and (git rev-parse --is-shallow-repository 2>$null) -eq 'true') {
            Write-Verbose "Merge commit $compareSha is at the shallow boundary - deepening once"
            git fetch --quiet --deepen=1 origin 2>&1 | Out-Null
            $parents = @((git rev-list --parents -n 1 $compareSha 2>$null) -split ' ' | Select-Object -Skip 1)
        }
        if ($parents.Count -ge 2) {
            $result.Base = $parents[0]
            $result.Mode = 'MergeParent'
            $result.Label = 'merge parent 1'
            return $result
        }
        Write-Verbose "PR build but $compareSha is not a merge commit - falling back to the merge-base"
    }

    # Fallback (not a PR merge commit): three-dot against the target branch.
    if ($env:SYSTEM_PULLREQUEST_TARGETBRANCH) {
        $BaseBranch = 'origin/' + ($env:SYSTEM_PULLREQUEST_TARGETBRANCH -replace '^refs/heads/', '')
    }
    $branchName = $BaseBranch -replace '^origin/', ''
    $candidates = @($BaseBranch, "origin/$branchName", $branchName) | Select-Object -Unique

    $baseTip = $null
    foreach ($attempt in 1..2) {
        foreach ($candidate in $candidates) {
            $sha = git rev-parse --verify --quiet "$candidate^{commit}" 2>$null
            if ($LASTEXITCODE -eq 0 -and $sha) {
                $baseTip = "$sha".Trim()
                $result.BaseBranch = $candidate
                break
            }
        }
        if ($baseTip -or -not $Fetch -or $attempt -eq 2) { break }
        Write-Verbose "Fetching $branchName from origin..."
        git fetch --quiet origin "${branchName}:refs/remotes/origin/${branchName}" 2>&1 | Out-Null
    }
    if (-not $baseTip) {
        $result.Skip = $true
        $result.Reason = "Target branch $BaseBranch is not present in the clone"
        return $result
    }

    $mergeBase = git merge-base $baseTip $compareSha 2>$null
    if ($LASTEXITCODE -ne 0 -or -not $mergeBase) {
        Write-Verbose "No merge-base of $baseTip and $compareSha in the shallow clone - deepening once"
        git fetch --quiet --deepen=200 origin 2>&1 | Out-Null
        $mergeBase = git merge-base $baseTip $compareSha 2>$null
    }
    if ($LASTEXITCODE -ne 0 -or -not $mergeBase) {
        $result.Skip = $true
        $result.Reason = "No merge-base of $($result.BaseBranch) and $compareSha (shallow clone)"
        return $result
    }

    $result.Base = "$mergeBase".Trim()
    $result.Mode = 'MergeBase'
    $result.Label = "merge-base with $($result.BaseBranch)"
    return $result
}