Overview
gh is the official GitHub CLI. Most list commands take --json fields and --jq expr, so they compose with jq-syntax. Flags below were checked against gh 2.89.
Auth
Use GH_TOKEN in CI and the browser flow on workstations.
| Command | Effect |
|---|---|
gh auth login | Interactive login (browser or token). |
gh auth login --with-token < token.txt | Token from stdin. |
GH_TOKEN=... gh ... | Token from the environment (GH_TOKEN beats GITHUB_TOKEN); simplest in CI. |
gh auth status | Accounts and scopes. |
gh auth refresh -s workflow | Add scopes. |
Pull requests
Pass title and body flags in scripts so no prompt blocks them.
| Command | Effect |
|---|---|
gh pr create --fill | Open a PR with title and body from commits. |
gh pr create --title "..." --body "..." --base main --draft | Fully specified (no prompts). |
gh pr list --state all --author "@me" | Filter PRs (--label, --search also work). |
gh pr view 42 --web | Open in the browser. |
gh pr checkout 42 | Check out the PR branch. |
gh pr diff 42 --name-only | Changed files. |
gh pr review 42 --approve / --request-changes -b "..." | Review. |
gh pr merge 42 --squash --delete-branch | Merge; add --auto to wait for checks. |
gh pr status, gh pr close 42 | Your PRs and review requests / close without merging. |
Issues, repos, releases
Create labels before referencing them with --label.
| Command | Effect |
|---|---|
gh issue create --title "..." --body "..." --label bug | New issue; the label must exist. |
gh issue list --label bug --assignee "@me" | Filter issues. |
gh issue close 10 --comment "Fixed in #42" | Close with a comment. |
gh issue comment 10 --body "...", gh issue edit 10 --add-label priority | Comment / change labels. |
gh label create bug --color d73a4a | Create a label. |
gh repo create my-app --public --clone | Create and clone. |
gh repo clone org/repo, gh repo fork, gh repo view --web | Clone / fork / open in the browser. |
gh release create v1.2.0 --generate-notes dist/*.tgz | Release with generated notes and assets. |
gh release list, gh release upload v1.2.0 dist/app.tar.gz | List releases / add assets to one. |
Workflow runs
Use --exit-status in scripts so a failed run fails the job.
| Command | Effect |
|---|---|
gh workflow run ci.yml --ref main | Dispatch; the workflow needs on: workflow_dispatch. |
gh workflow list, gh run list --workflow ci.yml | Workflows / recent runs. |
gh run watch --exit-status | Follow a run; non-zero exit if it fails. |
gh run view <id> --log-failed | Logs of failed steps only. |
gh run rerun <id> --failed | Re-run failed jobs. |
API and —jq
{owner}, {repo}, and {branch} in the endpoint fill in from the current repository.
| Command | Effect |
|---|---|
gh api repos/{owner}/{repo}/pulls --jq '.[].number' | REST call, filtered. |
gh api graphql -f query='{ viewer { login } }' | GraphQL query. |
gh api --paginate repos/{owner}/{repo}/issues --jq '.[].title' | Every page; --jq runs on each page. |
gh pr list --json number,title --jq '.[] | "\(.number)\t\(.title)"' | Tab-separated list. |
gh issue list --json number,labels --jq '.[] | select(.labels[].name == "bug") | .number' | Select by nested field. |
Gotchas
Avoid these in scripts; each prompts, changes the HTTP method, or fails outside a repo.
| Gotcha | Fix |
|---|---|
gh pr create and gh issue create prompt when flags are missing. | Pass --title and --body, or --fill, in scripts. |
Adding -f or -F to gh api switches the method to POST. | Add --method GET to send them as a query string. |
--slurp cannot be combined with --jq. | Pipe gh api --paginate --slurp into jq. |
gh pr checkout changes your working tree. | Commit or stash first. |
Outside a git repo {owner}/{repo} do not resolve. | Spell out repos/org/name or set GH_REPO. |