gh — GitHub CLI Guide
# macOS brew install gh # Linux (Debian/Ubuntu) (type -p curl >/dev/null || sudo apt install curl -y) && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && sudo apt update && sudo apt install gh -y # Windows (winget) winget install --id GitHub.cli # Verify gh --version
gh is GitHub's official CLI, bringing the entire GitHub workflow to your terminal. Fork repos, create PRs, review code, run CI checks, manage issues, and create releases — all without opening a browser. It integrates with git so your existing workflows remain untouched.
Authentication is one command: `gh auth login`. It supports OAuth, SSH keys, and personal access tokens. Once authenticated, every command works against your account. Use `gh auth status` to verify, and `gh auth logout` to switch accounts.
The killer feature is PR management from the terminal. `gh pr create` with `--fill` auto-generates the title and body from your commits. `gh pr checkout` fetches and checks out any PR locally. `gh pr review` submits reviews with comments, approve, or request-changes — all inline in your terminal. For open source, `gh pr create --web` opens the browser pre-filled, which many contributors prefer for first-time PRs.
Auth & Setup
# Interactive login (OAuth via browser): gh auth login # Token-based login (for CI/headless): gh auth login --with-token < ~/my-token.txt # Verify auth status: gh auth status # Switch accounts: gh auth logout gh auth login
# Set default git protocol: gh config set git_protocol ssh # Set default editor: gh config set editor code --wait # Set pager: gh config set pager "delta" # Preferred host: gh config set host github.com # View all config: gh config list
Repository Ops
# Fork a repo: gh repo fork owner/repo # Fork and clone in one step: gh repo fork owner/repo --clone # Fork to your account and add as remote: gh repo fork owner/repo --remote # Rename default remote name: gh repo fork owner/repo --remote-name upstream
# Create a new repo from current dir: gh repo create my-project --public --source=. --remote=origin --push # Create with template: gh repo create --template owner/template-repo --public # Clone a repo: gh repo clone owner/repo # List your repos: gh repo list --limit 30 # View a repo: gh repo view owner/repo --web
Pull Requests
# Basic PR (auto-fill from commits): gh pr create --fill # PR with custom title and body: gh pr create --title "fix: resolve login redirect loop" --body "Closes #42. Adds redirect validation to prevent infinite loops when session expires." # PR with draft status: gh pr create --draft --fill # Assign reviewers: gh pr create --fill --reviewer @team/maintainers # Open in browser to complete: gh pr create --web
# List open PRs: gh pr list # List with status: gh pr list --state all --limit 50 # List PRs authored by you: gh pr list --author @me # List PRs needing your review: gh pr list --review-requested @me # Checkout a PR locally: gh pr checkout 123 # View PR in browser: gh pr view 123 --web # Show PR diff: gh pr diff 123
# Merge with merge commit: gh pr merge 123 # Squash and merge: gh pr merge 123 --squash # Rebase and merge: gh pr merge 123 --rebase # Merge and delete branch: gh pr merge 123 --delete-branch # Close without merging: gh pr close 123 # Reopen: gh pr reopen 123
Issues & Discussions
# Create an issue: gh issue create --title "Add input validation" --body "Users can submit empty forms. Add validation on the client and server side." # List issues: gh issue list --limit 50 # List issues by label: gh issue list --label "good first issue" # View issue: gh issue view 42 # Close issue: gh issue close 42 --comment "Fixed in PR #123" # Reopen: gh issue reopen 42
CI & Checks
# List workflow runs: gh run list --limit 10 # View a specific run: gh run view 1234 # Watch a run in real-time: gh run watch 1234 # Rerun a failed run: gh run rerun 1234 # Download artifacts: gh run download 1234 # View run logs: gh run view 1234 --log
Reviews
# Add a comment: gh pr review 123 --comment --body "Nice work! Consider handling the empty state." # Approve: gh pr review 123 --approve # Request changes: gh pr review 123 --request-changes --body "This needs a test for the edge case." # Review specific files (opens $EDITOR): gh pr review 123 --comment
Gists & Releases
# Create a gist: gh gist create file.ts # Create public gist with description: gh gist create --public --desc "Custom React hook for debounce" src/hooks/useDebounce.ts # List gists: gh gist list # Create a release: gh release create v1.2.0 --title "v1.2.0" --notes "Bug fixes and performance improvements" # Upload assets: gh release create v2.0.0 ./dist/app.zip --title "v2.0.0"
Search & Browse
# Search repositories: gh search repos "topic:hacktoberfest language:typescript" # Search issues: gh search issues "label:\"good first issue\" state:open" # Search PRs: gh search prs --author @me --state open # Search across GitHub: gh search -- "todo in:file language:python" # Browse in browser: gh browse # open current repo gh browse --issues gh browse --pull-requests gh browse --settings
Tips
# Full OSS contribution workflow: # 1. Find a good first issue: gh search issues --repo=owner/project --label="good first issue" --limit=10 # 2. Fork and clone: gh repo fork owner/project --clone cd project # 3. Create a branch: git switch -c fix/issue-42 # 4. Make changes and commit # 5. Push and create PR: git push -u origin fix/issue-42 gh pr create --fill --label "bug" # 6. Open in browser to verify: gh pr view --web # 7. After merge, clean up: git switch main git pull upstream main git branch -d fix/issue-42
# Add to ~/.gitconfig or ~/.bashrc/zshrc: # Quick PR create: alias pr="gh pr create --fill" # Quick PR checkout: alias prco="gh pr checkout" # View CI status: alias ci="gh run list --limit 5" # Quick issue create: alias issue="gh issue create" # Fork + clone shortcut: alias fork="gh repo fork --clone" # Alias in gh itself: gh alias set prc "pr create --fill" gh alias set prco "pr checkout" gh alias set prl "pr list"