private/Get-InitialModifiedSnapshot.ps1
|
function Get-InitialModifiedSnapshot { <# .SYNOPSIS Builds a hashtable of modified files for O(1) lookup during -SkipModified processing. .DESCRIPTION Performs an initial sweep of all modified files in the repository and returns a hashtable with normalized paths as keys for fast lookup. This includes: - Uncommitted working tree changes - Staged changes - Committed but not pushed changes (for feature branches) - Recent commit changes (for main branch, based on CommitDepth) .PARAMETER GitContext The git context hashtable from Initialize-GitContext containing UpstreamBranch, IsOnMainBranch, CommitDepth, CurrentBranch, and RepoRoot. .OUTPUTS [hashtable] with normalized file paths (forward slashes) as keys and $true as values. Empty hashtable if no modified files found. .EXAMPLE $gitContext = Initialize-GitContext -CommitDepth 5 $snapshot = Get-InitialModifiedSnapshot -GitContext $gitContext if ($snapshot.ContainsKey($normalizedPath)) { Write-Host "File is modified" } #> [CmdletBinding()] param( [Parameter(Mandatory)] [hashtable]$GitContext ) $snapshot = @{} if (-not $GitContext -or -not $GitContext.RepoRoot) { Write-PSFMessage -Level Verbose -Message "No valid git context provided, returning empty snapshot" return $snapshot } Write-PSFMessage -Level Verbose -Message "Performing initial sweep of modified files..." $allModifiedFiles = @() # Get uncommitted working tree changes $workingTreeChanges = git diff --name-only 2>&1 | Where-Object { $_ -is [string] } if ($LASTEXITCODE -eq 0 -and $workingTreeChanges) { $allModifiedFiles += $workingTreeChanges Write-PSFMessage -Level Verbose -Message "Found $(@($workingTreeChanges).Count) uncommitted working tree change(s)" } # Get staged changes $stagedChanges = git diff --name-only --cached 2>&1 | Where-Object { $_ -is [string] } if ($LASTEXITCODE -eq 0 -and $stagedChanges) { $allModifiedFiles += $stagedChanges Write-PSFMessage -Level Verbose -Message "Found $(@($stagedChanges).Count) staged change(s)" } # Get committed changes based on branch if ($GitContext.IsOnMainBranch) { $recentCommitChanges = git log -n $GitContext.CommitDepth --name-only --pretty=format: 2>&1 | Where-Object { $_ -is [string] -and $_.Trim() } if ($LASTEXITCODE -eq 0 -and $recentCommitChanges) { $allModifiedFiles += $recentCommitChanges Write-PSFMessage -Level Verbose -Message "Found $(@($recentCommitChanges).Count) file(s) modified in last $($GitContext.CommitDepth) commit(s)" } } else { $committedChanges = git diff --name-only "$($GitContext.UpstreamBranch)..HEAD" 2>&1 | Where-Object { $_ -is [string] } if ($LASTEXITCODE -eq 0 -and $committedChanges) { $allModifiedFiles += $committedChanges Write-PSFMessage -Level Verbose -Message "Found $(@($committedChanges).Count) committed but not pushed change(s)" } } # Convert to hashtable for O(1) lookups and normalize paths if ($allModifiedFiles.Count -gt 0) { $allModifiedFiles | Select-Object -Unique | ForEach-Object { $filename = $_.Trim() if ($filename) { $resolvedPath = Join-Path $GitContext.RepoRoot $filename | Resolve-Path -ErrorAction SilentlyContinue if ($resolvedPath) { $normalizedPath = $resolvedPath.Path -replace '\\', '/' $snapshot[$normalizedPath] = $true } } } Write-PSFMessage -Level Verbose -Message "Initial sweep: $($snapshot.Count) modified files to potentially skip" } else { Write-PSFMessage -Level Verbose -Message "Initial sweep: No modified files found" } return $snapshot } |