Skip to content

Instantly share code, notes, and snippets.

@zhang-ning
Forked from overengineer/git-json.sh
Created September 17, 2024 02:22
Show Gist options
  • Save zhang-ning/a8cdb9432b0caa831bc7b039a7e8b64d to your computer and use it in GitHub Desktop.
Save zhang-ning/a8cdb9432b0caa831bc7b039a7e8b64d to your computer and use it in GitHub Desktop.
git log json format
#!/bin/bash
# Bash unofficial strict mode
set -euo pipefail
# http://www.dwheeler.com/essays/filenames-in-shell.html
IFS=$'\n\t'
function define() { IFS='\n' read -r -d '' ${1} || true; }
define TMPL << 'EOF'
{
"commit": "%H",
"tree": "%T",
"parent": "%P",
"refs": "%D",
"encoding": "%e",
"message": "MSG",
"commit_notes": "%N",
"verification_flag": "%G?",
"signer": "%GS",
"signer_key": "%GK",
"author": {
"name": "AUTHOR",
"email": "%aE",
"date": "%ai"
},
"commiter": {
"name": "COMMITER",
"email": "%cE",
"date": "%ci"
}
}
EOF
function strip () {
# strip newlines then strip all whitespace
sed -e :a -e '/./,$!d;/^\n*$/{$d;N;};/\n$/ba' | sed -E 's/^\s+|\s+$//g'
}
function sanitize () {
# escape newline, escape quotes, escape backslash, escape tabs, fix double escapes, delete invalid characters
sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/"/\\"/g' | sed 's/\\\\/\\/g' | sed 's/\t/\\t/g' | sed -E 's/\\([^nt"])/\\\\\1/g' | tr -d '\r\0\t' | sed -E 's/[\x00-\x1f]//g';
}
function field () {
git show -s --format="$1" "$2" | strip | sanitize
}
git log --pretty=format:'%H' | while IFS='' read -r hash; do
TMP="$TMPL"
TMP="${TMP/MSG/$(field "%B" $hash)}"
TMP="${TMP/AUTHOR/$(field "%aN" $hash)}"
TMP="${TMP/COMMITER/$(field "%cN" $hash)}"
git show $hash -s --format="$TMP"
done
# | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/\x0\x0\x0/\0\0\n/g' | sed 's/\"/\\\"/g' | sed 's/\x0\x0/"/g' | sed 's/\x0/" "/g' | tr -d '\000' \
# | xargs printf '{"commit": "%s","abbreviated_commit": "%s","tree": "%s","abbreviated_tree": "%s","parent": "%s","abbreviated_parent": "%s","refs": "%s","encoding": "%s","subject": "%s","sanitized_subject_line": "%s","body": "%s","commit_notes": "%s","verification_flag": "%s","signer": "%s","signer_key": "%s","author": {"name": "%s","email": "%s","date": "%s"},"commiter": {"name": "%s","email": "%s","date": "%s"}}\n'
# | sed "$ s/,$//" | sed ':a;N;$!ba;s/\r\n\([^{]\)/\\n\1/g'| awk 'BEGIN { print("[") } { print(%s) } END { print("]") }' | sed ':a;N;$!ba;s/\n/ /g'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment