Skip to content

Instantly share code, notes, and snippets.

@dfinke
Created August 25, 2024 18:31
Show Gist options
  • Save dfinke/24bdab2441c1b31be8f230408d05d92c to your computer and use it in GitHub Desktop.
Save dfinke/24bdab2441c1b31be8f230408d05d92c to your computer and use it in GitHub Desktop.
Git-like Diff Tool in PowerShell
# Git-like Diff Tool in PowerShell
function Compare-Files {
param (
[string]$OldFilePath,
[string]$NewFilePath,
[int]$ContextLines = 3
)
$oldFile = Get-Content -Path $OldFilePath
$newFile = Get-Content -Path $NewFilePath
$diffs = [System.Collections.Generic.List[PSObject]]::new()
$oldIndex = 0
$newIndex = 0
while ($oldIndex -lt $oldFile.Count -or $newIndex -lt $newFile.Count) {
$oldLine = if ($oldIndex -lt $oldFile.Count) { $oldFile[$oldIndex] } else { $null }
$newLine = if ($newIndex -lt $newFile.Count) { $newFile[$newIndex] } else { $null }
if ($oldLine -eq $newLine) {
$oldIndex++
$newIndex++
}
else {
$diffs.Add([pscustomobject]@{
ChangeType = if ($null -eq $oldLine) { 'Added' } elseif ($newLine -eq $null) { 'Deleted' } else { 'Modified' }
OldLineNumber = if ($null -ne $oldLine) { $oldIndex + 1 } else { $null }
NewLineNumber = if ($null -ne $newLine) { $newIndex + 1 } else { $null }
OldLine = $oldLine
NewLine = $newLine
})
if ($null -ne $oldLine) { $oldIndex++ }
if ($null -ne $newLine) { $newIndex++ }
}
}
return $diffs
}
function Write-Diff {
param (
[psobject[]]$Diffs,
[string[]]$OldFile,
[string[]]$NewFile,
[int]$ContextLines = 3
)
foreach ($diff in $Diffs) {
if ($diff.ChangeType -eq 'Modified') {
Write-Host "Line $($diff.OldLineNumber),$($diff.NewLineNumber) Modified:" -ForegroundColor Yellow
for ($i = [Math]::Max(0, $diff.OldLineNumber - $ContextLines - 1); $i -lt [Math]::Min($OldFile.Count, $diff.OldLineNumber + $ContextLines); $i++) {
Write-Host " $($OldFile[$i])"
}
Write-Host "- $($diff.OldLine)" -ForegroundColor Red
Write-Host "+ $($diff.NewLine)" -ForegroundColor Green
}
elseif ($diff.ChangeType -eq 'Added') {
Write-Host "Line $($diff.NewLineNumber) Added:" -ForegroundColor Green
Write-Host "+ $($diff.NewLine)" -ForegroundColor Green
}
elseif ($diff.ChangeType -eq 'Deleted') {
Write-Host "Line $($diff.OldLineNumber) Deleted:" -ForegroundColor Red
Write-Host "- $($diff.OldLine)" -ForegroundColor Red
}
}
}
function Show-GitLikeDiff {
param (
[string]$OldFilePath,
[string]$NewFilePath,
[int]$ContextLines = 3
)
$oldFile = Get-Content -Path $OldFilePath
$newFile = Get-Content -Path $NewFilePath
$diffs = Compare-Files -OldFilePath $OldFilePath -NewFilePath $NewFilePath -ContextLines $ContextLines
Write-Diff -Diffs $diffs -OldFile $oldFile -NewFile $newFile -ContextLines $ContextLines
}
# Example usage:
Show-GitLikeDiff -OldFilePath './old.ps1' -NewFilePath './new.ps1'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment