Get-RepositoryStatus.ps1
function Get-RepositoryStatus { <# .Synopsis Gets the working tree status. .Description Gets paths that have differences between the index file and the current HEAD commit, paths that have differences between the working tree and the index file, and paths in the working tree that are not tracked by Git. The first are what you would commit by running git commit; the second and third are what you could commit by running git add before running git commit. .Parameter Repository Path to the git repository. Can be relative or absolute. If not specified defaults to the current directory .Link https://git-scm.com/docs/git-status #> [CmdletBinding()] param( [Parameter(Mandatory=$False,Position=1,ValueFromPipeline=$True)] [string]$Repository = ".\" ) process { $Repository = Resolve-Path -Path $Repository Write-Verbose "Getting status of $Repository" $RepositoryData = [PSCustomObject]@{} $Files = New-Object System.Collections.ArrayList $RepositoryData | Add-Member -MemberType NoteProperty -Name 'RepoPath' -Value $Repository $Output = (git -C $Repository status --porcelain=2 -b) 2>&1 if ($Output.GetType().Name -eq "ErrorRecord") { Write-Error -Message ($Output.Exception.Message) -CategoryActivity ($Output.Exception.Message.SubString(0, $Output.Exception.Message.IndexOf(":"))) -ErrorId $LASTEXITCODE } foreach ($line in $Output) { if ($line.StartsWith("# branch.oid")) { $RepositoryData | Add-Member -MemberType NoteProperty -Name "CurrentCommit" -Value ($line.Substring(13)) } elseif ($line.StartsWith("# branch.head")) { $RepositoryData | Add-Member -MemberType NoteProperty -Name "CurrentBranch" -Value ($line.Substring(14)) } elseif ($line -cmatch '1\s([\.MADRCU\?\!][\.MDUA]?)\s(N\.\.\.)\s([0-7]{6})\s([0-7]{6})\s([0-7]{6})\s([0-9a-f]{40})\s([0-9a-f]{40})\s(\S+)') { # 1 2 3 4 5 6 7 8 #1 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <path> $File = [PSCustomObject]@{} $File | Add-Member -MemberType NoteProperty -Name "Path" -Value (Join-Path -Path $Repository -ChildPath $matches[8]) $File | Add-Member -MemberType NoteProperty -Name "Status" -Value ($matches[1]) $Files.Add($File) | Out-Null } elseif ($line -cmatch '2\s([\.MADRCU\?\!][\.MDUA]?)\s(N\.\.\.)\s([0-7]{6})\s([0-7]{6})\s([0-7]{6})\s([0-9a-f]{40})\s([0-9a-f]{40})\s([XC])(\d{3})\s(\S+)`t(\S*)') { # 1 2 3 4 5 6 7 8 9 10 11 #2 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <X><score> <path><sep><origPath> $File = [PSCustomObject]@{} $File | Add-Member -MemberType NoteProperty -Name "Path" -Value (Join-Path -Path $Repository -ChildPath $matches[10]) $File | Add-Member -MemberType NoteProperty -Name "Status" -Value ($matches[1]) $File | Add-Member -MemberType NoteProperty -Name "OriginalPath" -Value (Join-Path -Path $Repository -ChildPath $matches[11]) $File | Add-Member -MemberType NoteProperty -Name "IsMove" -Value ($matches[8] -eq "C") $Files.Add($File) | Out-Null } elseif ($line -cmatch '\?\s(\S+)') { $File = [PSCustomObject]@{} $File | Add-Member -MemberType NoteProperty -Name "Path" -Value (Join-Path -Path $Repository -ChildPath $matches[1]) $File | Add-Member -MemberType NoteProperty -Name "Status" -Value "??" $Files.Add($File) | Out-Null } else { Write-Verbose "Ignoring $line" } } $RepositoryData | Add-Member -MemberType NoteProperty -Name "Files" -Value $Files Write-Output $RepositoryData } } |