Skip to content

Instantly share code, notes, and snippets.

@Tiberriver256
Last active December 4, 2022 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tiberriver256/c65f51c30a3798e712c173e7e51b0dfb to your computer and use it in GitHub Desktop.
Save Tiberriver256/c65f51c30a3798e712c173e7e51b0dfb to your computer and use it in GitHub Desktop.
Runs a git log in PowerShell and prints options as a PowerShell custom object
<#
.SYNOPSIS
Runs a git log in PowerShell and prints options as a PowerShell custom object
.EXAMPLE
PS> Get-GitLogStats -CommitHash -AuthorName -AuthorEmail -AdditionalArgs '--since="30 days ago"'
CommitHash AuthorName AuthorEmail
---------- ---------- -----------
5426c8744a7fa3a602122738415ab32c80f2c1ad Micah Rairdon SomeFancyEmail@lala.com
5427c8744a7fa3a602122738415ab32c80f2c1ad Micah Rairdon SomeFancyEmail@lala.com
5426c8745a7fa3a602122738415ab32c80f2c1ad Micah Rairdon SomeFancyEmail@lala.com
.EXAMPLE
PS> Get-GitLogStats -AuthorName -AuthorEmail -AdditionalArgs '--since="30 days ago"' -IncludeModifiedLineStats
AuthorName : Micah Rairdon
AuthorEmail : SomeFancyEmail@lala.com
FilesChanged : 2
Insertions : 2
Deletions : 2
AuthorName : Micah Rairdon
AuthorEmail : SomeFancyEmail@lala.com
FilesChanged : 29
Insertions : 2500
Deletions : 288
#>
function Get-GitLogStats {
param(
[string]
$AdditionalArgs,
[switch]
$CommitHash,
[switch]
$AbbreviatedCommitHash,
[switch]
$TreeHash,
[switch]
$AbbreviatedTreeHash,
[switch]
$ParentHashes,
[switch]
$AbbreviatedParentHashes,
[switch]
$AuthorName,
[switch]
$AuthorNameRespectingMailmap,
[switch]
$AuthorEmail,
[switch]
$AuthorEmailRespectingMailmap,
[switch]
$AuthorEmailLocalPart,
[switch]
$AuthorLocalPartRespectingMailmap,
[switch]
$AuthorDate,
[switch]
$AuthorDateRFC2822Style,
[switch]
$AuthorDateRelative,
[switch]
$AuthorDateUNIXTimestamp,
[switch]
$AuthorDateISO8601LikeFormat,
[switch]
$AuthorDateStrictISO8601Format,
[switch]
$AuthorDateShortFormat,
[switch]
$AuthorDateHumanStyle,
[switch]
$CommitterName,
[switch]
$CommitterNameRespectingMailmap,
[switch]
$CommitterEmail,
[switch]
$CommitterEmailRespectingMailmap,
[switch]
$CommitterEmailLocalPart,
[switch]
$CommitterLocalPart,
[switch]
$CommitterDateRFC2822Style,
[switch]
$CommitterDateRelative,
[switch]
$CommitterDateUNIXTimestamp,
[switch]
$CommitterDateISO8601LikeFormat,
[switch]
$CommitterDateStrictISO8601Format,
[switch]
$CommitterDateShortFormat,
[switch]
$CommitterDateHumanStyle,
[switch]
$RefNames,
[switch]
$RefNamesWithoutTheWrapping,
[switch]
$RefNameGivenOnTheCommandLineByWhichTheCommitWasReached,
[switch]
$Encoding,
[switch]
$Subject,
[switch]
$SanitizedSubjectLine,
[switch]
$Body,
[switch]
$RawBody,
[switch]
$CommitNotes,
[switch]
$RawVerificationMessageFromGPGForASignedCommit,
[switch]
$ShowSignatureValidity,
[switch]
$ShowTheNameOfTheSignerForASignedCommit,
[switch]
$ShowTheKeyUsedToSignASignedCommit,
[switch]
$ShowTheFingerprintOfTheKeyUsedToSignASignedCommit,
[switch]
$ShowTheFingerprintOfThePrimaryKeyWhoseSubkeyWasUsedToSignASignedCommit,
[switch]
$ShowTheTrustLevelForTheKeyUsedToSignASignedCommit,
[switch]
$ReflogSelector,
[switch]
$ShortenedReflogSelector,
[switch]
$ReflogIdentityName,
[switch]
$ReflogIdentityNameRespectingMailmap,
[switch]
$ReflogIdentityEmail,
[switch]
$ReflogIdentityEmailRespectingMailMap,
[switch]
$ReflogSubject,
[switch]
$IncludeModifiedLineStats
)
$FormatString = ""
$Headers = @()
$Delimiter = [char]28
if ($CommitHash) {
$Headers += "CommitHash"
$FormatString += "$Delimiter%H"
}
if ($AbbreviatedCommitHash) {
$Headers += "AbbreviatedCommitHash"
$FormatString += "$Delimiter%h"
}
if ($TreeHash) {
$Headers += "TreeHash"
$FormatString += "$Delimiter%T"
}
if ($AbbreviatedTreeHash) {
$Headers += "AbbreviatedTreeHash"
$FormatString += "$Delimiter%t"
}
if ($ParentHashes) {
$Headers += "ParentHashes"
$FormatString += "$Delimiter%P"
}
if ($AbbreviatedParentHashes) {
$Headers += "AbbreviatedParentHashes"
$FormatString += "$Delimiter%p"
}
if ($AuthorName) {
$Headers += "AuthorName"
$FormatString += "$Delimiter%an"
}
if ($AuthorNameRespectingMailmap) {
$Headers += "AuthorNameRespectingMailmap"
$FormatString += "$Delimiter%aN"
}
if ($AuthorEmail) {
$Headers += "AuthorEmail"
$FormatString += "$Delimiter%ae"
}
if ($AuthorEmailRespectingMailmap) {
$Headers += "AuthorEmailRespectingMailmap"
$FormatString += "$Delimiter%aE"
}
if ($AuthorEmailLocalPart) {
$Headers += "AuthorEmailLocalPart"
$FormatString += "$Delimiter%al"
}
if ($AuthorLocalPartRespectingMailmap) {
$Headers += "AuthorLocalPartRespectingMailmap"
$FormatString += "$Delimiter%aL"
}
if ($AuthorDate) {
$Headers += "AuthorDate"
$FormatString += "$Delimiter%ad"
}
if ($AuthorDateRFC2822Style) {
$Headers += "AuthorDateRFC2822Style"
$FormatString += "$Delimiter%aD"
}
if ($AuthorDateRelative) {
$Headers += "AuthorDateRelative"
$FormatString += "$Delimiter%ar"
}
if ($AuthorDateUNIXTimestamp) {
$Headers += "AuthorDateUNIXTimestamp"
$FormatString += "$Delimiter%at"
}
if ($AuthorDateISO8601LikeFormat) {
$Headers += "AuthorDateISO8601LikeFormat"
$FormatString += "$Delimiter%ai"
}
if ($AuthorDateStrictISO8601Format) {
$Headers += "AuthorDateStrictISO8601Format"
$FormatString += "$Delimiter%aI"
}
if ($AuthorDateShortFormat) {
$Headers += "AuthorDateShortFormat"
$FormatString += "$Delimiter%as"
}
if ($AuthorDateHumanStyle) {
$Headers += "AuthorDateHumanStyle"
$FormatString += "$Delimiter%ah"
}
if ($CommitterName) {
$Headers += "CommitterName"
$FormatString += "$Delimiter%cn"
}
if ($CommitterNameRespectingMailmap) {
$Headers += "CommitterNameRespectingMailmap"
$FormatString += "$Delimiter%cN"
}
if ($CommitterEmail) {
$Headers += "CommitterEmail"
$FormatString += "$Delimiter%ce"
}
if ($CommitterEmailRespectingMailmap) {
$Headers += "CommitterEmailRespectingMailmap"
$FormatString += "$Delimiter%cE"
}
if ($CommitterEmailLocalPart) {
$Headers += "CommitterEmailLocalPart"
$FormatString += "$Delimiter%cl"
}
if ($CommitterLocalPart) {
$Headers += "CommitterLocalPart"
$FormatString += "$Delimiter%cL"
}
if ($CommitterDate) {
$Headers += "CommitterDate"
$FormatString += "$Delimiter%cd"
}
if ($CommitterDateRFC2822Style) {
$Headers += "CommitterDateRFC2822Style"
$FormatString += "$Delimiter%cD"
}
if ($CommitterDateRelative) {
$Headers += "CommitterDateRelative"
$FormatString += "$Delimiter%cr"
}
if ($CommitterDateUNIXTimestamp) {
$Headers += "CommitterDateUNIXTimestamp"
$FormatString += "$Delimiter%ct"
}
if ($CommitterDateISO8601LikeFormat) {
$Headers += "CommitterDateISO8601LikeFormat"
$FormatString += "$Delimiter%ci"
}
if ($CommitterDateStrictISO8601Format) {
$Headers += "CommitterDateStrictISO8601Format"
$FormatString += "$Delimiter%cI"
}
if ($CommitterDateShortFormat) {
$Headers += "CommitterDateShortFormat"
$FormatString += "$Delimiter%cs"
}
if ($CommitterDateHumanStyle) {
$Headers += "CommitterDateHumanStyle"
$FormatString += "$Delimiter%ch"
}
if ($RefNames) {
$Headers += "RefNames"
$FormatString += "$Delimiter%d"
}
if ($RefNamesWithoutTheWrapping) {
$Headers += "RefNamesWithoutTheWrapping"
$FormatString += "$Delimiter%D"
}
if ($RefNameGivenOnTheCommandLineByWhichTheCommitWasReached) {
$Headers += "RefNameGivenOnTheCommandLineByWhichTheCommitWasReached"
$FormatString += "$Delimiter%S"
}
if ($Encoding) {
$Headers += "Encoding"
$FormatString += "$Delimiter%e"
}
if ($Subject) {
$Headers += "Subject"
$FormatString += "$Delimiter%s"
}
if ($SanitizedSubjectLine) {
$Headers += "SanitizedSubjectLine"
$FormatString += "$Delimiter%f"
}
if ($Body) {
$Headers += "Body"
$FormatString += "$Delimiter%b"
}
if ($RawBody) {
$Headers += "RawBody"
$FormatString += "$Delimiter%B"
}
if ($CommitNotes) {
$Headers += "CommitNotes"
$FormatString += "$Delimiter%N"
}
if ($RawVerificationMessageFromGPGForASignedCommit) {
$Headers += "RawVerificationMessageFromGPGForASignedCommit"
$FormatString += "$Delimiter%GG"
}
if ($ShowSignatureValidity) {
$Headers += "ShowSignatureValidity"
$FormatString += "$Delimiter%G?"
}
if ($ShowTheNameOfTheSignerForASignedCommit) {
$Headers += "ShowTheNameOfTheSignerForASignedCommit"
$FormatString += "$Delimiter%GS"
}
if ($ShowTheKeyUsedToSignASignedCommit) {
$Headers += "ShowTheKeyUsedToSignASignedCommit"
$FormatString += "$Delimiter%GK"
}
if ($ShowTheFingerprintOfTheKeyUsedToSignASignedCommit) {
$Headers += "ShowTheFingerprintOfTheKeyUsedToSignASignedCommit"
$FormatString += "$Delimiter%GF"
}
if ($ShowTheFingerprintOfThePrimaryKeyWhoseSubkeyWasUsedToSignASignedCommit) {
$Headers += "ShowTheFingerprintOfThePrimaryKeyWhoseSubkeyWasUsedToSignASignedCommit"
$FormatString += "$Delimiter%GP"
}
if ($ShowTheTrustLevelForTheKeyUsedToSignASignedCommit) {
$Headers += "ShowTheTrustLevelForTheKeyUsedToSignASignedCommit"
$FormatString += "$Delimiter%GT"
}
if ($ReflogSelector) {
$Headers += "ReflogSelector"
$FormatString += "$Delimiter%gD"
}
if ($ShortenedReflogSelector) {
$Headers += "ShortenedReflogSelector"
$FormatString += "$Delimiter%gd"
}
if ($ReflogIdentityName) {
$Headers += "ReflogIdentityName"
$FormatString += "$Delimiter%gn"
}
if ($ReflogIdentityNameRespectingMailmap) {
$Headers += "ReflogIdentityNameRespectingMailmap"
$FormatString += "$Delimiter%gN"
}
if ($ReflogIdentityEmail) {
$Headers += "ReflogIdentityEmail"
$FormatString += "$Delimiter%ge"
}
if ($ReflogIdentityEmailRespectingMailmap) {
$Headers += "ReflogIdentityEmailRespectingMailmap"
$FormatString += "$Delimiter%gE"
}
if ($ReflogSubject) {
$Headers += "ReflogSubject"
$FormatString += "$Delimiter%gs"
}
$FormatString = $FormatString.TrimStart("$Delimiter")
$GitArgs = "log --pretty=format:$FormatString"
if ($AdditionalArgs.Length -gt 0) {
$GitArgs += " "
$GitArgs += $AdditionalArgs
}
if ($IncludeModifiedLineStats) {
$GitArgs += " "
$GitArgs += "--shortstat --no-merges"
}
$splitString = [regex]::Split( $GitArgs, ' (?=(?:[^"]|"[^"]*")*$)' )
Write-Debug "Executing git with args: [$splitString]"
$Results = (git ($splitString)) -join "`r`n"
if ($IncludeModifiedLineStats) {
foreach ($Entry in $Results -split "`r`n`r`n") {
Write-Debug $Entry
$CsvStats = ($Entry -split "`r`n")[0]
$ShortStat = ($Entry -split "`r`n")[1]
$StatObject = $CsvStats | ConvertFrom-Csv -Delimiter "$Delimiter" -Header $Headers
if ($ShortStat -match "(\d+) files? changed, (\d+) insertions?\(\+\), (\d+) deletions?\(-\)") {
$StatObject | Add-Member -MemberType NoteProperty -Name "FilesChanged" -Value $Matches[1]
$StatObject | Add-Member -MemberType NoteProperty -Name "Insertions" -Value $Matches[2]
$StatObject | Add-Member -MemberType NoteProperty -Name "Deletions" -Value $Matches[3]
}
elseif ($ShortStat -match "(\d+) files? changed, (\d+) insertions?\(\+\)") {
$StatObject | Add-Member -MemberType NoteProperty -Name "FilesChanged" -Value $Matches[1]
$StatObject | Add-Member -MemberType NoteProperty -Name "Insertions" -Value $Matches[2]
$StatObject | Add-Member -MemberType NoteProperty -Name "Deletions" -Value 0
}
elseif ($ShortStat -match "(\d+) files? changed, (\d+) deletions?\(\-\)") {
$StatObject | Add-Member -MemberType NoteProperty -Name "FilesChanged" -Value $Matches[1]
$StatObject | Add-Member -MemberType NoteProperty -Name "Insertions" -Value 0
$StatObject | Add-Member -MemberType NoteProperty -Name "Deletions" -Value $Matches[2]
}
else {
$StatObject | Add-Member -MemberType NoteProperty -Name "FilesChanged" -Value 0
$StatObject | Add-Member -MemberType NoteProperty -Name "Insertions" -Value 0
$StatObject | Add-Member -MemberType NoteProperty -Name "Deletions" -Value 0
}
$StatObject
}
}
else {
$Results | ConvertFrom-Csv -Delimiter "$Delimiter" -Header $Headers
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment