functions/Get-GitCommit.ps1
function Get-GitCommit { <# .SYNOPSIS Gets information for a given SHA1 commit hash. .DESCRIPTION Gets information for a given SHA1 commit hash. .PARAMETER RepoName The name of the git repository to return. This should match the directory name of one of the repositories defined in the $GitRepoPath module variable. If there is no match, a warning is generated. When the parameter is omitted, the current repository will be used if currently inside a repository; otherwise, nothing is returned. .PARAMETER SHA1Hash The SHA1 hash of (or a reference to) a commit in the current repository. If omitted, the HEAD commit is returned. .EXAMPLE ## Call from outside a repository without parameters ## PS C:\> $GitRepoPath = 'C:\PowdrgitExamples\MyToolbox;C:\PowdrgitExamples\Project1' # to ensure the repository paths are defined PS C:\> Get-GitCommit # Nothing was returned because a RepoName was not provided. .EXAMPLE ## Call from outside a repository for non-existent repository ## PS C:\> $GitRepoPath = 'C:\PowdrgitExamples\MyToolbox;C:\PowdrgitExamples\Project1' # to ensure the repository paths are defined PS C:\> Get-GitCommit -RepoName NonExistentRepo WARNING: [Get-GitCommit]Repository 'NonExistentRepo' not found. Check the repository directory has been added to the $GitRepoPath module variable. .EXAMPLE ## Call from outside a repository with RepoName parameter ## PS C:\> $GitRepoPath = 'C:\PowdrgitExamples\MyToolbox;C:\PowdrgitExamples\Project1' # to ensure the repository paths are defined PS C:\> Get-GitCommit -RepoName MyToolbox | Format-Table -Property RepoName,SHA1Hash,AuthorName,Subject RepoName SHA1Hash AuthorName Subject -------- -------- ---------- ------- MyToolbox ba6dfdc703948adbd01590c965932ae8ff692aa0 nmbell Merging from feature1 # When SHA1Hash is not specified, the HEAD commit is returned. .EXAMPLE ## Call from inside a repository with SHA1Hash parameter ## PS C:\> $GitRepoPath = 'C:\PowdrgitExamples\MyToolbox;C:\PowdrgitExamples\Project1' # to ensure the repository paths are defined PS C:\> Set-GitBranch -RepoName MyToolbox -BranchName main -SetLocation # move to the repository directory and checkout the main branch PS C:\PowdrgitExamples\MyToolbox> $commitHash = Get-GitLog -NoMerges | Where-Object Subject -eq 'feature1 commit' | Select-Object -ExpandProperty SHA1Hash # pick a commit from the log PS C:\PowdrgitExamples\MyToolbox> Get-GitCommit -SHA1Hash $commitHash | Format-Table -Property RepoName,SHA1Hash,AuthorName,Subject RepoName SHA1Hash AuthorName Subject -------- -------- ---------- ------- MyToolbox 3a987081541ca2f31f575d47287cb3fdf82a1135 nmbell feature1 commit .EXAMPLE ## Pipe results from Get-GitLog ## PS C:\> $GitRepoPath = 'C:\PowdrgitExamples\MyToolbox;C:\PowdrgitExamples\Project1' # to ensure the repository paths are defined PS C:\> Set-GitBranch -RepoName MyToolbox -BranchName main -SetLocation # move to the repository directory and checkout the main branch PS C:\PowdrgitExamples\MyToolbox> Get-GitLog | Get-GitCommit | Format-Table -Property RepoName,SHA1Hash,AuthorName,Subject RepoName SHA1Hash AuthorName Subject -------- -------- ---------- ------- MyToolbox ba6dfdc703948adbd01590c965932ae8ff692aa0 nmbell Merging from feature1 MyToolbox beffe458a0460726f79316fd0dad2d2392a35b64 nmbell Add feature1_File1.txt MyToolbox 3a987081541ca2f31f575d47287cb3fdf82a1135 nmbell feature1 commit MyToolbox 87b1320518c17702d30e463966bc070ce6481459 nmbell Initial commit # Output is identical to: # PS C:\PowdrgitExamples\MyToolbox> Get-GitLog | Format-Table -Property RepoName,SHA1Hash,AuthorName,Subject .INPUTS [System.String] Accepts string objects via the SHA1Hash parameter. The output of Get-GitLog can be piped into Get-GitCommit. .OUTPUTS [GitCommit] Returns a custom GitCommit object. For details use Get-Member at a command prompt e.g.: PS C:\PowdrgitExamples\MyToolbox> Get-GitCommit | Get-Member -MemberType Properties .NOTES Author : nmbell .LINK about_powdrgit .LINK Get-GitCommitFile .LINK Get-GitFileHistory .LINK Get-GitLog #> # Use cmdlet binding [CmdletBinding( HelpURI = 'https://github.com/nmbell/powdrgit/blob/main/help/Get-GitCommit.md' )] # Declare parameters Param( [Parameter( Mandatory = $false , Position = 0 , ValueFromPipeline = $false , ValueFromPipelineByPropertyName = $true )] [ArgumentCompleter({ Param ($commandName,$parameterName,$wordToComplete,$commandAst,$fakeBoundParameters) Get-GitRepo -Verbose:$false ` | Select-Object -ExpandProperty RepoName ` | Where-Object { $_ -like "$wordToComplete*" } ` | Sort-Object })] [String] $RepoName , [Parameter( Mandatory = $false , Position = 1 , ValueFromPipeline = $true , ValueFromPipelineByPropertyName = $true )] [String] $SHA1Hash = 'HEAD' ) BEGIN { $wvBlock = 'B' # Common BEGIN: Set-StrictMode -Version 2.0 $thisFunctionName = $MyInvocation.InvocationName $start = Get-Date $wvIndent = '| '*($PowdrgitCallDepth++) Write-Verbose "$(wvTimestamp)$wvIndent[$thisFunctionName][$wvBlock]Start: $($start.ToString('yyyy-MM-dd HH:mm:ss.fff'))" # Function BEGIN: Write-Verbose "$(wvTimestamp)$wvIndent[$thisFunctionName][$wvBlock]Storing current location" Push-Location -StackName GetGitCommitInfo $startOfText = '!!>>' # commit info delimiter $endOfText = '<<!!' # commit info delimiter $gitCommandTemplate = 'git show <SHA1Hash> --date=iso8601-strict-local --format=format:"'+$startOfText+'%H|%T|%P|%ad|%an|%ae|%cd|%cn|%ce|%D|%s|%b'+$endOfText+'"' # https://git-scm.com/docs/git-show#_pretty_formats } PROCESS { $wvBlock = 'P' # Find the repository name from current location If (!$RepoName) { $RepoName = Get-GitRepo -Current | Select-Object -ExpandProperty RepoName } # Go to the repository and get the repository info $repo = Set-GitRepo -RepoName $RepoName -PassThru -WarningAction SilentlyContinue If ($repo) { # Validate parameters $gitCommandRefType = "git cat-file -t $SHA1Hash" $refType = Invoke-GitExpression -Command $gitCommandRefType -SuppressGitErrorStream If ($refType -notin 'commit') { Write-Warning "`"$SHA1Hash`" is not a valid commit in repository '$($repo.Name)'." } # Get commit info Write-Verbose "$(wvTimestamp)$wvIndent[$thisFunctionName][$wvBlock]Gathering commit info" $gitCommand = $gitCommandTemplate.Replace('<SHA1Hash>',$SHA1Hash) $gitResults = Invoke-GitExpression -Command $gitCommand -SuppressGitErrorStream ` | ConvertTo-GitParsableResults -StartOfText $startOfText -EndOfText $endOfText # Parse the results If ($gitResults) { $lineSplit = $gitResults.Split('|') # Output [GitCommit]@{ 'RepoName' = $repo.Name 'SHA1Hash' = $lineSplit[0] 'TreeHash' = $lineSplit[1] 'ParentHashes' = $lineSplit[2].Split(' ').Trim() 'IsMerge' = $lineSplit[2].Split(' ').Count -gt 1 'AuthorDate' = [DateTime]::Parse($lineSplit[3]) 'AuthorName' = $lineSplit[4] 'AuthorEmail' = $lineSplit[5] 'CommitterDate' = $lineSplit[6] 'CommitterName' = $lineSplit[7] 'CommitterEmail' = $lineSplit[8] 'RefNames' = $lineSplit[9].Split(',').Trim() 'Subject' = $lineSplit[10] 'Body' = $lineSplit[11] } } } ElseIf ($RepoName) { Write-Warning "[$thisFunctionName]Repository '$RepoName' not found. Check the repository directory has been added to the `$GitRepoPath module variable." } } END { $wvBlock = 'E' # Function END: Write-Verbose "$(wvTimestamp)$wvIndent[$thisFunctionName][$wvBlock]Setting location to original directory" Pop-Location -StackName GetGitCommitInfo # Common END: $end = Get-Date $duration = New-TimeSpan -Start $start -End $end Write-Verbose "$(wvTimestamp)$wvIndent[$thisFunctionName][$wvBlock]Finish: $($end.ToString('yyyy-MM-dd HH:mm:ss.fff')) ($('{0}d {1:00}:{2:00}:{3:00}.{4:000}' -f $duration.Days,$duration.Hours,$duration.Minutes,$duration.Seconds,$duration.Milliseconds))" $PowdrgitCallDepth-- } } |