cheat sheet

gh

Complete GitHub CLI reference. Auth, configuration, repos, issues, pull requests, releases, Actions, attestations, projects, models, rulesets, caches, secrets, gists, search, API, extensions, and codespaces.

gh — GitHub CLI

What it is

gh is GitHub's official command-line tool. It brings pull requests, issues, releases, Actions, and the GitHub API directly into the terminal — no browser required for the full development workflow.

Installation

bash
# macOS
brew install gh

# Linux (Debian/Ubuntu)
sudo apt install gh

# Linux (manual — latest release)
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
  | sudo dd of=/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

# Windows
winget install GitHub.cli

# Verify
gh --version

Output: (none — exits 0 on success)


Auth

Manages the credentials gh uses to talk to GitHub. You must authenticate before any other gh command will work; the token is stored in the system keyring or in an environment variable for CI environments.

Login

Authenticates gh against GitHub.com or a GitHub Enterprise server. Use --web for the OAuth browser flow; use --with-token in CI or scripts where no interactive terminal is available.

bash
gh auth login                        # interactive: GitHub.com or Enterprise
gh auth login --web                  # open browser to authenticate
gh auth login --with-token < token   # non-interactive (CI, scripts)

Output: (none — exits 0 on success)

Status and token

Confirms which account is active and what permission scopes the token carries. Use gh auth token to retrieve the raw token for piping into other tools that require a GITHUB_TOKEN.

bash
gh auth status                       # show active account and scopes
gh auth status --show-token          # include the raw token
gh auth token                        # print token to stdout (pipe to scripts)

Output:

text
github.com
  ✓ Logged in to github.com account alicedev (keyring)
  - Active account: true
  - Git operations protocol: https
  - Token: ghp_xxxxxxxxxxxxxxxxxxxx
  - Token scopes: gist, read:org, repo, workflow

Logout and refresh

logout removes stored credentials from the keyring; refresh re-prompts for scopes without fully logging out — useful when a command fails because the token is missing a required permission.

bash
gh auth logout                       # remove stored credentials
gh auth refresh                      # re-prompt for scopes
gh auth refresh --scopes read:org,repo,workflow

Output: (none — exits 0 on success)

Switch accounts

Switches the active account when multiple GitHub identities are stored. Use this when you work across personal and work GitHub accounts on the same machine.

bash
gh auth switch                       # interactive account picker
gh auth switch --user otheraccount

Output: (none — exits 0 on success)


Configuration

Controls gh's per-user settings: default editor, git protocol (HTTPS vs SSH), pager, and prompt behavior. User preferences live in ~/.config/gh/config.yml; per-host credentials (GitHub.com plus any Enterprise hosts) live in ~/.config/gh/hosts.yml. Both files are plain YAML — you can hand-edit them, but gh config set and gh auth login are the supported paths. Aliases (below) and extensions store metadata in the same directory.

bash
gh config list                       # show all settings
gh config get editor                 # get one value
gh config set editor vim             # set editor
gh config set git_protocol ssh       # use SSH for git operations (default: https)
gh config set prompt disabled        # disable interactive prompts (for scripts)
gh config set pager "less -R"

Output: (none — exits 0 on success)

Aliases

bash
gh alias set pv 'pr view'            # gh pv → gh pr view
gh alias set imine 'issue list --assignee @me'
gh alias list
gh alias delete pv

Output: (none — exits 0 on success)


Repositories

Commands for creating, cloning, forking, inspecting, and managing GitHub repositories. Most commands auto-detect the current repo from the git remote, so you rarely need to pass owner/repo explicitly when inside a cloned directory.

Create and clone

Creates a new GitHub repository (optionally under an org) and optionally clones it locally in one step. Pass --source=. --push to publish an existing local directory without leaving the terminal.

bash
gh repo create myrepo                              # interactive setup
gh repo create myrepo --public --clone             # public repo, clone immediately
gh repo create myrepo --private --description "My project"
gh repo create org/myrepo --public                 # create under an org

gh repo clone alicedev/myrepo                      # clone by owner/repo
gh repo clone alicedev/myrepo -- --depth=1         # pass flags to git clone
gh repo clone alicedev/myrepo --no-upstream        # skip upstream remote for forks (2.88+)

Output: (none — exits 0 on success)

View and list

Shows repo metadata (description, topics, stars, open issues) in the terminal or browser. gh repo list supports filtering by language, visibility, and archive state — pipe with --json for scripting.

bash
gh repo view                                       # current repo in terminal
gh repo view alicedev/myrepo                       # any repo
gh repo view alicedev/myrepo --web                 # open in browser

gh repo list                                       # your repos
gh repo list alicedev --limit 50
gh repo list --visibility public
gh repo list --language python
gh repo list --archived

Output:

text
NAME                    DESCRIPTION                    VISIBILITY  UPDATED
alicedev/jockey          Personal cheat sheet site      public      about 1 hour ago
alicedev/scripts        Utility scripts                private     2 days ago
alicedev/dotfiles       Shell config                   public      last week

Fork

Creates a personal copy of another user's repository on GitHub and optionally clones it locally with the upstream remote pre-configured for pulling future changes.

bash
gh repo fork original-owner/myrepo                # fork to your account
gh repo fork original-owner/myrepo --clone        # fork and clone locally
gh repo fork original-owner/myrepo --org myorg    # fork to an org

Output: (none — exits 0 on success)

Edit and manage

Modifies repository settings — description, homepage, visibility, feature flags, and default branch — without opening the GitHub web UI. Use gh repo delete with care; it is permanent and bypasses the trash.

bash
gh repo edit --description "New description"
gh repo edit --homepage "https://example.com"
gh repo edit --visibility private
gh repo edit --enable-issues=false
gh repo edit --enable-wiki=false
gh repo edit --default-branch main
gh repo edit --squash-merge-commit-message PR_TITLE  # tune squash commit (2.88+)

gh repo rename new-name                            # rename current repo
gh repo archive                                    # archive (read-only)
gh repo delete alicedev/myrepo --confirm           # permanent deletion

Output: (none — exits 0 on success)

Sync fork

Brings a forked repository's branch up to date with its upstream source — equivalent to a git fetch upstream && git merge but without manually configuring the upstream remote.

bash
gh repo sync                                       # sync fork with upstream
gh repo sync --branch main
gh repo sync alicedev/myrepo --source upstream-owner/myrepo

Output: (none — exits 0 on success)

Deploy keys

Deploy keys are repo-scoped SSH keys for machines that need read (or read-write) access to a single repository — common for CI servers and deployment pipelines that shouldn't use a personal SSH key.

bash
gh repo deploy-key list
gh repo deploy-key add ~/.ssh/id_ed25519.pub --title "CI key" --allow-write
gh repo deploy-key delete <id>

Output: (none — exits 0 on success)


Issues

Commands for creating, filtering, viewing, and managing GitHub issues. Use --json with any list or view command to get machine-readable output for scripting.

Create

bash
gh issue create                                    # interactive
gh issue create --title "Bug: login fails" --body "Steps to reproduce..."
gh issue create --title "Feature request" --label enhancement --assignee @me
gh issue create --template bug_report.md
gh issue create --web                              # open browser form

Output: (none — exits 0 on success)

List and filter

bash
gh issue list                                      # open issues
gh issue list --state closed
gh issue list --state all
gh issue list --assignee @me
gh issue list --assignee alicedev
gh issue list --author alicedev
gh issue list --label "bug,needs-triage"
gh issue list --milestone "v2.0"
gh issue list --search "login error"
gh issue list --limit 50
gh issue list --json number,title,state,assignees  # structured output

Output:

text
Showing 3 of 3 open issues in alicedev/myrepo

#12  Bug: login fails on mobile        (bug, needs-triage)    about 1 day ago
#9   Add dark mode support             (enhancement)          3 days ago
#4   Docs: update README               (documentation)        last week

View

bash
gh issue view 12                                   # terminal view
gh issue view 12 --web                             # open in browser
gh issue view 12 --comments                        # include all comments
gh issue view 12 --json title,body,labels,assignees

Output: (none — exits 0 on success)

Edit and manage

bash
gh issue edit 12 --title "Updated title"
gh issue edit 12 --body "New description"
gh issue edit 12 --add-label "priority:high"
gh issue edit 12 --remove-label "needs-triage"
gh issue edit 12 --add-assignee alicedev
gh issue edit 12 --milestone "v2.0"

gh issue close 12
gh issue close 12 --comment "Resolved in #45"
gh issue close 12 --duplicate-of 9                 # close as duplicate (2.88+)
gh issue reopen 12
gh issue pin 12
gh issue unpin 12
gh issue lock 12 --reason "resolved"
gh issue unlock 12
gh issue transfer 12 alicedev/other-repo
gh issue delete 12 --confirm

Output: (none — exits 0 on success)

Comments

bash
gh issue comment 12 --body "Looking into this now"
gh issue comment 12 --body-file comment.md
gh issue comment 12 --editor                       # open $EDITOR

Output: (none — exits 0 on success)


Pull Requests

The core gh pr workflow: create a PR from the current branch, review CI checks, iterate, and merge — all without leaving the terminal. gh pr create --fill uses the branch name and commit messages to populate the title and body automatically.

Create

bash
gh pr create                                       # interactive
gh pr create --title "feat: add login" --body "Implements #12"
gh pr create --base main --head feature/login
gh pr create --draft
gh pr create --reviewer alicedev,otheruser
gh pr create --assignee @me
gh pr create --label "feature,needs-review"
gh pr create --milestone "v2.0"
gh pr create --web
gh pr create --fill                                # use branch name + commits as title/body

Output: (none — exits 0 on success)

List and filter

bash
gh pr list                                         # open PRs
gh pr list --state closed
gh pr list --state merged
gh pr list --state all
gh pr list --assignee @me
gh pr list --author alicedev
gh pr list --reviewer @me
gh pr list --label "needs-review"
gh pr list --base main
gh pr list --head feature/login
gh pr list --draft
gh pr list --search "fix login"
gh pr list --json number,title,state,author,reviewDecision

Output: (none — exits 0 on success)

View

bash
gh pr view                                         # current branch's PR
gh pr view 45
gh pr view 45 --web
gh pr view 45 --comments
gh pr view 45 --json title,state,reviews,checks

Output: (none — exits 0 on success)

Checkout and diff

bash
gh pr checkout 45                                  # check out PR branch locally
gh pr checkout 45 --branch local-branch-name

gh pr diff                                         # diff for current branch's PR
gh pr diff 45
gh pr diff 45 --patch                              # unified patch format
gh pr diff 45 --name-only                          # just changed file names
gh pr diff 45 --exclude "*.lock" --exclude "dist/*"  # skip noisy files (2.88+)

Output: (none — exits 0 on success)

Review

bash
gh pr review 45 --approve
gh pr review 45 --request-changes --body "Please fix the tests"
gh pr review 45 --comment --body "Looks good overall"

Output: (none — exits 0 on success)

Edit and manage

bash
gh pr edit 45 --title "Updated title"
gh pr edit 45 --body "New description"
gh pr edit 45 --add-label "needs-docs"
gh pr edit 45 --add-reviewer alicedev
gh pr edit 45 --add-reviewer @copilot          # request a Copilot Code Review (2.88+)
gh pr edit 45 --milestone "v2.0"

gh pr ready 45                                     # convert draft → ready for review
gh pr close 45
gh pr close 45 --comment "Superseded by #50"
gh pr reopen 45
gh pr lock 45 --reason "resolved"

Output: (none — exits 0 on success)

Merge

bash
gh pr merge 45                                     # interactive merge method
gh pr merge 45 --merge                             # create merge commit
gh pr merge 45 --squash                            # squash and merge
gh pr merge 45 --rebase                            # rebase and merge
gh pr merge 45 --squash --delete-branch            # squash + delete head branch
gh pr merge 45 --auto                              # auto-merge once checks pass
gh pr merge 45 --squash --subject "feat: login"    # custom squash commit message

Output: (none — exits 0 on success)

Checks

bash
gh pr checks                                       # checks on current branch's PR
gh pr checks 45
gh pr checks 45 --watch                            # stream updates until all complete
gh pr checks 45 --fail-fast                        # exit on first failure

Output:

text
All checks were successful
0 failing, 0 pending, and 3 successful checks

✓  CI / typecheck          1m23s  https://github.com/...
✓  deploy/cloudflare       2m01s  https://github.com/...
✓  CodeQL / analyze        4m15s  https://github.com/...

Comments

bash
gh pr comment 45 --body "LGTM"
gh pr comment 45 --body-file review.md
gh pr comment 45 --editor

Output: (none — exits 0 on success)


Releases

Creates and manages GitHub releases, which pair a git tag with release notes and downloadable binary assets. Use --generate-notes to auto-populate the body from merged PRs since the last release.

Create

bash
gh release create v1.0.0
gh release create v1.0.0 --title "Version 1.0.0" --notes "First stable release"
gh release create v1.0.0 --notes-file CHANGELOG.md
gh release create v1.0.0 --generate-notes             # auto-generate from merged PRs
gh release create v1.0.0 --draft
gh release create v1.0.0 --prerelease
gh release create v1.0.0 --target main                # tag from this branch/SHA
gh release create v1.0.0 dist/app.tar.gz dist/app.zip # attach assets

Output: (none — exits 0 on success)

List and view

bash
gh release list
gh release list --limit 20
gh release view v1.0.0
gh release view v1.0.0 --json tagName,name,body,assets
gh release view --json tagName | jq -r '.tagName'     # latest release tag

Output: (none — exits 0 on success)

Download

bash
gh release download v1.0.0                            # all assets
gh release download v1.0.0 --pattern "*.tar.gz"
gh release download v1.0.0 --dir ./downloads
gh release download                                    # latest release

Output: (none — exits 0 on success)

Edit and delete

bash
gh release edit v1.0.0 --title "Version 1.0.0 (LTS)"
gh release edit v1.0.0 --notes-file CHANGELOG.md
gh release edit v1.0.0 --draft=false                  # publish a draft
gh release upload v1.0.0 dist/app-v2.tar.gz           # add asset to existing release
gh release delete v1.0.0 --confirm
gh release delete v1.0.0 --cleanup-tag --confirm      # also delete the git tag

Output: (none — exits 0 on success)


Attestations

gh attestation verifies the integrity and provenance of release artifacts using Sigstore-signed build attestations. Built into core gh since v2.50, the command enforces the SLSA v1 provenance predicate by default and lets you confirm an artifact really came from the GitHub repo, commit, and workflow it claims to. Use it for supply-chain verification before installing third-party binaries or container images.

Verify a file or image

Confirms a downloaded artifact matches an attestation published by a specific owner or repo. --owner accepts any GitHub user or org; pass --repo owner/name for stricter scoping. Container images use the oci:// URI form.

bash
gh attestation verify ./app.tar.gz --owner alicedev
gh attestation verify ./app.tar.gz --repo alicedev/myrepo
gh attestation verify ./app.tar.gz --repo alicedev/myrepo --signer-workflow ".github/workflows/release.yml"

# Container image (OCI)
gh attestation verify oci://ghcr.io/alicedev/myrepo:v1.0.0 --owner alicedev

# Predicate type other than SLSA provenance
gh attestation verify ./sbom.json --owner alicedev --predicate-type "https://spdx.dev/Document"

Output:

text
Loaded digest sha256:abc123... for file://./app.tar.gz
Loaded 1 attestation from GitHub API
✓ Verification succeeded!

sha256:abc123... was attested by:
REPO              PREDICATE_TYPE                  WORKFLOW
alicedev/myrepo   https://slsa.dev/provenance/v1  .github/workflows/release.yml@refs/tags/v1.0.0

Offline verification

Use --bundle to verify against a local attestation file without network access (CI air-gaps, supply-chain audits). gh attestation trusted-root emits the Sigstore Public Good and GitHub TUF metadata you need to seed the offline verifier.

bash
gh attestation download ./app.tar.gz --repo alicedev/myrepo  # save bundle locally
gh attestation verify ./app.tar.gz --bundle ./app.tar.gz.jsonl --owner alicedev
gh attestation trusted-root > trusted_root.jsonl

Output: (none — exits 0 on success)


GitHub Actions

Commands for inspecting workflow runs, streaming logs, re-running failed jobs, triggering workflow_dispatch workflows, and managing workflow files — without leaving the terminal.

Workflow runs

bash
gh run list                                        # recent runs, all workflows
gh run list --workflow=ci.yml
gh run list --branch main
gh run list --status failure
gh run list --limit 20
gh run list --json databaseId,status,conclusion,workflowName

gh run view                                        # most recent run
gh run view 1234567890
gh run view 1234567890 --log                       # full logs
gh run view 1234567890 --log-failed                # only failed step logs
gh run view 1234567890 --web

gh run watch                                       # stream live run output
gh run watch 1234567890
gh run watch 1234567890 --exit-status              # exit non-zero if run fails

Output:

text
STATUS  TITLE                          WORKFLOW  BRANCH  EVENT  ID           ELAPSED  AGE
✓       Add slim CI workflow           CI        main    push   25007324419  1m5s     5 minutes ago
X       Add Rewriting history section  CI        main    push   25001862039  47s      2 hours ago

Re-run and cancel

bash
gh run rerun 1234567890
gh run rerun 1234567890 --failed-only               # re-run only failed jobs
gh run rerun 1234567890 --job <job-id>
gh run cancel 1234567890
gh run cancel                                       # cancel most recent run

Output: (none — exits 0 on success)

Download artifacts

bash
gh run download 1234567890                         # all artifacts
gh run download 1234567890 --name dist-files
gh run download 1234567890 --dir ./artifacts

Output: (none — exits 0 on success)

Workflows

bash
gh workflow list
gh workflow view ci.yml
gh workflow view ci.yml --yaml                     # print full YAML
gh workflow run ci.yml                             # manual trigger (workflow_dispatch)
gh workflow run ci.yml --ref feature/my-branch
gh workflow run deploy.yml --field environment=production
gh workflow enable ci.yml
gh workflow disable ci.yml

Output: (none — exits 0 on success)

Actions cache

gh cache lists and deletes the per-branch caches that actions/cache and the setup-* actions populate during workflow runs. Use it to free quota when a repo bumps against the 10 GB Actions cache limit or when a poisoned cache is wedging CI.

bash
gh cache list
gh cache list --ref refs/heads/main --limit 50
gh cache list --key node-modules-                # prefix match
gh cache list --order asc --sort size            # find the largest caches

gh cache delete <cache-id>
gh cache delete --key node-modules-abc123
gh cache delete --all                            # wipe every cache in the repo

Output: (none — exits 0 on success)


Secrets and Variables

Secrets are encrypted values (tokens, passwords) injected into Actions workflows at runtime; variables are plaintext configuration values. Both can be scoped to a repo, an environment, or an org.

Secrets

bash
gh secret list                                     # repo secrets
gh secret list --org myorg
gh secret list --env production                    # environment secrets

gh secret set MY_SECRET                            # prompts for value
gh secret set MY_SECRET --body "value"
gh secret set MY_SECRET < secret.txt               # read from file
gh secret set MY_SECRET --org myorg
gh secret set MY_SECRET --env production
gh secret set MY_SECRET --repos repo1,repo2        # org secret scoped to repos

gh secret delete MY_SECRET

Output: (none — exits 0 on success)

Variables

bash
gh variable list
gh variable set APP_ENV --body "production"
gh variable set APP_ENV --env staging --body "staging"
gh variable set APP_ENV --org myorg --body "prod"
gh variable delete APP_ENV

Output: (none — exits 0 on success)


Labels

Labels are coloured tags applied to issues and PRs for triage and filtering. Use gh label clone to copy a consistent label set from one repo to another rather than recreating them by hand.

bash
gh label list
gh label list --json name,color,description

gh label create "priority:high" --color "ff0000" --description "Urgent"
gh label edit "priority:high" --color "cc0000"
gh label delete "wontfix" --confirm

gh label clone alicedev/other-repo                 # copy all labels from another repo

Output: (none — exits 0 on success)


Milestones

Milestones group issues and PRs around a target date or release goal. There is no native gh milestone subcommand — use gh api with the REST endpoint directly.

bash
gh api repos/:owner/:repo/milestones               # list (via API — no native milestone subcommand)

# Create via API
gh api repos/:owner/:repo/milestones \
  --method POST \
  --field title="v2.0" \
  --field due_on="2026-06-01T00:00:00Z" \
  --field description="Second major release"

Output: (none — exits 0 on success)


Gists

Gists are lightweight, single-file (or multi-file) code snippets hosted on GitHub — useful for sharing scripts, configs, or notes without creating a full repository.

bash
gh gist create file.txt                            # create from file
gh gist create file.txt --public
gh gist create file.txt --desc "My snippet"
gh gist create file1.txt file2.py                  # multi-file gist
echo "content" | gh gist create -                  # from stdin
gh gist create --web file.txt                      # open browser after creating

gh gist list
gh gist list --public
gh gist list --limit 20

gh gist view <id>
gh gist view <id> --raw
gh gist view <id> --web

gh gist edit <id>                                  # open $EDITOR
gh gist edit <id> --filename newname.py

gh gist clone <id>                                 # git clone the gist
gh gist delete <id> --confirm

Output: (none — exits 0 on success)


Runs GitHub's code, repository, issue, PR, and commit search from the CLI. Supports the same qualifiers as the GitHub search UI (language:, stars:, label:, author:, etc.) and returns structured JSON output for scripting.

bash
gh search repos "astro tailwind"
gh search repos "astro" --language typescript --stars ">100"
gh search repos "astro" --sort stars --order desc --limit 20

gh search issues "login fails" --repo alicedev/myrepo
gh search issues "memory leak" --label bug --state open
gh search issues "login" --assignee @me

gh search prs "fix login" --repo alicedev/myrepo
gh search prs "refactor" --state merged --author alicedev

gh search commits "fix null pointer" --repo alicedev/myrepo
gh search commits "hotfix" --author alicedev --after "2026-01-01"

gh search code "StylesheetCSS" --repo alicedev/myrepo
gh search code "TODO" --language typescript --repo alicedev/myrepo

Output: (none — exits 0 on success)


API access

gh api makes authenticated REST or GraphQL calls without managing tokens manually.

REST

bash
gh api user                                        # authenticated user info
gh api repos/:owner/:repo                          # current repo info (auto-fills :owner/:repo)
gh api repos/alicedev/myrepo/issues                # list issues
gh api repos/:owner/:repo/pulls?state=open&per_page=50

# POST / PATCH / DELETE
gh api repos/:owner/:repo/issues \
  --method POST \
  --field title="New issue" \
  --field body="Description"

gh api repos/:owner/:repo/issues/12 \
  --method PATCH \
  --field state=closed

gh api repos/:owner/:repo/issues/12 \
  --method DELETE

Output: (none — exits 0 on success)

Pagination

bash
gh api repos/:owner/:repo/issues --paginate         # fetch all pages automatically
gh api repos/:owner/:repo/issues --paginate \
  --jq '.[].title'                                  # extract field from each page

Output: (none — exits 0 on success)

GraphQL

bash
gh api graphql --field query='
  query {
    viewer {
      login
      repositories(first: 5, orderBy: {field: UPDATED_AT, direction: DESC}) {
        nodes { name updatedAt }
      }
    }
  }
'

# With variables
gh api graphql \
  --field query='query($owner:String!, $repo:String!) {
    repository(owner:$owner, name:$repo) {
      stargazerCount
      forkCount
    }
  }' \
  --field owner=alicedev \
  --field repo=myrepo

Output: (none — exits 0 on success)

jq filtering

bash
gh api repos/:owner/:repo/issues \
  --jq '.[] | {number, title, state}'

gh api repos/:owner/:repo/pulls \
  --jq '[.[] | select(.draft == false)] | length'  # count non-draft PRs

Output: (none — exits 0 on success)

Rate limit

bash
gh api rate_limit --jq '.rate | {limit, remaining, reset}'

Output: (none — exits 0 on success)


SSH Keys

Manages the SSH public keys associated with your GitHub account — the keys that authorize git push over SSH. Add a --type signing key to enable SSH-based commit signing without a GPG setup.

bash
gh ssh-key list
gh ssh-key add ~/.ssh/id_ed25519.pub --title "Work laptop"
gh ssh-key add ~/.ssh/id_ed25519.pub --type signing   # for commit signing
gh ssh-key delete <id> --confirm

Output: (none — exits 0 on success)


GPG Keys

Manages GPG public keys linked to your GitHub account for verifying signed commits and tags. Upload your public key after generating a GPG keypair and configuring git to sign commits automatically.

bash
gh gpg-key list
gh gpg-key add public-key.gpg
gh gpg-key delete <key-id> --confirm

Output: (none — exits 0 on success)


Projects

gh project drives GitHub Projects (the v2 / "ProjectV2" boards) from the CLI — list and view projects, add issues or PRs as items, create draft items, and edit custom fields. The command requires the project scope on your token; run gh auth refresh -s project first if calls 401.

List, view, copy, create

bash
gh project list --owner alicedev                   # your projects
gh project list --owner myorg                      # an org's projects

gh project view 7 --owner alicedev                 # by project number
gh project view 7 --owner alicedev --web

gh project create --owner alicedev --title "Q3 planning"
gh project copy 7 --source-owner alicedev --target-owner myorg --title "Forked board"

Output: (none — exits 0 on success)

Items and fields

item-add attaches an existing issue or PR by URL; item-create creates a draft item that lives only on the board. Custom fields (status, iteration, single-select, number, text, date) are managed via the field-* subcommands.

bash
gh project item-list 7 --owner alicedev
gh project item-add 7 --owner alicedev --url https://github.com/alicedev/myrepo/issues/12
gh project item-create 7 --owner alicedev --title "Spike: caching" --body "Investigate..."
gh project item-edit --id PVTI_abc... --project-id PVT_xyz... --field-id PVTSSF_field... --single-select-option-id <option-id>
gh project item-archive --id PVTI_abc...

