← Back to all cheatsheets
DevOps
githubgitcliversion-controldevops

GitHub CLI (gh) Cheat Sheet

Installation & Setup

Install GitHub CLI

# macOS (Homebrew)
brew install gh

# macOS (MacPorts)
sudo port install gh

# Ubuntu/Debian
sudo apt install gh

# Fedora/RHEL/CentOS
sudo dnf install gh

# Arch Linux
sudo pacman -S github-cli

# Windows (Scoop)
scoop install gh

# Windows (Winget)
winget install --id GitHub.cli

# Verify installation
gh --version

Authentication

# Login to GitHub (interactive)
gh auth login

# Login with specific protocol
gh auth login --with-token < token.txt

# Login to GitHub Enterprise
gh auth login --hostname github.enterprise.com

# Check authentication status
gh auth status

# Logout
gh auth logout

# Setup git credential helper
gh auth setup-git

# Refresh authentication
gh auth refresh

Repository Operations

Creating Repositories

# Create new repository (interactive)
gh repo create

# Create public repository
gh repo create myrepo --public

# Create private repository
gh repo create myrepo --private

# Create from current directory
gh repo create --source=. --public

# Create with description and README
gh repo create myrepo --public --description "My project" --add-readme

# Create and clone
gh repo create myrepo --public --clone

# Create from template
gh repo create myrepo --template owner/template-repo

Cloning Repositories

# Clone your repository
gh repo clone myrepo

# Clone someone else's repository
gh repo clone owner/repo

# Clone with specific name
gh repo clone owner/repo custom-name

Repository Management

# View repository in browser
gh repo view

# View specific repository
gh repo view owner/repo

# View repository details
gh repo view owner/repo --json name,description,url

# List your repositories
gh repo list

# List organization repositories
gh repo list orgname

# Filter repositories
gh repo list --limit 50
gh repo list --public
gh repo list --private
gh repo list --source
gh repo list --fork

# Fork a repository
gh repo fork owner/repo

# Fork and clone
gh repo fork owner/repo --clone

# Rename repository
gh repo rename new-name

# Delete repository
gh repo delete owner/repo

# Archive repository
gh repo archive owner/repo

# Sync fork with upstream
gh repo sync owner/repo

Issues

Creating Issues

# Create issue (interactive)
gh issue create

# Create with title and body
gh issue create --title "Bug report" --body "Description of bug"

# Create from file
gh issue create --title "Bug" --body-file bug-report.md

# Create with labels
gh issue create --title "Bug" --label bug,critical

# Create and assign
gh issue create --title "Task" --assignee username

# Create with milestone
gh issue create --title "Feature" --milestone "v1.0"

# Create and open in browser
gh issue create --web

Listing Issues

# List open issues
gh issue list

# List all issues (including closed)
gh issue list --state all

# List closed issues
gh issue list --state closed

# Filter by label
gh issue list --label bug
gh issue list --label "help wanted"

# Filter by assignee
gh issue list --assignee username
gh issue list --assignee @me

# Filter by author
gh issue list --author username

# Limit results
gh issue list --limit 50

# Search issues
gh issue list --search "error in login"

# List with specific fields
gh issue list --json number,title,state,labels

Viewing Issues

# View issue details
gh issue view 123

# View in browser
gh issue view 123 --web

# View comments
gh issue view 123 --comments

# View specific fields
gh issue view 123 --json title,body,state,labels

Managing Issues

# Close issue
gh issue close 123

# Close with comment
gh issue close 123 --comment "Fixed in PR #456"

# Reopen issue
gh issue reopen 123

# Edit issue
gh issue edit 123 --title "New title"
gh issue edit 123 --body "New description"
gh issue edit 123 --add-label bug
gh issue edit 123 --remove-label question
gh issue edit 123 --add-assignee username
gh issue edit 123 --remove-assignee username

# Comment on issue
gh issue comment 123 --body "This is a comment"

# Delete issue (requires admin)
gh issue delete 123

# Pin issue
gh issue pin 123

# Unpin issue
gh issue unpin 123

# Transfer issue to another repository
gh issue transfer 123 owner/other-repo

Pull Requests

Creating Pull Requests

# Create PR (interactive)
gh pr create

# Create with title and body
gh pr create --title "Add feature" --body "Description"

# Create from file
gh pr create --title "Fix bug" --body-file pr-description.md

# Create draft PR
gh pr create --draft

# Create and assign reviewers
gh pr create --reviewer user1,user2

# Create with labels
gh pr create --label enhancement,documentation

# Create to specific branch
gh pr create --base develop

# Create from specific branch
gh pr create --head feature-branch

# Create and open in browser
gh pr create --web

# Create and auto-merge when checks pass
gh pr create --title "Feature" --body "Description" && gh pr merge --auto --squash

Listing Pull Requests

# List open PRs
gh pr list

# List all PRs
gh pr list --state all

# List closed/merged PRs
gh pr list --state closed
gh pr list --state merged

# Filter by label
gh pr list --label bug

# Filter by assignee
gh pr list --assignee @me

# Filter by author
gh pr list --author username

# Search PRs
gh pr list --search "authentication"

# List with specific fields
gh pr list --json number,title,state,headRefName

Viewing Pull Requests

# View PR details
gh pr view 456

# View in browser
gh pr view 456 --web

# View PR diff
gh pr diff 456

# View PR checks
gh pr checks 456

# View PR comments
gh pr view 456 --comments

# View specific fields
gh pr view 456 --json title,body,state,reviews

Managing Pull Requests

# Checkout PR locally
gh pr checkout 456

# Review PR
gh pr review 456

# Approve PR
gh pr review 456 --approve

# Request changes
gh pr review 456 --request-changes --body "Please fix formatting"

# Comment on PR
gh pr review 456 --comment --body "Looks good overall"

# Edit PR
gh pr edit 456 --title "New title"
gh pr edit 456 --body "New description"
gh pr edit 456 --add-reviewer user1
gh pr edit 456 --add-label bug

# Mark PR as ready for review
gh pr ready 456

# Convert to draft
gh pr ready 456 --undo

# Close PR
gh pr close 456

# Reopen PR
gh pr reopen 456

# Merge PR
gh pr merge 456

# Merge with squash
gh pr merge 456 --squash

# Merge with rebase
gh pr merge 456 --rebase

# Merge and delete branch
gh pr merge 456 --merge --delete-branch

# Auto-merge when checks pass
gh pr merge 456 --auto --squash

# Comment on PR
gh pr comment 456 --body "Great work!"

PR Workflows

# Create branch, make changes, and create PR
git checkout -b feature-branch
# ... make changes ...
git add .
git commit -m "Add feature"
git push -u origin feature-branch
gh pr create --title "Add new feature" --body "Description of feature"

# Review and merge workflow
gh pr list
gh pr view 456
gh pr diff 456
gh pr checks 456
gh pr review 456 --approve
gh pr merge 456 --squash --delete-branch

# Update PR with latest from main
gh pr checkout 456
git fetch origin
git rebase origin/main
git push --force-with-lease

GitHub Actions

Viewing Workflows

# List workflows
gh workflow list

# View workflow runs
gh run list

# View specific workflow runs
gh run list --workflow=ci.yml

# View run details
gh run view 123456

# View run in browser
gh run view 123456 --web

# Watch run in real-time
gh run watch 123456

# View run logs
gh run view 123456 --log

# Download run artifacts
gh run download 123456

Managing Workflows

# Trigger workflow manually
gh workflow run ci.yml

# Trigger with inputs
gh workflow run release.yml --field version=1.0.0

# Rerun workflow
gh run rerun 123456

# Rerun failed jobs only
gh run rerun 123456 --failed

# Cancel workflow run
gh run cancel 123456

# Delete workflow run
gh run delete 123456

# Enable workflow
gh workflow enable ci.yml

# Disable workflow
gh workflow disable ci.yml

# View workflow file
gh workflow view ci.yml

Releases

Creating Releases

# Create release (interactive)
gh release create

# Create release with tag
gh release create v1.0.0

# Create with title and notes
gh release create v1.0.0 --title "Version 1.0.0" --notes "Release notes"

# Create from notes file
gh release create v1.0.0 --notes-file CHANGELOG.md

