Last active
September 8, 2026 09:54
-
-
Save peterhellberg/d8af898904cdc57e83f221a27dfbe07d to your computer and use it in GitHub Desktop.
A gh prs alias
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
| #!/usr/bin/env bash | |
| # gh prs — list open PRs with their review status, which github.com/<owner>/<repo>/pulls | |
| # no longer shows (the "Approved" checkmark was removed from the list view in late 2025). | |
| # | |
| # Status is derived from the review lists, not reviewDecision: GitHub leaves reviewDecision | |
| # null in repos whose branch has no rule requiring an approval, even when approvals exist. | |
| # | |
| # "changes" and "commented" come from latestReviews, but "approved" comes from the full | |
| # reviews history: latestReviews holds only the single most recent review per author, so a | |
| # review comment left after an approval hides that approval. A later COMMENTED review does | |
| # not retract an approval — only CHANGES_REQUESTED or a dismissal does, and an approval is | |
| # therefore ignored when that author's latestReviews state is CHANGES_REQUESTED or DISMISSED. | |
| # | |
| # Status column: approved (green) / changes (red) / required (yellow) / pending (yellow, | |
| # reviewer requested, nothing submitted) / commented (cyan) / draft (dim) / — (dim, nothing pending). | |
| # The PR number is an OSC 8 hyperlink, but only when stdout is a terminal, so `gh prs | grep` stays clean. | |
| # Run this script once to install the alias; then: gh prs [--repo owner/name] [any other gh pr list flags] | |
| set -euo pipefail | |
| gh alias set --clobber --shell prs - <<'EOF' | |
| if [ -t 1 ]; then | |
| NUM='printf "\033]8;;%s\033\\#%v\033]8;;\033\\" .url .number' | |
| else | |
| NUM='printf "#%v" .number' | |
| fi | |
| gh pr list --json number,reviewDecision,title,reviewRequests,latestReviews,reviews,isDraft,url --template "{{range .}}{{\$approved := false}}{{\$changes := false}}{{\$commented := false}}{{\$latest := .latestReviews}}{{range \$latest}}{{if eq .state \"CHANGES_REQUESTED\"}}{{\$changes = true}}{{else if eq .state \"COMMENTED\"}}{{\$commented = true}}{{end}}{{end}}{{range \$r := .reviews}}{{if eq \$r.state \"APPROVED\"}}{{\$stale := false}}{{range \$l := \$latest}}{{if and (eq \$l.author.login \$r.author.login) (or (eq \$l.state \"CHANGES_REQUESTED\") (eq \$l.state \"DISMISSED\"))}}{{\$stale = true}}{{end}}{{end}}{{if not \$stale}}{{\$approved = true}}{{end}}{{end}}{{end}}{{if .isDraft}}{{tablerow (autocolor \"black+h\" ($NUM)) (autocolor \"black+h\" \"draft\") (autocolor \"black+h\" .title)}}{{else if \$changes}}{{tablerow ($NUM) (autocolor \"red\" \"changes\") .title}}{{else if \$approved}}{{tablerow ($NUM) (autocolor \"green\" \"approved\") .title}}{{else if eq .reviewDecision \"REVIEW_REQUIRED\"}}{{tablerow ($NUM) (autocolor \"yellow\" \"required\") .title}}{{else if .reviewRequests}}{{tablerow ($NUM) (autocolor \"yellow\" \"pending\") .title}}{{else if \$commented}}{{tablerow ($NUM) (autocolor \"cyan\" \"commented\") .title}}{{else}}{{tablerow ($NUM) (autocolor \"black+h\" \"—\") .title}}{{end}}{{end}}" "$@" | |
| EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment