Public/Switch-Work.ps1
|
function Switch-Work { <# .SYNOPSIS Switch to another existing working area. .DESCRIPTION Switch-Work moves into a different existing working area. Use it to return to the main working area or to inspect a previous task's branch. The command refuses to switch when an unfinished merge, rebase, cherry-pick, revert, or bisect is in progress; when there are unfinished conflicts; or when there are unsaved changes that would be lost or carried into the destination. Save your work with Save-Work first, or use Save-Work -NoPush for a local checkpoint. Each invocation writes a self-contained diagnostic log file. Successful runs log silently; failures throw a plain-English message and point at the log file with the technical detail. .PARAMETER Name The name of the working area to switch into. Must already exist. .PARAMETER LogPath Override the directory where the diagnostic log for this run is written. .EXAMPLE Switch-Work -Name main .EXAMPLE Find-CodeChange; Switch-Work -Name giteasy-v2-refresh .NOTES Safety: - Refuses to run during an unfinished merge, rebase, cherry-pick, revert, or bisect. - Refuses to run while there are unfinished conflicts. - Refuses to switch when there are unsaved changes in the active working area. - Refuses to switch into a working area that does not exist. .LINK New-WorkBranch .LINK Find-CodeChange .LINK Save-Work #> [CmdletBinding(SupportsShouldProcess)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0)] [string]$Name, [Parameter()] [string]$LogPath = '' ) $repoRoot = $null try { $rootProbe = Invoke-GEGit -ArgumentList @('rev-parse', '--show-toplevel') -AllowFailure if ($rootProbe.ExitCode -eq 0) { $repoRoot = $rootProbe.Output | Select-Object -First 1 } } catch { $repoRoot = $null } $session = Start-GELogSession -Command 'Switch-Work' -Repository ([string]$repoRoot) -LogPath $LogPath $userMessageOnFailure = "Could not switch to working area '$Name'." try { Assert-GESafeSave -Path ([string]$repoRoot) -LogPath $session.Path | Out-Null if (-not $repoRoot) { $rootResult = Invoke-GEGit -ArgumentList @('rev-parse', '--show-toplevel') -LogPath $session.Path $repoRoot = $rootResult.Output | Select-Object -First 1 } $existCheck = Invoke-GEGit -ArgumentList @('rev-parse', '--verify', '--quiet', "refs/heads/$Name") -WorkingDirectory $repoRoot -LogPath $session.Path -AllowFailure if ($existCheck.ExitCode -ne 0) { throw "No working area named '$Name' exists. Use New-WorkBranch to create one, or check Show-History for a list of existing names." } $statusResult = Invoke-GEGit -ArgumentList @('status', '--porcelain=v1') -WorkingDirectory $repoRoot -LogPath $session.Path $statusLines = @($statusResult.Output | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) if ($statusLines.Count -gt 0) { throw "Cannot switch right now. There are unsaved changes in the active working area. Save them with Save-Work first, or use Save-Work -NoPush for a local checkpoint." } if (-not $PSCmdlet.ShouldProcess($repoRoot, "Switch to working area '$Name'")) { Complete-GELogSession -Path $session.Path -Outcome 'SUCCESS' -UserMessage 'Skipped (WhatIf).' return } Invoke-GEGit -ArgumentList @('checkout', $Name) -WorkingDirectory $repoRoot -LogPath $session.Path | Out-Null Write-Host "Switched to working area '$Name'." $result = [PSCustomObject]@{ Repository = $repoRoot Branch = $Name Message = "Working area '$Name' is now active." } Complete-GELogSession -Path $session.Path -Outcome 'SUCCESS' return $result } catch { $err = $_ $innerMessage = $err.Exception.Message if ($innerMessage -like 'git *') { $finalMsg = $userMessageOnFailure } else { $finalMsg = $innerMessage } Complete-GELogSession -Path $session.Path -Outcome 'FAILURE' -UserMessage $finalMsg -ErrorMessage $innerMessage throw "$finalMsg Details: $($session.Path)" } } |