# Create and upload assets
gh release create v1.0.0 ./dist/*.zip

# Create draft release
gh release create v1.0.0 --draft

# Create prerelease
gh release create v1.0.0-beta --prerelease

# Auto-generate release notes
gh release create v1.0.0 --generate-notes

Managing Releases

# List releases
gh release list

# View release
gh release view v1.0.0

# View latest release
gh release view --latest

# Download release assets
gh release download v1.0.0

# Download specific asset
gh release download v1.0.0 --pattern "*.zip"

# Upload assets to existing release
gh release upload v1.0.0 ./dist/*.zip

# Edit release
gh release edit v1.0.0 --title "New title"

# Delete release
gh release delete v1.0.0

# Delete and keep tag
gh release delete v1.0.0 --yes

Gists

Creating Gists

# Create public gist from file
gh gist create file.txt

# Create private gist
gh gist create file.txt --secret

# Create from multiple files
gh gist create file1.txt file2.js

# Create from stdin
echo "console.log('hello')" | gh gist create --filename hello.js

# Create with description
gh gist create file.txt --desc "My useful script"

Managing Gists

# List your gists
gh gist list

# View gist
gh gist view gist-id

# Edit gist
gh gist edit gist-id

# Delete gist
gh gist delete gist-id

# Clone gist
gh gist clone gist-id

Searching

Search Repositories

# Search repositories
gh search repos "machine learning"

# Search with filters
gh search repos "react" --language=javascript
gh search repos "kubernetes" --stars=">1000"
gh search repos "docker" --forks=">100"
gh search repos "api" --topic=rest

# Search in organization
gh search repos "tools" --owner=organization-name

# Sort results
gh search repos "python" --sort=stars
gh search repos "nodejs" --sort=forks
gh search repos "vue" --sort=updated

# Limit results
gh search repos "golang" --limit 50

# Output as JSON
gh search repos "rust" --json name,description,stars

Search Issues and Pull Requests

# Search issues
gh search issues "bug"

# Search in specific repository
gh search issues "error" --repo=owner/repo

# Search with filters
gh search issues "crash" --state=open
gh search issues "feature" --label=enhancement
gh search issues "security" --author=username

# Search PRs
gh search prs "refactor"

# Search merged PRs
gh search prs "update" --state=merged

# Search draft PRs
gh search prs "draft" --draft

# Combine filters
gh search issues "performance" --state=open --label=bug --sort=comments

Search Code

# Search code
gh search code "function login"

# Search in specific language
gh search code "import pandas" --language=python

# Search in organization
gh search code "config" --owner=orgname

# Search in specific repository
gh search code "authentication" --repo=owner/repo

# Search with path filter
gh search code "test" --path="**/*.test.js"

# Search in specific file
gh search code "API_KEY" --filename=config.js

Search Commits

# Search commits
gh search commits "fix bug"

# Search by author
gh search commits "refactor" --author=username

# Search in repository
gh search commits "update" --repo=owner/repo

# Search by date
gh search commits "merge" --author-date=">2024-01-01"

# Search in specific organization
gh search commits "deploy" --owner=orgname

Finding Deleted Files

Using Git Log to Find Deleted Files

# Find all deleted files
git log --all --full-history --diff-filter=D --summary

# Find deleted files with specific name
git log --all --full-history --diff-filter=D --summary | grep "filename"

# Find when specific file was deleted
git log --all --full-history -- path/to/deleted/file.txt

# Find deleted files in specific directory
git log --all --full-history --diff-filter=D --summary -- path/to/directory/

# Show commits that deleted files
git log --diff-filter=D --summary

# Find who deleted a file
git log --all --full-history -- path/to/file.txt
# Last commit shown is when it was deleted

Searching GitHub for Deleted Files

# Search code history (GitHub web search)
# In browser: Go to repository > Click "Go to file" > Search filename

# Use gh to search commits mentioning the file
gh api "repos/owner/repo/commits?path=deleted-file.txt"

# Search in all branches for file history
gh api "repos/owner/repo/git/trees/main?recursive=1" | grep "filename"

# Find file in old commits
git log --all --full-history --oneline -- path/to/file
# Then restore from specific commit:
git checkout <commit-hash> -- path/to/file

Restoring Deleted Files

# Find the commit where file was deleted
git log --all --full-history --diff-filter=D --summary | grep "myfile.txt"

# Get the commit hash before deletion
git log --all --full-history -- path/to/myfile.txt

# Restore file from commit before deletion
git checkout <commit-hash>^ -- path/to/myfile.txt

# Or restore from specific commit
git checkout <commit-hash>~1 -- path/to/myfile.txt

# Restore and commit
git checkout <commit-hash>^ -- path/to/myfile.txt
git add path/to/myfile.txt
git commit -m "Restore deleted file"

# Create new branch with restored file
git checkout -b restore-file
git checkout <commit-hash>^ -- path/to/myfile.txt
git commit -m "Restore myfile.txt"
gh pr create --title "Restore deleted file"

Finding Deleted Files in Pull Requests

# Search PRs that deleted files
gh search prs "delete" --repo=owner/repo

# View PR that deleted specific files
gh pr list --search "filename" --state=merged

# View files changed in PR
gh pr view 123 --json files --jq '.files[] | select(.deletions > 0)'

# See deleted files in a PR
gh pr diff 123 | grep "^---"
# Find all files deleted in last 30 days
git log --since="30 days ago" --diff-filter=D --summary

# Find deleted files with specific extension
git log --all --full-history --diff-filter=D --summary | grep "\.js$"

# Find deleted files by size (large files)
git log --all --full-history --diff-filter=D --stat | grep -B 3 "changed"

# Search commit messages for deletions
gh api "repos/owner/repo/commits" --jq '.[] | select(.commit.message | contains("delete") or contains("remove"))'

# Find files deleted in specific date range
git log --since="2024-01-01" --until="2024-12-31" --diff-filter=D --summary

# Use GitHub API to search commits
gh api "search/commits?q=repo:owner/repo+delete+filename" --jq '.items[] | {sha: .sha, message: .commit.message, date: .commit.author.date}'

API Access

Making API Calls

# Basic API call
gh api repos/owner/repo

# POST request
gh api repos/owner/repo/issues -f title="Bug" -f body="Description"

# With pagination
gh api repos/owner/repo/issues --paginate

# Specify fields with jq
gh api repos/owner/repo --jq '.name'

# Pretty print JSON
gh api repos/owner/repo | jq '.'

# Save to file
gh api repos/owner/repo > repo.json

Common API Operations

# List repository branches
gh api repos/owner/repo/branches

# Get repository statistics
gh api repos/owner/repo --jq '{stars: .stargazers_count, forks: .forks_count}'

# List repository contributors
gh api repos/owner/repo/contributors

# Get rate limit status
gh api rate_limit

# List organization members
gh api orgs/orgname/members

# Get user information
gh api users/username

# List repository tags
gh api repos/owner/repo/tags

# Get latest release
gh api repos/owner/repo/releases/latest

Aliases

Creating Aliases

# Create alias
gh alias set pv 'pr view'

# Usage: gh pv 123

# Common aliases
gh alias set co 'pr checkout'
gh alias set pc 'pr create'
gh alias set prs 'pr list'
gh alias set issues 'issue list'
gh alias set ic 'issue create'

# Alias with flags
gh alias set bugs 'issue list --label=bug'

# Complex alias
gh alias set myprs 'pr list --author=@me --state=open'

# List aliases
gh alias list

# Delete alias
gh alias delete pv

Useful Alias Examples

# Quick PR creation
gh alias set quickpr 'pr create --fill'

# View my issues
gh alias set myissues 'issue list --assignee=@me'

# Recent PRs
gh alias set recent 'pr list --limit 5'

# Create issue from template
gh alias set bug 'issue create --label=bug --assignee=@me'

# Approve and merge
gh alias set shipit 'pr review --approve'

# Check CI status
gh alias set ci 'pr checks'

# Clone my repos
gh alias set cloneme 'repo clone'

Configuration

View Configuration

# View all configuration
gh config list

# View specific config
gh config get editor

# View config location
gh config get --host github.com git_protocol

Set Configuration

# Set editor
gh config set editor vim

# Set git protocol
gh config set git_protocol ssh

# Set browser
gh config set browser firefox

# Set default repository
gh config set default_repo owner/repo

# Set pager
gh config set pager less

Advanced Tips

Scripting with gh

# Get repository name
REPO=$(gh repo view --json name --jq '.name')

# Get PR number
PR=$(gh pr view --json number --jq '.number')

# Check if PR is approved
APPROVED=$(gh pr view 123 --json reviewDecision --jq '.reviewDecision')

# Loop through issues
gh issue list --json number --jq '.[].number' | while read issue; do
  gh issue view $issue
done

# Create multiple issues from file
while IFS= read -r line; do
  gh issue create --title "$line" --body "Auto-generated"
done < issues.txt

# Bulk close issues
gh issue list --label "wontfix" --json number --jq '.[].number' | \
  xargs -I {} gh issue close {}

CI/CD Integration

# Check if workflow is successful
gh run list --workflow=ci.yml --status=success --limit 1

