#!/usr/bin/env zsh autoload -U colors colors set -eu -o pipefail function define() { IFS='\n' read -r -d '' ${1} || true; } local commit_template_fn="$(mktemp)" TRAPEXIT() { rm "$commit_template_fn" } function git-issue-start() { >"$commit_template_fn" <<"EOF" issue: # issue body EOF git stash TRAPEXIT() { git stash pop } git commit --allow-empty -t "$commit_template_fn" } git-issue-sum() { git log --format=format:"%h: %s" --grep issue: } alias git-issue-list=git-issue-sum alias git-issue-summary=git-issue-sum function git-issue-summarize() { git show -s --format=format:"%h: %s" "${1?need a ref}" -- echo } git-issue-normalize-ref () { git show -s --format=format:"%h" ${1?need a ref} -- } git-issue-closed-commits() { git log --format=format:"%h:%s" --grep close | sed -E 's/^.*:close\(([^)]+)\):.*$/\1/' | sort } git-issue-aborted-commits() { git log --format=format:"%h:%s" --grep abort | sed -E 's/^.*:abort\(([^)]+)\):.*$/\1/' | sort } git-issue-issue-commits() { git log --format=format:"%h" --grep issue: | sort } git-issue-open() { comm -23 <( ( git-issue-issue-commits ) ) <( ( git-issue-closed-commits ) ) | { while read -r; do git-issue-summarize "$REPLY" done } } git-issue-closed() { git-issue-closed-commits | { while read -r; do git-issue-summarize "$REPLY" done } } git-issue-aborted() { git-issue-aborted-commits | { while read -r; do git-issue-summarize "$REPLY" done } } git-issue-progress() { : ${1?need a ref} issue="$(git-issue-normalize-ref "$1")" git-issue-show "$issue" echo git log \ --format=format:$'%h: %s\n' \ --grep "$(git-issue-normalize-ref "${issue}")" | gtac } in-progress() { : ${1?need a ref} issue="$(git-issue-normalize-ref "$1")" git log \ --format=format:$'%h: %s\n' \ --grep "$(git-issue-normalize-ref "${issue}")" | grep -v "close($issue)" } git-issue-ip() { in-progress "$@" } function git-issue-all() { { git-issue-open | { while read -r; do if in-progress "${REPLY%%:*}" >/dev/null; then printf "${fg[yellow]}PROGRESS${reset_color}\t$REPLY\n"; else printf "${fg[green]}OPEN${reset_color}\t$REPLY\n"; fi done } | sort -r git-issue-closed | { while read -r; do printf "${fg[red]}CLOSED${reset_color}\t$REPLY\n"; done } git-issue-aborted | { while read -r; do printf "${fg[red]}ABORTED${reset_color}\t$REPLY\n"; done } } | column -t -s $'\t' } git-issue-show() { git show --format=full "$1" -- } git-issue-show-brief() { git show --format=format:"%h: %s" "$1" -- } git-issue-close() { issue="$(git-issue-normalize-ref "${1?must provide an issue hash to close}")" if ! git-issue-show "$issue" &>/dev/null; then echo "invalid issue '$issue' provided" >&2 return fi >"$commit_template_fn" </dev/null; then echo "invalid issue '$issue' provided" >&2 return fi >"$commit_template_fn" <