| name | gh |
| description | GitHub CLI (gh) — the official command-line interface to GitHub. Use when the user needs to create or manage pull requests, issues, repositories, GitHub Actions, gists, API calls, authentication, or any other GitHub workflow from the terminal. Also use for scripting GitHub automation, querying the GraphQL/REST API, managing forks/clones, and viewing workflow run logs. Prefer gh over web browsing or the raw REST API. |
| tagline | Official GitHub CLI for PRs, issues, repos, Actions, API, and more |
| triggers | [{"pattern":"(create|make|open|submit|push|get|prepare)\\s+(a|an|the\\s+)?(pr|pull\\s*request|pull-request)","description":"PR creation/opening requests"},{"pattern":"(pr|pull\\s*request|pull-request)\\s+(create|make|open|submit|push)","description":"PR creation/opening requests (reverse order)"},{"pattern":"gh\\s+(pr|pull-request|pull\\s*request)","description":"gh pr commands"},{"pattern":"(assign|reviewer|merge|checkout|review|approve|comment|list|show)\\s+(pr|pull\\s*request)","description":"PR workflow actions"},{"pattern":"(pr|pull\\s*request)\\s+(assign|reviewer|merge|checkout|review|approve|comment|list|show|diff|rebase|close)","description":"PR workflow actions (reverse order)"},{"pattern":"(issue|pr)\\s+(comment|label|transfer|lock|pin|reopen|close|lock)","description":"Issue/PR management actions"}] |
GitHub CLI (gh)
Official CLI to GitHub. Install from https://cli.github.com/
Auth
gh auth login
gh auth login --hostname HOST
gh auth login --with-token
gh auth status / token / logout / refresh -s SCOPE
Headless: GH_TOKEN/GITHUB_TOKEN. Enterprise: GH_ENTERPRISE_TOKEN + GH_HOST.
Key env vars
| Variable | Purpose |
|---|
GH_TOKEN / GITHUB_TOKEN | Auth token (overrides stored creds) |
GH_HOST | Default hostname |
GH_REPO | Default OWNER/REPO |
GH_EDITOR / GIT_EDITOR | Text editor |
GH_BROWSER / GH_PAGER | Browser / pager |
GH_DEBUG / DEBUG | Verbose; api for HTTP traffic |
GH_PROMPT_DISABLED | Disable prompts |
Universal flags
-R, --repo [HOST/]OWNER/REPO — override target repo
-w, --web — open in browser
--json FIELDS — machine-readable output
Pull Requests
gh pr create --title T --body B --reviewer alice --label bug --draft
gh pr create --fill
gh pr create --base dev --head fork:branch
gh pr create --project "Roadmap"
gh pr view 123 --web
gh pr diff 123
gh pr edit 123 --add-label wip --remove-label draft
gh pr checkout 123 [--branch name] [--detach]
gh pr merge 123 --squash --delete-branch [--auto|--rebase|--merge]
gh pr merge 123 --admin
gh pr review 123 --approve -b "LGTM"
gh pr review 123 -r -b "Needs work"
gh pr list --state open --author me
gh pr status
gh pr close 123 / reopen 123 / lock 123 / ready 123 / revert 123
gh pr edit 123 --body-file body.md
gh pr comment 123 -b $'Line 1\nLine 2'
Gotcha: Newlines in comments — Literal \n in bash strings are not rendered as
newlines by GitHub. For multi-line comments, use $'...' syntax for actual newlines, or
use --body-file:
gh pr comment <N> -b $'Line 1\nLine 2\nLine 3'
gh pr comment <N> -b "Line 1\nLine 2"
gh pr comment <N> --body-file comment.md
PR description style
Write PR descriptions that a human (or agent) can skim — focus on what the PR does,
why, and how to use it. Avoid file-level diffs.
Recommended structure:
- What — one paragraph on the core change or new capability
- Key features — bullet list of the most user-facing changes
- Examples — concrete CLI examples or API calls showing how it works
- Why it helps (optional) — one short paragraph on the motivation or benefit
Less emphasis on technical internals — agents should know what the PR delivers, not
which files changed. (The diffs page covers that.)
Reviewers and assignment
Always assign yourself (@me) to the PR as the author.
Do not manually assign reviewers — GitHub's CODEOWNERS file handles automatic reviewer
assignment based on changed files.
Auto-close: Fixes #N, Closes #N, Resolves #N in body. Aliases: gh pr new =
create, gh pr co = checkout.
Review cycle
To check for pending reviews:
gh pr status
gh pr view <N> --json reviewDecision,reviews
A COMMENTED review decision means inline comments were left (not approval). Always
inspect and address them.
Note: You cannot submit a review (gh pr review) on your own PR — only post comments
and resolve threads.
Copilot review workflow
- Fetch inline comments:
gh api repos/<org>/<repo>/pulls/<N>/reviews --jq '.[] | select(.author.login == "copilot-pull-request-reviewer") | .id'
gh api repos/<org>/<repo>/pulls/<N>/reviews/<ID>/comments --jq '.[] | {path, line, body, id}'
- Read the relevant code and judge whether each comment makes sense.
- Fix the code if the feedback is valid (or improve it even if the suggestion isn't
perfect).
- Reply to ambiguous comments — if a comment contains a question or is unclear,
reply on that specific thread:
gh api repos/<org>/<repo>/pulls/<N>/comments -X POST -f body="Your clarification question here" -F in_reply_to=<COMMENT_ID>
- Post a summary comment on the PR listing what you fixed, tagged with
@copilot:
gh pr comment <N> -b $'Addressed all comments:\n- Fixed: <list>\n@copilot'
- Resolve all threads via GraphQL (REST API cannot resolve threads):
gh api graphql --method POST -f 'query=query { repository(owner: "<org>", name: "<repo>") { pullRequest(number: <N>) { reviewThreads(first: 20) { edges { node { id isResolved } } } } } }'
gh api graphql --method POST -f 'query=mutation { resolveReviewThread(input: {threadId: "PRRT_xxx"}) { clientMutationId } }'
Human review workflow
- Fetch inline comments for each review:
gh api repos/<org>/<repo>/pulls/<N>/reviews/<REVIEW_ID>/comments --jq '.[] | {id, path, line, body}'
- Reply directly to each comment — explain your fix or reasoning on the specific
thread:
gh api repos/<org>/<repo>/pulls/<N>/comments -X POST -f body="Your reply here" -F in_reply_to=<COMMENT_ID>
- Do NOT resolve threads without replying — resolve only for trivial nits you've
immediately fixed. Otherwise, reply with context.
- No overall summary comment — individual replies are sufficient.
- Re-request the review after addressing all comments:
echo '{"reviewers":["<reviewer-login>"]}' | gh api --method POST repos/<org>/<repo>/pulls/<N>/requested_reviewers --input -
Note: gh pr edit --add-reviewer doesn't actually re-request — use the API
endpoint directly.
Key principle: Copilot → resolve threads + one summary tagged @copilot. Humans →
reply to each thread, no summary, re-request review.
Issues
gh issue create --title T --body B --label bug --assignee alice,@me,@copilot
gh issue create --template "Bug Report" --web
gh issue view 42 --web
gh issue edit 42 --add-label priority
gh issue comment 42 -b "Update"
gh issue close 42 / reopen 42 / lock 42 / pin 42 / transfer 42 owner/repo
gh issue list --state open --author me
gh issue status
Aliases: gh issue new = create.
Gotchas
YAML frontmatter only works in web UI: When using gh issue create --body-file,
YAML frontmatter (like the template headers in .github/ISSUE_TEMPLATE/) is not
parsed — it renders as raw text in the issue body. To use templates properly:
- Use
gh issue create --template "Bug Report" --web to open the browser with the
template
- Or paste the body manually into the web form after selecting the template
- The
--body and --body-file flags bypass template processing entirely
Default repo is local git remote: gh issue create without --repo uses the
current directory's git remote. Always specify --repo owner/repo when creating issues
in external repos to avoid accidental creation in the wrong place.
Repositories
gh repo create NAME --public [--clone] [--description "desc"] [--template tpl]
gh repo clone owner/repo [-- --depth 1]
gh repo fork owner/repo
gh repo edit NAME --add-topic mytopic
gh repo rename NAME new-name
gh repo sync / archive / delete / view --web
gh repo list --limit 50
gh repo gitignore list / view Go
gh repo license list / view MIT
GitHub Actions
gh run list [--workflow ci.yml]
gh run view 123 --log / watch 123 / cancel 123 / delete 123 / download 123 / rerun 123 --failed
gh workflow list / enable NAME / disable NAME / run NAME.yml
gh run watch --fail-fast
Gists
gh gist create script.py -d "desc"
gh gist list / view abc / edit abc --desc "new desc" --add newfile.py / rename abc new / delete abc / clone abc
API
gh api repos/{owner}/{repo}/issues
gh api repos/{owner}/{repo}/issues -X POST -f title=New
gh api graphql -f query='query { viewer { login } }'
gh api ... --jq '.[].name' --paginate --slurp
gh api ... --template '{{range .}}{{.name}}{{end}}'
gh api ... -F 'files[n][content]=@file.txt'
gh api ... -H 'Accept: ...' --preview=baptista --cache 3600s
Placeholders {owner}, {repo}, {branch} resolve from current repo or GH_REPO.
Aliases
gh alias set co 'pr checkout'
gh alias set si '! gh issue create --title "$@"'
gh alias list / delete co / import ./aliases.yaml
Config
gh config set git_protocol ssh / editor vim / color_labels enabled
gh config list / get git_protocol / clear-cache
Keys: git_protocol, editor, prompt, pager, browser, color_labels,
telemetry, spinner.
Search
gh search repos --topic rust / code --repo o/r "TODO" / issues --state open / prs --state merged
Completion
gh completion -s bash | zsh | fish | powershell
Notes
- Repo resolution: current dir git remotes →
GH_REPO → explicit --repo.
--web opens the GitHub page in browser.
- Project board membership needs
project scope (gh auth refresh -s project).
- Draft PRs show
[WIP] in listings.
- Copilot reviews:
state: COMMENTED means changes requested, not approval. See
the "Review cycle" section for the full workflow.