# Wait for checks to pass
while ! gh pr checks | grep -q "All checks have passed"; do
  sleep 10
done

# Auto-merge after CI passes
gh pr create --title "Update" --body "Auto update"
PR_NUMBER=$(gh pr list --limit 1 --json number --jq '.[0].number')
gh pr merge $PR_NUMBER --auto --squash

# Trigger release workflow
gh workflow run release.yml -f version=1.0.0

Working with Multiple Repositories

# Clone all repositories from organization
gh repo list orgname --limit 1000 --json name --jq '.[].name' | \
  xargs -I {} gh repo clone orgname/{}

# Update all repositories
for repo in */; do
  cd "$repo"
  git pull
  cd ..
done

# Check status of all repos
for repo in */; do
  echo "=== $repo ==="
  cd "$repo"
  git status --short
  cd ..
done

# Run command in all repos
for repo in */; do
  cd "$repo"
  gh pr list
  cd ..
done

Batch Operations

# Close all stale issues
gh issue list --label stale --json number --jq '.[].number' | \
  xargs -I {} gh issue close {} --comment "Closing stale issue"

# Add label to multiple issues
for issue in 1 2 3 4 5; do
  gh issue edit $issue --add-label priority
done

# Request review from team
gh pr list --author=@me --json number --jq '.[].number' | \
  xargs -I {} gh pr edit {} --add-reviewer team-name

# Approve all PRs from specific author
gh pr list --author=username --json number --jq '.[].number' | \
  xargs -I {} gh pr review {} --approve

Quick Reference

# Authentication
gh auth login                           # Login to GitHub
gh auth status                          # Check auth status

# Repositories
gh repo create <name>                   # Create repository
gh repo clone <owner/repo>              # Clone repository
gh repo view                            # View repository
gh repo fork <owner/repo>               # Fork repository

# Issues
gh issue create                         # Create issue
gh issue list                           # List issues
gh issue view <number>                  # View issue
gh issue close <number>                 # Close issue

# Pull Requests
gh pr create                            # Create PR
gh pr list                              # List PRs
gh pr view <number>                     # View PR
gh pr checkout <number>                 # Checkout PR
gh pr merge <number>                    # Merge PR
gh pr review <number> --approve         # Approve PR

# Actions
gh workflow list                        # List workflows
gh run list                             # List workflow runs
gh run view <run-id>                    # View run details
gh run watch <run-id>                   # Watch run

# Releases
gh release create <tag>                 # Create release
gh release list                         # List releases
gh release download <tag>               # Download release

# Search
gh search repos <query>                 # Search repositories
gh search issues <query>                # Search issues
gh search code <query>                  # Search code

# Deleted Files
git log --diff-filter=D --summary       # Find deleted files
git checkout <commit>^ -- <file>        # Restore deleted file

# API
gh api <endpoint>                       # Make API call
gh api repos/owner/repo                 # Get repo info

# Aliases
gh alias set <name> <command>           # Create alias
gh alias list                           # List aliases

Best Practices

# 1. Use gh for GitHub operations, git for local operations
gh pr create                            # Create PR (GitHub)
git commit -m "message"                 # Commit (local)

# 2. Always authenticate before scripting
gh auth status || gh auth login

# 3. Use JSON output for scripting
gh pr list --json number,title --jq '.'

# 4. Create aliases for common workflows
gh alias set quickship 'pr merge --squash --delete-branch'

# 5. Use --web to open in browser when needed
gh pr view 123 --web

# 6. Paginate API calls for complete data
gh api repos/owner/repo/issues --paginate

# 7. Use specific repo context in scripts
gh issue list --repo=owner/repo

# 8. Check rate limits in scripts
gh api rate_limit --jq '.rate.remaining'

# 9. Use draft PRs for work in progress
gh pr create --draft

# 10. Auto-merge only with required checks
gh pr merge --auto --squash

Troubleshooting

# Debug mode
GH_DEBUG=1 gh pr list

# Check gh version
gh --version

# Update gh
brew upgrade gh                         # macOS
sudo apt update && sudo apt upgrade gh  # Ubuntu/Debian

# Clear authentication
gh auth logout
gh auth login

# Check API rate limit
gh api rate_limit

# Verify repository access
gh repo view owner/repo

# Check workflow permissions
gh workflow list

# View full API response
gh api repos/owner/repo --include

Resources