[CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [string]$TfsExportRoot, [Parameter(Mandatory = $true)] [string]$Changeset, [string]$RepositoryRoot, [switch]$AllowDirtyTargets ) $ErrorActionPreference = 'Stop' if ([string]::IsNullOrWhiteSpace($RepositoryRoot)) { $RepositoryRoot = Split-Path -Parent $PSScriptRoot } $repositoryRoot = [System.IO.Path]::GetFullPath($RepositoryRoot) $tfsExportRoot = [System.IO.Path]::GetFullPath($TfsExportRoot) $statePath = Join-Path $repositoryRoot 'sync\tfs-state.json' $files = [ordered]@{ 'F4SDM42WebApi\F4SDHelperService.cs' = 'Legacy\F4SDM42WebApi\F4SDHelperService.cs' 'F4SDM42WebApi\F4SDM42WebApiController.cs' = 'Legacy\F4SDM42WebApi\F4SDM42WebApiController.cs' 'F4SDM42WebApi\cM42LogEntry.cs' = 'Legacy\F4SDM42WebApi\cM42LogEntry.cs' 'F4SDM42WebApi\Properties\AssemblyInfo.cs' = 'Legacy\F4SDM42WebApi\Properties\AssemblyInfo.cs' 'F4SDHelper\Properties\AssemblyInfo.cs' = 'Legacy\F4SDHelper\Properties\AssemblyInfo.cs' } if (-not (Test-Path -LiteralPath (Join-Path $repositoryRoot '.git'))) { throw "Repository root is not a Git worktree: $repositoryRoot" } foreach ($sourceRelative in $files.Keys) { $sourcePath = Join-Path $tfsExportRoot $sourceRelative if (-not (Test-Path -LiteralPath $sourcePath)) { throw "Required TFS source file not found: $sourcePath" } } if (-not $AllowDirtyTargets) { $targetPaths = @($files.Values) $status = & git -C $repositoryRoot status --porcelain -- $targetPaths if ($LASTEXITCODE -ne 0) { throw 'Could not inspect the Git worktree.' } if ($status) { throw "Legacy sync targets contain uncommitted changes. Commit or stash them first:`n$($status -join [Environment]::NewLine)" } } $utf8WithBom = [System.Text.UTF8Encoding]::new($true) $hashes = [ordered]@{} foreach ($entry in $files.GetEnumerator()) { $sourcePath = Join-Path $tfsExportRoot $entry.Key $targetPath = Join-Path $repositoryRoot $entry.Value $content = [System.IO.File]::ReadAllText($sourcePath) $content = [regex]::Replace($content, "`r?`n", "`r`n") if ($PSCmdlet.ShouldProcess($targetPath, "Import TFS changeset $Changeset")) { [System.IO.File]::WriteAllText($targetPath, $content, $utf8WithBom) } $hashes[$entry.Value.Replace('\', '/')] = (Get-FileHash -LiteralPath $sourcePath -Algorithm SHA256).Hash } $baseCommit = (& git -C $repositoryRoot rev-parse HEAD).Trim() $state = [ordered]@{ LastImportedChangeset = $Changeset ImportedAtUtc = [DateTime]::UtcNow.ToString('o') SourceRoot = $tfsExportRoot BaseGitCommit = $baseCommit Files = $hashes } if ($PSCmdlet.ShouldProcess($statePath, 'Update TFS import state')) { [System.IO.File]::WriteAllText( $statePath, ($state | ConvertTo-Json -Depth 5), $utf8WithBom) } Write-Host "Imported TFS changeset $Changeset into the Legacy sources." Write-Host 'Review and commit this import on sync/tfs-legacy, then merge it into the development branch.' Write-Host 'Publishing the final result back to TFS remains a manual Visual Studio step.'