Extensions/Git.Branch.UGit.Extension.ps1
<# .SYNOPSIS git branch extension .DESCRIPTION Outputs git branch as objects (unless, -m, -c, -column, -format, or -show-current are passed) .EXAMPLE git branch # Get a list of branches .EXAMPLE git branch | # Get all branches Where-Object -Not IsCurrentBranch | # where it is not the current branch Where-Object BranchName -NotIn 'main', 'master' | # and the name is not either main or master git branch -d # then attempt to delete the branch. #> [Management.Automation.Cmdlet("Out","Git")] # It's an extension for Out-Git [ValidatePattern("^git branch",Options='IgnoreCase')] # when the pattern is "git branch" [OutputType('git.branch', 'git.branch.deleted','git.branch.detail')] param() begin { <# If any of these parameters are used, we will skip processing. #> $SkipIf = 'm', 'c', 'column','format', 'show-current' -join '|' if ($gitCommand -match "\s-(?>$SkipIf)") { continue } $allBranches = @() } process { # If -d or -delete was passed if ($gitCommand -match '\s-(?>d|-delete)') { # and we have a confirmation of the branch being deleted if ("$gitout" -match '^Deleted branch (?<BranchName>\S+) \(was (?<BranchHash>[0-9a-f]+)\)') { # Output a 'git.branch.deleted' object [PSCustomObject][Ordered]@{ PSTypeName = 'git.branch.deleted' DeletedBranchName = $Matches.BranchName BranchHash = $Matches.BranchHash GitRoot = $GitRoot } } elseif (-not ("$gitout" -replace '\s')) { # Otherwise, if there was content on the line $gitout # output it. } return } # Current branches will start with an asterisk. Convert this to a boolean. $IsCurrentBranch = ("$gitOut" -match '^\*\s' -as [bool]) # If the -verbose flag was passed, we have more information in a more predictable fashion. if ($gitCommand -match '\s-(?:v|-verbose)'){ # The branch name and hash are each separated by spaces. Everything else is a commit message. $branchName, $branchHash, $lastCommitMessage = "$gitOut" -replace '^[\*\s]+' -split '\s+' -ne '' # All this to this of all branches (we will sort them at the end). $allBranches += [PSCustomObject][Ordered]@{ PSTypeName = 'git.branch.detail' BranchName = $branchName BranchHash = $branchHash CommitMessage = $lastCommitMessage -join ' ' IsCurrentBranch = $IsCurrentBranch GitRoot = $GitRoot } } else { # If verbose wasn't passed, the branchname is any whitepsace. # If remotes were passed, then they may start with origin. We can replace this. $branchName = "$gitOut" -replace '^[\s\*]+' -replace '^origin/' # Add the output to the list of all branches $allBranches += [PSCustomObject][Ordered]@{ PSTypeName = 'git.branch' BranchName = $branchName IsCurrentBranch = $IsCurrentBranch GitRoot = $GitRoot } } # If the user passed their own --sort parameter, if ($gitCommand -match '\s--sort') { $allBranches[-1] # don't sort for them and output the branch, $allBranches = @() # and reset the list of all branches. } } end { # If no --sort was passed, $allBranches | Sort-Object @{ # then put the current branch first Expression='IsCurrentBranch' Descending=$true }, BranchName # and sort the rest alphabetically. } |