-
-
Save maage/f4853041435f49d521ccaa78017ca428 to your computer and use it in GitHub Desktop.
bash function for git log as JSON
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# attempting to be the most robust solution for outputting git log as JSON, | |
# using only bash shell syntax, `git`, `sed` and `tr`. | |
# - uses traditional JSON camelCase | |
# - includes every major field that git log can output, including the body | |
# - proper sections for author, committer, and signature | |
# - multiple date formats (one for reading, ISO for parsing) | |
# - properly handle body values, even those that contain quotation marks and | |
# escaped characters | |
# - outputs as minimized JSON, can be piped to `jq` for pretty printing | |
# - can run against the current directory as `git-log-json` or against a file | |
# or folder with `git-log-json foo` | |
# - easily piped into `jq`, e.g. this will get all the commit subjects: | |
# $ git-log-json foo | jq -r '.[] | .subject' | |
# - accept any option git log accepts, --pretty etc does not make sense but accepted | |
# - requires support for en_US.UTF-8 locale, needed to support \0 as delim | |
# credit to @nsisodiya, @varemenos, @overengineer, and others for the | |
# original working code: | |
# https://gist.github.com/varemenos/e95c2e098e657c7688fd | |
git-log-json() { | |
local a | |
for a in "$@"; do | |
case "${a}" in | |
--) break ;; | |
--format=*|--pretty|--pretty=*|--oneline|-p|-u|--patch) | |
>&2 echo "ERROR: git-log-json does not accept ${a} as option" | |
return 1 | |
;; | |
esac | |
done | |
local LANG=en_US.UTF-8 | |
# Force UTF-8 to handle \0 as native | |
git log --pretty=format:"$( | |
{ | |
# Normalize, handle delims between keys and values and entries | |
tr -d '\r\n ' | sed -E 's/"([^"]*)"/%x00\1%x00/g;s/$/,%x00/' | |
} << 'EOF' | |
{ | |
"author": | |
{ | |
"name": "%aN", | |
"email": "%aE", | |
"date": "%aD", | |
"dateISO8601": "%aI" | |
}, | |
"body": "%b", | |
"commitHash": "%H", | |
"commitHashAbbreviated": "%h", | |
"committer": | |
{ | |
"name": "%cN", | |
"email": "%cE", | |
"date": "%cD", | |
"dateISO8601": "%cI" | |
}, | |
"encoding": "%e", | |
"notes": "%N", | |
"parent": "%P", | |
"parentAbbreviated": "%p", | |
"refs": "%D", | |
"signature": | |
{ | |
"key": "%GK", | |
"signer": "%GS", | |
"verificationFlag": "%G?" | |
}, | |
"subject": "%s", | |
"subjectSanitized": "%f", | |
"tree": "%T", | |
"treeAbbreviated": "%t" | |
} | |
EOF | |
)" "$@" | \ | |
# Force UTF-8 to handle \0 as native | |
sed -E ' | |
# Slurp all into memory | |
:a | |
N | |
$!ba | |
# Handle quotations | |
s/\\/\\\\/g | |
s/"/\\"/g | |
# Join entries, drop \n so it does not mess later | |
s/(\x00[}],)\x00\n([{]\x00)/\1\2/g | |
# Handle \n\r\t | |
s/\r//g | |
s/\n/\\n/g | |
s/\t/\\t/g | |
# Wrap with [ ], drops last entry delim | |
s/^(.*),\x00$/[\1]/ | |
# Handle key/value delims | |
s/\x00/"/g; | |
' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment