99 lines
3.3 KiB
PowerShell
99 lines
3.3 KiB
PowerShell
|
|
param(
|
||
|
|
[string]$RepoPath = (Split-Path $PSScriptRoot -Parent),
|
||
|
|
[bool]$AutoStash = $true,
|
||
|
|
[bool]$Push = $true,
|
||
|
|
[ValidateSet('abort','leave')][string]$OnConflict = 'leave'
|
||
|
|
)
|
||
|
|
|
||
|
|
function ExecGit {
|
||
|
|
param([string[]]$ArgList, [bool]$IgnoreError = $false)
|
||
|
|
Write-Host ("git " + ($ArgList -join ' ')) -ForegroundColor Cyan
|
||
|
|
& git @ArgList
|
||
|
|
$code = $LASTEXITCODE
|
||
|
|
if (!$IgnoreError -and $code -ne 0) {
|
||
|
|
throw ("Git command failed ({0}): git {1}" -f $code, ($ArgList -join ' '))
|
||
|
|
}
|
||
|
|
return $code
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
if (!(Test-Path $RepoPath)) { throw ("RepoPath not found: {0}" -f $RepoPath) }
|
||
|
|
Set-Location $RepoPath
|
||
|
|
|
||
|
|
# Ensure git is available
|
||
|
|
ExecGit @('--version') $true | Out-Null
|
||
|
|
|
||
|
|
$currentBranch = (& git rev-parse --abbrev-ref HEAD).Trim()
|
||
|
|
if ([string]::IsNullOrWhiteSpace($currentBranch)) { throw 'Cannot resolve current branch' }
|
||
|
|
Write-Host ("Current branch: {0}" -f $currentBranch) -ForegroundColor Green
|
||
|
|
|
||
|
|
# Check worktree state
|
||
|
|
$statusPorcelain = (& git status --porcelain)
|
||
|
|
$hasChanges = -not [string]::IsNullOrWhiteSpace(($statusPorcelain -join ''))
|
||
|
|
$stashMade = $false
|
||
|
|
if ($hasChanges -and $AutoStash) {
|
||
|
|
Write-Host 'Worktree not clean, auto-stash' -ForegroundColor Yellow
|
||
|
|
ExecGit @('stash','push','-u','-m','auto-stash before merge-main-framework')
|
||
|
|
$stashMade = $true
|
||
|
|
} elseif ($hasChanges -and -not $AutoStash) {
|
||
|
|
throw 'Worktree has uncommitted changes; commit or enable -AutoStash'
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fetch remotes
|
||
|
|
ExecGit @('fetch','--all','--prune')
|
||
|
|
|
||
|
|
# Ensure remote branch exists
|
||
|
|
$remoteRef = (& git ls-remote --heads origin main-framework)
|
||
|
|
if ([string]::IsNullOrWhiteSpace(($remoteRef -join ''))) {
|
||
|
|
throw 'Remote origin/main-framework not found. Check remote and branch name.'
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host ("Merging origin/main-framework -> {0}" -f $currentBranch) -ForegroundColor Green
|
||
|
|
$mergeCode = ExecGit @('merge','--no-ff','origin/main-framework') $true
|
||
|
|
|
||
|
|
# Detect conflicts
|
||
|
|
$unmerged = (& git ls-files -u)
|
||
|
|
$hasConflicts = -not [string]::IsNullOrWhiteSpace(($unmerged -join ''))
|
||
|
|
if ($hasConflicts) {
|
||
|
|
Write-Host ('Conflicts detected. Strategy: {0}' -f $OnConflict) -ForegroundColor Yellow
|
||
|
|
if ($OnConflict -eq 'abort') {
|
||
|
|
ExecGit @('merge','--abort')
|
||
|
|
if ($stashMade) {
|
||
|
|
Write-Host 'Restoring stash (stash pop)' -ForegroundColor Yellow
|
||
|
|
ExecGit @('stash','pop') $true | Out-Null
|
||
|
|
}
|
||
|
|
throw 'Merge aborted. Please resolve conflicts manually and retry.'
|
||
|
|
} else {
|
||
|
|
Write-Host 'Leaving conflict state for manual resolution:' -ForegroundColor Yellow
|
||
|
|
Write-Host '- Edit conflicted files and run: git add <file>'
|
||
|
|
Write-Host '- Then conclude: git commit'
|
||
|
|
if ($stashMade) { Write-Host 'Note: run stash pop after resolving' -ForegroundColor Yellow }
|
||
|
|
exit 2
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($mergeCode -eq 0) {
|
||
|
|
Write-Host 'Merge completed.' -ForegroundColor Green
|
||
|
|
} else {
|
||
|
|
$st = (& git status)
|
||
|
|
Write-Host $st
|
||
|
|
}
|
||
|
|
|
||
|
|
# Pop stash if any
|
||
|
|
if ($stashMade) {
|
||
|
|
Write-Host 'Restoring stash (stash pop)' -ForegroundColor Yellow
|
||
|
|
ExecGit @('stash','pop') $true | Out-Null
|
||
|
|
}
|
||
|
|
|
||
|
|
# Push if requested
|
||
|
|
if ($Push) {
|
||
|
|
Write-Host 'Pushing to remote...' -ForegroundColor Green
|
||
|
|
ExecGit @('push')
|
||
|
|
Write-Host 'Push completed.' -ForegroundColor Green
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host ("Done: origin/main-framework merged into {0}" -f $currentBranch) -ForegroundColor Green
|
||
|
|
} catch {
|
||
|
|
Write-Error $_
|
||
|
|
exit 1
|
||
|
|
}
|