GitHub CLI
Manage pull requests, issues, repos, and workflows directly from the terminal with gh.
Recipe
Quick-reference recipe card — copy-paste ready.
# Authenticate
gh auth login
# Create a pull request
gh pr create --title "feat: add auth page" --body "Adds login and signup forms"
# List open PRs
gh pr list
# Check out a PR locally
gh pr checkout 42
# Merge a PR
gh pr merge 42 --squash --delete-branch
# Create an issue
gh issue create --title "Bug: sidebar flickers" --label bug
# View repo in browser
gh browseWhen to reach for this: Any GitHub operation you would normally do in the browser — PRs, issues, releases, Actions.
Working Example
# Full PR workflow from terminal
git checkout -b feature/search
# ... write code ...
git add src/components/Search.tsx src/app/search/page.tsx
git commit -m "feat: add search page with debounced input"
git push -u origin feature/search
# Create PR with body
gh pr create --title "feat: add search page" --body "## Summary
- Debounced search input with 300ms delay
- Server-side filtering via search params
- Loading skeleton during fetch
## Test plan
- [ ] Type in search box, verify debounce
- [ ] Check URL updates with search param
- [ ] Verify loading state appears"
# Check CI status
gh pr checks 42
# View PR diff
gh pr diff 42
# Merge when ready
gh pr merge 42 --squash --delete-branchWhat this demonstrates:
- End-to-end feature workflow without leaving the terminal
- PR body supports full Markdown
--squashcombines all commits into one clean commit on main--delete-branchcleans up the remote branch after merge
Deep Dive
Pull Request Commands
# Create PR (interactive — prompts for title, body, reviewers)
gh pr create
# Create PR with reviewers and labels
gh pr create --title "fix: resolve hydration error" \
--reviewer teammate1,teammate2 \
--label "bug,priority:high"
# Create draft PR
gh pr create --draft --title "WIP: new dashboard"
# List PRs with filters
gh pr list --state open --author @me
gh pr list --label "needs-review"
gh pr list --search "is:open draft:false"
# View PR details
gh pr view 42
gh pr view 42 --web # opens in browser
# Review a PR
gh pr checkout 42
gh pr review 42 --approve
gh pr review 42 --request-changes --body "Need to handle the loading state"
gh pr review 42 --comment --body "Looks good, minor suggestion on line 45"
# Merge options
gh pr merge 42 --merge # merge commit
gh pr merge 42 --squash # squash and merge
gh pr merge 42 --rebase # rebase and merge
gh pr merge 42 --auto --squash # auto-merge when checks pass
# Close without merging
gh pr close 42Issue Commands
# Create issue (interactive)
gh issue create
# Create with labels and assignee
gh issue create \
--title "Add dark mode support" \
--body "Users have requested a dark mode toggle in settings." \
--label "enhancement,ui" \
--assignee @me
# List issues
gh issue list
gh issue list --label "bug" --state open
gh issue list --assignee @me
# View and manage
gh issue view 15
gh issue close 15
gh issue reopen 15
# Add a comment
gh issue comment 15 --body "Fixed in PR #42"
# Transfer issue to another repo
gh issue transfer 15 org/other-repoRepository Commands
# Clone a repo
gh repo clone owner/repo
# Create a new repo
gh repo create my-app --private --clone
gh repo create my-app --public --template nextjs/template
# Fork a repo
gh repo fork owner/repo --clone
# View repo info
gh repo view
gh repo view owner/repo --web
# List your repos
gh repo list --language typescript --sort updated
# Set repo topics
gh repo edit --add-topic "nextjs,react,typescript"GitHub Actions / Workflow Commands
# List recent workflow runs
gh run list
# View a specific run
gh run view 12345
# Watch a run in progress
gh run watch 12345
# Re-run a failed job
gh run rerun 12345 --failed
# Trigger a workflow manually
gh workflow run deploy.yml --ref main
# List workflows
gh workflow list
gh workflow view deploy.ymlRelease Commands
# Create a release
gh release create v1.0.0 --title "v1.0.0" --notes "Initial release"
# Create release with auto-generated notes
gh release create v1.1.0 --generate-notes
# Create a draft release
gh release create v2.0.0-beta --draft --prerelease
# List releases
gh release list
# Download release assets
gh release download v1.0.0API Access
# Call any GitHub REST API endpoint
gh api repos/owner/repo/pulls/42/comments
# Create a comment via API
gh api repos/owner/repo/issues/15/comments \
-f body="Automated comment from CLI"
# GraphQL query
gh api graphql -f query='
query {
repository(owner: "vercel", name: "next.js") {
stargazerCount
description
}
}
'
# Paginate results
gh api repos/owner/repo/issues --paginate --jq '.[].title'Gotchas
Things that will bite you. Each gotcha includes what goes wrong, why it happens, and the fix.
-
Auth scope issues —
ghreturns 403 errors for certain operations. Fix: Re-authenticate with the required scopes:gh auth login --scopes repo,read:org. -
Wrong default branch — PR targets the wrong base branch. Fix: Specify explicitly:
gh pr create --base main. -
Auto-merge not enabled —
gh pr merge --autofails silently. Fix: Enable auto-merge in the repo settings first (Settings > General > Allow auto-merge). -
Stale checkout —
gh pr checkoutdoesn't pull latest changes if you already have the branch. Fix: Rungit pullafter checkout, or delete the local branch first.
Alternatives
Other ways to solve the same problem — and when each is the better choice.
| Alternative | Use When | Don't Use When |
|---|---|---|
| GitHub web UI | Complex PR reviews with inline comments | Quick operations or scripting |
hub CLI (legacy) | Already embedded in existing scripts | New projects — gh is the official successor |
| GitHub API directly | Custom integrations or CI scripts | Interactive terminal workflows |
| VS Code GitHub extension | You prefer a GUI within your editor | Terminal-first workflows |
FAQs
How do I authenticate the GitHub CLI for the first time?
gh auth login- Follow the interactive prompts to choose HTTPS or SSH and authenticate via browser
- Your token is stored securely and reused for subsequent commands
How do I create a draft PR from the terminal?
gh pr create --draft --title "WIP: new feature"- Draft PRs signal that the work is not ready for review
- Convert to ready via
gh pr ready 42
What is the difference between --squash, --merge, and --rebase when merging a PR?
--squashcombines all commits into one commit on the target branch--mergecreates a merge commit preserving all individual commits--rebasereplays commits individually on top of the target branch (linear history)
How do I check the CI status of a PR from the command line?
gh pr checks 42- Lists all check runs and their pass/fail/pending status
- Use
gh pr checks 42 --watchto follow in real-time
Gotcha: Why does gh pr merge --auto fail silently?
- Auto-merge must be enabled in the repository settings first
- Go to Settings > General > "Allow auto-merge" and enable it
- Branch protection rules with required checks must also be configured
How do I create an issue and assign it to myself?
gh issue create --title "Bug: form validation" --assignee @me --label bug@meis a shorthand for your GitHub username
Can I call arbitrary GitHub API endpoints with gh?
gh api repos/owner/repo/pulls/42/comments
gh api graphql -f query='{ viewer { login } }'gh apihandles authentication automatically- Supports both REST and GraphQL endpoints
How do I re-run only the failed jobs in a GitHub Actions workflow?
gh run rerun 12345 --failed- This saves time by skipping jobs that already passed
Gotcha: I used gh pr checkout but the code is outdated. Why?
- If you already had the branch locally,
gh pr checkoutswitches to it without pulling - Run
git pullafter checkout to get the latest changes
How do I create a PR that targets a branch other than the default?
gh pr create --base develop --title "feat: new feature"- Without
--base, the PR targets the repository's default branch (usuallymain)
How do I add reviewers and labels with TypeScript-related tags to a PR?
gh pr create --title "fix: type error in utils" \
--reviewer teammate1 \
--label "bug,typescript"- Labels must already exist in the repository
How do I list only my open PRs across all repos?
gh pr list --state open --author @me- Add
--repo owner/repoto scope to a specific repository
Related
- Essential Git Commands — Core Git operations for daily use
- Merging & Rebasing — Branch integration strategies
- Git Utilities — Stash, bisect, cherry-pick, and other power tools