Working with GitHub using gh CLI
Problem definition
You want a reliable, scriptable way to list every pull request in a repository, regardless of which base branch it targets (main, develop, release/*, etc.), and then filter those PRs by author (PERSON_1).
The catch: different “views” of contribution exist (commits vs PR metadata). Here we focus purely on PR metadata.
Solution overview
You have two solid approaches:
-
Approach A (preferred):
gh pr list- Best when you want a clean “PR-centric” view and easy filtering by
--author. - Supports
--state all,--author, structured output via--jsonand--jq. (GitHub CLI)
- Best when you want a clean “PR-centric” view and easy filtering by
-
Approach B (fallback / maximum control):
gh api+ REST pagination- Best when you want raw REST responses and explicit pagination behavior.
- Uses
--paginateand filters client-side with--jq. (GitHub CLI)
Approach A (preferred): gh pr list across all base branches, filtered by author
1) The command (copy/paste)
gh pr list \
-R OWNER/REPO \
--author PERSON_1 \
--state all \
--limit 5000 \
--json number,title,state,createdAt,mergedAt,baseRefName,headRefName,mergedBy,url \
--jq '.[] | "\(.number)\t\(.state)\tbase=\(.baseRefName)\thead=\(.headRefName)\tmergedBy=\(.mergedBy.login // "-")\t\(.title)\t\(.url)"'
2) Why this works
- Not specifying
--basemeans you are not restricting the target branch, so PRs to any base branch can appear. (--baseexists only as an optional filter.) (GitHub CLI) --author PERSON_1filters PRs by author directly. (GitHub CLI)--state allincludes open, closed, merged, etc. (GitHub CLI)--json ... --jq ...gives stable machine-friendly output without needing jq installed (GitHub CLI has built-in support for jq-style queries for JSON formatting). (GitHub CLI)
3) Useful variants
Only merged PRs:
gh pr list -R OWNER/REPO --author PERSON_1 --state merged --limit 5000 \
--json number,title,mergedAt,baseRefName,url \
--jq '.[] | "\(.number)\tmergedAt=\(.mergedAt)\tbase=\(.baseRefName)\t\(.title)\t\(.url)"'
Group counts by base branch (quick sanity report):
gh pr list -R OWNER/REPO --author PERSON_1 --state all --limit 5000 \
--json baseRefName \
--jq 'group_by(.baseRefName) | map({base: .[0].baseRefName, count: length})'
Approach B (fallback): gh api over REST “List pull requests” with pagination
This is useful when you want to be explicit about REST pagination and query params.
1) The command (copy/paste)
gh api -H "Accept: application/vnd.github+json" \
"repos/OWNER/REPO/pulls?state=all&per_page=100" \
--paginate \
--jq '.[] | select(.user.login=="PERSON_1") | "\(.number)\t\(.state)\tbase=\(.base.ref)\thead=\(.head.ref)\t\(.title)\t\(.html_url)"'
2) Why this works
- The REST endpoint supports
state(open/closed/all),base,head,per_page,page. (GitHub Docs) per_page=100asks for the maximum page size. (GitHub Docs)--paginatemakes GitHub CLI keep following pages. (GitHub CLI)- The REST endpoint does not have an
authorquery parameter, so we filter in--jqby.user.login. (GitHub Docs)
Practical recommendation
- Start with Approach A (
gh pr list) because it’s purpose-built for PRs and has a native--authorfilter. (GitHub CLI) - Use Approach B if you need raw REST output or you want tighter control over pagination and query params. (GitHub CLI)