gh project field-list 7 --owner alicedev
gh project field-create 7 --owner alicedev --name "Priority" --data-type "SINGLE_SELECT" --single-select-options "Low,Medium,High"
gh project field-delete --id PVTSSF_field...

Output: (none — exits 0 on success)


Rulesets

gh ruleset inspects the branch / tag rulesets that govern push protection, required reviews, status checks, and deletion blocks for a repo or org. Use gh ruleset check to ask "what rules would apply if I pushed this branch right now?" — handy when CI starts rejecting pushes for a non-obvious reason.

bash
gh ruleset list                                    # current repo
gh ruleset list --parents                          # include org-inherited rulesets
gh ruleset list --repo alicedev/myrepo
gh ruleset list --org myorg

gh ruleset view 42                                 # by ID
gh ruleset view                                    # interactive picker
gh ruleset view --web 42

gh ruleset check feature/login                     # which rules apply to this branch
gh ruleset check                                   # check the current branch

Output:

text
1 ruleset apply to the feature/login branch in alicedev/myrepo

main-branch-protection (#42)
- Source: alicedev/myrepo (Repository)
- Enforcement: active
- Rules:
  * pull_request (required reviewers: 1, dismiss stale reviews: true)
  * required_status_checks (CI / typecheck, deploy/cloudflare)
  * non_fast_forward

Models

gh models is an installable extension (gh extension install github/gh-models) that lets you call the GitHub Models inference catalogue — OpenAI GPT, Claude, Llama, Mistral, Phi, and others — from the terminal using your GitHub token. Useful for one-off prompts in shell pipelines, prompt benchmarking, and .prompt.yml-driven evals in CI.

bash
gh extension install github/gh-models

gh models list                                     # available chat models
gh models view openai/gpt-4o-mini

# One-shot prompt
gh models run openai/gpt-4o-mini "Summarise this changelog: $(cat CHANGELOG.md)"

# Interactive chat — REPL with /help, /reset, /save
gh models run claude-3-5-sonnet

# Pipe stdin
cat error.log | gh models run openai/gpt-4o "Diagnose the failure"

# Prompt-file evaluation (eval prompts vs test cases in CI)
gh models eval ./prompts/summarise.prompt.yml
gh models generate ./prompts/summarise.prompt.yml  # auto-generate test cases + evaluator

Output: (none — exits 0 on success)


Copilot in the terminal

Since early 2026, gh copilot auto-installs and shells out to the standalone GitHub Copilot CLI on first run — no separate gh extension install required. It provides command suggestions, shell explanations, and an agentic plan-then-build mode that can edit files and run tests.

bash
gh copilot                                         # launch interactive Copilot CLI
gh copilot suggest "find all files modified in the last 24 hours"
gh copilot explain "git rebase -i HEAD~3"

# Inside the Copilot REPL
/model claude-sonnet-4.5                           # switch model (also: gpt-5, gpt-4.1, etc.)
/memory                                            # show what Copilot has remembered
# Shift+Tab cycles plan-mode on/off — Copilot drafts a plan before editing files

Output: (none — exits 0 on success)


Skill (agent skills)

gh skill (introduced in v2.90.0, April 2026, public preview) discovers, installs, previews, and publishes Agent Skills — the portable, manifest-driven extensions that work across GitHub Copilot, Claude Code, Cursor, Codex, Gemini CLI, and Antigravity. Each skill is validated against the Agent Skills spec and supply-chain checks before install.

bash
gh skill search "code review"                      # browse the skill catalogue
gh skill preview owner/repo/skill-name             # show the skill manifest + prompt
gh skill install owner/repo/skill-name             # install into your local agent
gh skill install owner/repo/skill-name --pin v1.2.0
gh skill update                                    # update all installed skills
gh skill publish ./my-skill                        # publish from a local SKILL.md directory
gh skill install owner/repo/skill --allow-hidden-dirs  # accept skills in .claude/skills/, .agents/skills/

Output: (none — exits 0 on success)


Codespaces

GitHub Codespaces are cloud-hosted development environments (VS Code + container) that start from a repo's devcontainer config. Use gh cs ssh or gh cs code to connect from the terminal or VS Code without opening a browser.

bash
gh cs list
gh cs create                                       # new codespace for current repo
gh cs create --repo alicedev/myrepo --branch main
gh cs create --machine premiumLinux                # choose machine type

gh cs ssh                                          # SSH into most recent codespace
gh cs ssh -c <name>                                # SSH into named codespace
gh cs code -c <name>                               # open in VS Code

gh cs ports list -c <name>
gh cs ports forward 3000:3000 -c <name>            # forward port locally

gh cs stop -c <name>
gh cs delete -c <name> --confirm
gh cs delete --all --confirm

Output: (none — exits 0 on success)


Status

Shows your activity across repos — mentions, review requests, assignments.

bash
gh status                                          # dashboard: all activity
gh status --org myorg                              # filter to an org
gh status --exclude alicedev/noisy-repo

Output:

text
Mentions and team mentions (3)

  alicedev/myrepo#45   Please review this PR       2 hours ago
  alicedev/myrepo#12   Can you look at this?        yesterday

Review requests (1)

  alicedev/other#8     feat: add export function    1 hour ago

Assigned issues (2)

  alicedev/myrepo#9    Add dark mode support        3 days ago

Browse

Open GitHub pages in the browser without leaving the terminal.

bash
gh browse                                          # repo home page
gh browse --branch feature/login                   # specific branch
gh browse --commit abc1234                         # specific commit
gh browse src/components/GraphView.astro           # file in browser
gh browse src/components/GraphView.astro:315       # file at line number
gh browse src/components/GraphView.astro --blame   # open git-blame view (2.88+)
gh browse --projects                               # repo projects
gh browse --wiki                                   # repo wiki
gh browse --settings                               # repo settings

Output: (none — exits 0 on success)


Extensions

Extensions are community-built gh subcommands distributed as GitHub repos. Install them with gh extension install owner/repo; they appear as gh <extension-name> commands alongside the built-in ones.

bash
gh extension list
gh extension install owner/repo                    # install by repo name
gh extension install github/gh-copilot             # example: GitHub Copilot
gh extension upgrade --all
gh extension upgrade gh-copilot
gh extension remove gh-copilot
gh extension browse                                # search extensions in browser

Output: (none — exits 0 on success)


Environment and CI usage

gh works in headless environments by reading credentials from GH_TOKEN rather than the keyring. Set GH_REPO and GH_HOST to override auto-detection when running outside a git working tree.

Non-interactive mode

bash
export GH_TOKEN=$(gh auth token)                   # expose token for other tools
export GH_REPO=alicedev/myrepo                     # override repo detection
export GH_HOST=github.mycompany.com                # GitHub Enterprise host
export GH_NO_UPDATE_NOTIFIER=1                     # suppress update notices

# Pipe-friendly — disable prompts
gh pr create --title "..." --body "..." --base main
gh issue close 12 --comment "Done"

Output: (none — exits 0 on success)

In GitHub Actions

bash
# GITHUB_TOKEN is already available as GH_TOKEN — no login needed
- name: Close stale issues
  run: gh issue close ${{ steps.find.outputs.number }} --comment "Auto-closed"
  env:
    GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Output: (none — exits 0 on success)


Common workflows

Open a PR and watch CI

bash
gh pr create --fill --draft
gh pr checks --watch
gh pr ready                                        # promote to ready after checks pass

Output: (none — exits 0 on success)

Release from CI output

bash
# Tag, build, release, attach artifact
git tag v1.2.0 && git push origin v1.2.0
gh release create v1.2.0 --generate-notes dist/app.tar.gz

Output: (none — exits 0 on success)

Bulk-close issues by label

bash
gh issue list --label "wontfix" --json number --jq '.[].number' \
  | xargs -I{} gh issue close {} --comment "Closing as wontfix"

Output: (none — exits 0 on success)

Find PRs waiting for your review

bash
gh pr list --search "review-requested:@me" --json number,title,author \
  --jq '.[] | "#\(.number) \(.title) — \(.author.login)"'

Output: (none — exits 0 on success)

Check if a branch has an open PR

bash
gh pr view --json state --jq '.state' 2>/dev/null || echo "no PR"

Output: (none — exits 0 on success)

Squash-merge all approved PRs in a repo

bash
gh pr list --state open --json number,reviewDecision \
  --jq '.[] | select(.reviewDecision == "APPROVED") | .number' \
  | xargs -I{} gh pr merge {} --squash --delete-branch

Output: (none — exits 0 on success)

Create a repo, push existing code, open in browser

bash
gh repo create myrepo --public --source=. --remote=origin --push
gh repo view --web

Output: (none — exits 0 on success)

Mirror a release asset download into a script

bash
VERSION=$(gh release view --json tagName --jq '.tagName')
gh release download "$VERSION" --pattern "*.tar.gz" --dir /tmp/release

Output: (none — exits 0 on success)


Sources