Private/Get-PullRequestUrl.ps1
|
function Get-PullRequestUrl { <# .SYNOPSIS Builds a provider-specific pull/merge request creation URL from a git remote URL and branch. .DESCRIPTION Supports GitHub, Azure DevOps (dev.azure.com and *.visualstudio.com), Bitbucket Cloud, and GitLab. Both HTTPS and SSH remote formats are accepted. Returns the base remote URL for unrecognised providers so the user can navigate manually. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string] $RemoteUrl, [Parameter(Mandatory)] [string] $Branch, # Optional target/base branch (used by Azure DevOps) [string] $BaseBranch ) # Normalize Azure DevOps SSH: git@ssh.dev.azure.com:v3/org/project/repo if ($RemoteUrl -match '^git@ssh\.dev\.azure\.com:v3/([^/]+)/([^/]+)/(.+?)(?:\.git)?/?$') { $RemoteUrl = "https://dev.azure.com/$($Matches[1])/$($Matches[2])/_git/$($Matches[3])" } # Normalize generic SSH: git@host:owner/repo.git elseif ($RemoteUrl -match '^git@([^:]+):(.+?)(?:\.git)?/?$') { $RemoteUrl = "https://$($Matches[1])/$($Matches[2])" } # Strip trailing .git from HTTPS URLs $RemoteUrl = $RemoteUrl -replace '\.git/?$', '' # GitHub — branch is a path segment, slashes are preserved if ($RemoteUrl -match '//github\.com/') { return "$RemoteUrl/compare/$Branch`?expand=1" } # For query-string providers the branch must be fully URL-encoded (including /) $encodedBranch = [Uri]::EscapeDataString($Branch) # Azure DevOps (modern and legacy visualstudio.com hostname) if ($RemoteUrl -match '//dev\.azure\.com/|//[^/]+\.visualstudio\.com/') { $targetParam = if ($BaseBranch) { "&targetRef=$([Uri]::EscapeDataString($BaseBranch))" } else { '' } return "$RemoteUrl/pullrequestcreate?sourceRef=$encodedBranch$targetParam" } # Bitbucket Cloud if ($RemoteUrl -match '//bitbucket\.org/') { return "$RemoteUrl/pull-requests/new?source=$encodedBranch" } # GitLab if ($RemoteUrl -match '//gitlab\.com/|/gitlab\.') { return "$RemoteUrl/-/merge_requests/new?merge_request%5Bsource_branch%5D=$encodedBranch" } # Unknown provider — return the repo root so the user can navigate manually return $RemoteUrl } |