# scripts/tier2/fetch_tier2_branch.ps1 <# .SYNOPSIS Fetch a Tier 2 autonomous branch from the sandboxed clone into the main repo. .DESCRIPTION The Tier 2 sandbox blocks git push (and all other destructive git ops). After Tier 2 finishes a track, this script is the bridge: it fetches the tier2/ branch from the sandboxed clone (C:\projects\manual_slop_tier2) into the main repo (C:\projects\manual_slop), creating a local review/ branch so your working tree is untouched. You can then review the diff, merge to main, and push to origin yourself. This script does NOT push to origin. Pushing is the user's call. .PARAMETER TrackName The track name (e.g., send_result_to_send_20260616). The branch fetched is tier2/. .PARAMETER MainRepoPath Path to the main repo. Default: C:\projects\manual_slop .PARAMETER Tier2ClonePath Path to the Tier 2 sandboxed clone. Default: C:\projects\manual_slop_tier2 .PARAMETER RemoteName The git remote name to use for the Tier 2 clone. Default: tier2-clone .EXAMPLE pwsh -File scripts\tier2\fetch_tier2_branch.ps1 -TrackName send_result_to_send_20260616 Fetches tier2/send_result_to_send_20260616 from the sandboxed clone and creates review/send_result_to_send_20260616 in the main repo. .EXAMPLE pwsh -File scripts\tier2\fetch_tier2_branch.ps1 -TrackName my_track -RemoteName sandbox Same as above but uses 'sandbox' as the remote name (in case tier2-clone is taken). #> [CmdletBinding(SupportsShouldProcess = $true)] param( [Parameter(Mandatory = $true)] [string]$TrackName, [string]$MainRepoPath = "C:\projects\manual_slop", [string]$Tier2ClonePath = "C:\projects\manual_slop_tier2", [string]$RemoteName = "tier2-clone" ) $ErrorActionPreference = "Stop" # Resolve to absolute paths $MainRepoPath = (Resolve-Path $MainRepoPath -ErrorAction SilentlyContinue)?.Path if (-not $MainRepoPath) { throw "Main repo not found at $MainRepoPath. Adjust -MainRepoPath." } if (-not (Test-Path $Tier2ClonePath)) { throw "Tier 2 clone not found at $Tier2ClonePath. Run setup_tier2_clone.ps1 first." } $BranchName = "tier2/$TrackName" $ReviewBranch = "review/$TrackName" Write-Host "[fetch] Track: $TrackName" Write-Host "[fetch] Branch in sandbox: $BranchName" Write-Host "[fetch] Local review branch: $ReviewBranch" Write-Host "[fetch] Main repo: $MainRepoPath" Write-Host "[fetch] Tier 2 clone: $Tier2ClonePath" Write-Host "" # 1. Verify the branch exists in the Tier 2 clone Push-Location $Tier2ClonePath try { $branchSha = git rev-parse --verify $BranchName 2>$null if (-not $branchSha) { $available = git branch --format='%(refname:short)' | Where-Object { $_ -like 'tier2/*' } throw "Branch $BranchName does not exist in Tier 2 clone. Available tier2/* branches: $($available -join ', ')" } Write-Host "[fetch] Found branch in sandbox: $BranchName ($($branchSha.Substring(0,7)))" } finally { Pop-Location } # 2. Add the Tier 2 clone as a remote in the main repo (if not already) Push-Location $MainRepoPath try { $currentRemote = git remote get-url $RemoteName 2>$null if ($currentRemote -eq $Tier2ClonePath) { Write-Host "[fetch] Remote '$RemoteName' already points to Tier 2 clone" } elseif ($currentRemote) { Write-Host "[fetch] Remote '$RemoteName' exists but points elsewhere; updating" git remote set-url $RemoteName $Tier2ClonePath } else { Write-Host "[fetch] Adding remote '$RemoteName' -> $Tier2ClonePath" git remote add $RemoteName $Tier2ClonePath } # 3. Fetch the branch Write-Host "[fetch] Fetching $BranchName from $RemoteName" git fetch $RemoteName $BranchName 2>&1 | Out-Null # 4. Create or reset the local review branch if (git rev-parse --verify $ReviewBranch 2>$null) { Write-Host "[fetch] Local review branch $ReviewBranch exists; resetting to $RemoteName/$BranchName" git branch -f $ReviewBranch "$RemoteName/$BranchName" } else { Write-Host "[fetch] Creating local review branch $ReviewBranch" git branch $ReviewBranch "$RemoteName/$BranchName" } # 5. Print summary $currentBranch = git rev-parse --abbrev-ref HEAD $commitsAhead = git rev-list --count "$RemoteName/$BranchName" "^$currentBranch" 2>$null if (-not $commitsAhead) { $commitsAhead = 0 } $filesChanged = (git diff --stat "$currentBranch..$ReviewBranch" | Measure-Object -Line).Lines - 1 if ($filesChanged -lt 0) { $filesChanged = 0 } $firstLine = (git log --oneline "$currentBranch..$ReviewBranch" | Select-Object -First 1) Write-Host "" Write-Host "=== Summary ===" Write-Host " Branch: $BranchName" Write-Host " Local review branch: $ReviewBranch" Write-Host " Your current branch: $currentBranch (untouched)" Write-Host " Commits ahead: $commitsAhead" Write-Host " Files changed: $filesChanged" Write-Host " First commit: $firstLine" Write-Host "" Write-Host "=== Next steps ===" Write-Host " 1. Inspect the diff:" Write-Host " git diff $currentBranch..$ReviewBranch" Write-Host " git log $currentBranch..$ReviewBranch" Write-Host " 2. Inspect specific files:" Write-Host " git show $ReviewBranch -- " Write-Host " 3. If approved, merge to your current branch:" Write-Host " git merge --no-ff $ReviewBranch" Write-Host " 4. Push to origin (from main, in the non-sandboxed session):" Write-Host " git push origin $currentBranch" Write-Host "" Write-Host "[fetch] done. The review branch is local-only; nothing has been pushed to origin." } finally { Pop-Location }