콘텐츠로 이동

7장: GitHub CLI (gh) - 터미널에서 GitHub 완전 정복

gh가 뭔가요?

GitHub CLI(gh)는 터미널에서 GitHub를 조작하는 공식 도구입니다.

웹사이트를 켜지 않아도 PR 만들고, Issue 관리하고, 저장소를 복제할 수 있습니다. CLI만큼 빠르고 편한 게 없죠.

예전: 터미널에서 코드 작성 → 브라우저 켜서 GitHub 접속 → PR 생성 → 브라우저에서 리뷰
gh:   터미널에서 코드 작성 → 터미널에서 바로 PR 생성 → 터미널에서 리뷰

설치

Windows

# 방법 1: winget (권장)
winget install --id GitHub.cli

# 방법 2: Chocolatey
choco install gh

# 방법 3: Scoop
scoop install gh

# 방법 4: 수동 설치
# https://github.com/cli/cli/releases/latest 에서
# gh_*_windows_amd64.msi 다운로드 후 설치

macOS

# 방법 1: Homebrew (권장)
brew install gh

# 방법 2: MacPorts
sudo port install gh

# 방법 3: Conda
conda install --channel conda-forge gh

Linux

Ubuntu / Debian

# 공식 저장소 추가
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

Fedora / RHEL

sudo dnf install 'dnf-command(config-manager)'
sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
sudo dnf install gh

Arch Linux

sudo pacman -S github-cli

openSUSE

sudo zypper addrepo https://cli.github.com/packages/rpm/gh-cli.repo
sudo zypper ref
sudo zypper install gh

설치 확인

gh --version
# gh version 2.x.x (2024-xx-xx)

첫 로그인

gh auth login

대화형 프롬프트가 나옵니다:

? What account do you want to log into? GitHub.com
? What is your preferred protocol for Git operations? SSH
? Upload your SSH public key to your GitHub account? (이미 있으면 Skip)
? How would you like to authenticate GitHub CLI? Login with a web browser

! First copy your one-time code: XXXX-XXXX
- Press Enter to open github.com in your browser...

# 브라우저가 열리면 코드를 붙여넣고 Authorize 클릭

: HTTPS 대신 SSH를 선택하면 비밀번호 없이 편하게 작업할 수 있습니다.

로그인 상태 확인

gh auth status
# github.com
#   ✓ Logged in to github.com as username (oauth_token)

# 계정 정보 간단히 확인
gh api user --jq '.login'

토큰으로 로그인 (CI/자동화용)

gh auth login --with-token < my-token.txt

# 또는 환경 변수
export GH_TOKEN=ghp_xxxxxxxxxxxx

저장소(Repo) 관리

저장소 생성

# 퍼블릭 저장소 만들기
gh repo create my-project --public

# 프라이빗 저장소 만들기
gh repo create my-project --private

# 현재 디렉토리로 저장소 만들고 바로 초기화
mkdir my-project && cd my-project
git init
gh repo create my-project --public --source=. --push

# 설명 추가
gh repo create my-project --public -d "나의 멋진 프로젝트"

# .gitignore 템플릿 지정
gh repo create my-project --public --gitignore Python

# 라이선스 지정
gh repo create my-project --public --license MIT

저장소 복제

# 내 저장소
gh repo clone my-project

# 다른 사람 저장소
gh repo clone someone-else/project

# 소유자 생략하면 내 계정 기준
gh repo clone my-project
# = gh repo clone myname/my-project

저장소 정보 확인

# 저장소 정보 보기
gh repo view myname/my-project

# 웹에서 보기
gh repo view myname/my-project --web

# 설명만 출력
gh repo view --json description --jq '.description'

# 저장소 목록
gh repo list                    # 내 저장소
gh repo list --limit 5          # 5개만
gh repo list --public           # 퍼블릭만
gh repo list --private          # 프라이빗만
gh repo list someone-else       # 다른 사람 저장소

# 포크하기
gh repo fork someone-else/project
gh repo fork someone-else/project --clone  # 포크 후 바로 clone

저장소 삭제

# 주의: 되돌릴 수 없습니다!
gh repo delete myname/my-project --yes

Pull Request

PR 생성

# 브랜치에서 작업 후 push했다면
gh pr create

# 대화형으로 제목, 설명 입력
# 에디터가 열리면 작성 후 저장

# 한 번에 모두 지정
gh pr create \
  --title "feat: 검색 기능 추가" \
  --body "사용자가 게시글을 키워드로 검색할 수 있는 기능입니다."

# 리뷰어 지정
gh pr create \
  --title "fix: 로그인 버그 수정" \
  --reviewer myfriend,another-friend

# 담당자(assignee) 지정
gh pr create \
  --title "refactor: API 모듈 정리" \
  --assignee me

# 라벨 지정
gh pr create \
  --title "feat: 다크모드 추가" \
  --label "enhancement,frontend"

# 드래프트 PR (아직 작성 중)
gh pr create \
  --title "WIP: 새로운 대시보드" \
  --draft

PR 관리

# PR 목록 보기
gh pr list

# 상태별로 보기
gh pr list --state open        # 열린 PR
gh pr list --state closed      # 닫힌 PR
gh pr list --state merged      # 병합된 PR
gh pr list --author me         # 내가 만든 PR
gh pr list --label bug         # bug 라벨

# 특정 PR 보기
gh pr view 12
gh pr view 12 --web            # 브라우저에서 보기

# PR 체크아웃 (리뷰하러 가기)
gh pr checkout 12
# 자동으로 해당 PR의 브랜치로 이동

# PR 병합
gh pr merge 12
# 병합 방식 선택: merge, squash, rebase

# PR 닫기
gh pr close 12

# PR 다시 열기
gh pr reopen 12

PR 리뷰

# 리뷰하기
gh pr review 12

# 코멘트만 남기기
gh pr review 12 --comment -b "좋은 코드네요!"

# 승인 (Approve)
gh pr review 12 --approve -b "LGTM!"

# 변경 요청 (Request Changes)
gh pr review 12 --request-changes -b "에러 처리가 필요합니다."

# PR의 커밋 목록 보기
gh pr view 12 --json commits --jq '.commits[].messageHeadline'

# PR의 변경 파일 보기
gh pr diff 12

PR 상태 확인

# CI/테스트 상태 확인
gh pr checks 12

# 병합 가능한 상태인지 확인
gh pr view 12 --json mergeable --jq '.mergeable'

# 리뷰 상태 확인
gh pr view 12 --json reviews --jq '.reviews[] | "\(.author.login): \(.state)"'

Issue

Issue 만들기

# 대화형으로 만들기
gh issue create

# 한 번에 지정
gh issue create \
  --title "로그인 버그" \
  --body "Safari에서 로그인 버튼이 안 눌립니다."

# 라벨, 담당자, 프로젝트 지정
gh issue create \
  --title "다크모드 기능 요청" \
  --label "enhancement" \
  --assignee me \
  --project "v2.0"

# 에디터로 작성
gh issue create --editor

Issue 관리

# 목록 보기
gh issue list

# 상태별
gh issue list --state open
gh issue list --state closed
gh issue list --state all

# 필터링
gh issue list --author me
gh issue list --assignee me
gh issue list --label bug
gh issue list --limit 10

# 특정 Issue 보기
gh issue view 5
gh issue view 5 --web         # 브라우저에서 보기

# Issue 닫기 / 다시 열기
gh issue close 5
gh issue reopen 5

# Issue에 코멘트 남기기
gh issue comment 5 -b "재현해 보겠습니다."

# Issue 수정
gh issue edit 5 --title "수정된 제목"
gh issue edit 5 --body "수정된 내용"
gh issue edit 5 --add-label "critical"
gh issue edit 5 --remove-label "enhancement"

Issue 개수 확인

# 열린/닫힌 Issue 통계
gh issue list --state all --json state --jq 'group_by(.state) | map({state: .[0].state, count: length})'

GitHub Actions

워크플로우 실행 목록

# 실행 목록 보기
gh run list

# 특정 워크플로우만
gh run list --workflow test.yml

# 최근 5개
gh run list --limit 5

실행 상태 확인

# 특정 실행 상세 보기
gh run view 12345

# 실시간 로그 보기
gh run watch 12345

# 가장 최근 실행 watch
gh run watch

# 실패한 실행의 로그 보기
gh run view 12345 --log-failed

워크플로우 수동 실행

# 수동 트리거가 설정된 워크플로우 실행
gh workflow run test.yml

# 파라미터와 함께
gh workflow run deploy.yml -f environment=staging

# 워크플로우 목록
gh workflow list

Release

# 릴리즈 생성
gh release create v1.0.0

# 타이틀과 노트 포함
gh release create v1.0.0 \
  --title "v1.0.0 - 첫 정식 릴리즈!" \
  --notes "## 변경사항
- 검색 기능 추가
- 로그인 버그 수정"

# 파일 첨부 (빌드 산출물 등)
gh release create v1.0.0 ./dist/app.zip

# 프리릴리즈
gh release create v2.0.0-beta.1 --prerelease

# 릴리즈 목록
gh release list

# 특정 릴리즈 보기
gh release view v1.0.0

# 릴리즈 다운로드
gh release download v1.0.0

# 릴리즈 삭제
gh release delete v1.0.0 --yes

Gist

# 코드 스니펫 공유
gh gist create hello.py

# 설명과 함께
gh gist create hello.py -d "Hello World 예제"

# 퍼블릭 gist
gh gist create hello.py --public

# stdin에서 생성
echo "print('hello')" | gh gist create -t python

# gist 목록
gh gist list

# gist 보기
gh gist view abc123

# gist 수정
gh gist edit abc123

API 직접 호출

gh api를 쓰면 GitHub API를 직접 호출할 수 있습니다.

# 내 정보
gh api user

# 특정 저장소 정보
gh api repos/owner/repo

# 이슈 검색
gh api "search/issues?q=repo:owner/repo+is:issue+is:open"

# JSON 필터링 (jq 문법)
gh api user --jq '.login'
gh api user --jq '.public_repos'

# POST 요청
gh api repos/owner/repo/issues \
  -f title="New Issue" \
  -f body="Issue 내용"

# REST API가 아닌 GraphQL도 가능
gh api graphql -f query='{ viewer { login } }'

검색

# 저장소 검색
gh search repos "react todo app" --limit 5

# 언어 필터
gh search repos "web framework" --language python

# 별 개수 필터
gh search repos "cli tool" --stars ">1000"

# 이슈 검색
gh search issues "memory leak" --repo owner/repo

# PR 검색
gh search prs "fix login" --state open --repo owner/repo

# 코드 검색
gh search code "TODO" --repo owner/repo

확장 (Extensions)

# 확장 목록 보기
gh extension list

# 확장 설치
gh extension install owner/gh-extension-name

# 인기 있는 확장들
gh extension install dlvhdr/gh-dash      # PR/Issue 대시보드
gh extension install meiji163/gh-notify   # 알림 관리

# 직접 만들기도 가능
gh extension create my-extension

실전: 하루 GitHub 워크플로우

# 아침: 알림 확인
gh api notifications --jq '.[] | "\(.repository.full_name): \(.subject.title)"'

# 작업 시작: 브랜치 만들고 작업
git checkout -b feature/search
# ... 코딩 ...
git add . && git commit -m "feat: add search"
git push -u origin feature/search

# PR 생성
gh pr create \
  --title "feat: 검색 기능 추가" \
  --body "## 변경사항
- 키워드 검색 API 연동
- 검색 결과 UI 구현

## 테스트
- [x] 키워드 입력 후 결과 표시
- [x] 빈 검색어 처리" \
  --reviewer myfriend \
  --label "enhancement"

# PR 번호 확인
gh pr list --author me --state open

# 리뷰 확인
gh pr view 1 --comments
gh pr checks 1

# 병합
gh pr merge 1 --squash

# 로컬 업데이트
git checkout main && git pull

# 이슈 정리
gh issue close 5 -b "PR #1 에서 해결"

명령어 치트시트

# 인증
gh auth login              # 로그인
gh auth status             # 상태 확인
gh auth logout             # 로그아웃

# 저장소
gh repo create             # 만들기
gh repo clone              # 복제
gh repo view               # 보기
gh repo fork               # 포크
gh repo list               # 목록

# Pull Request
gh pr create               # PR 만들기
gh pr list                 # 목록
gh pr view 12              # 상세
gh pr checkout 12          # 브랜치로 이동
gh pr merge 12             # 병합
gh pr review 12 --approve  # 승인
gh pr close 12             # 닫기
gh pr diff 12              # 변경사항
gh pr checks 12            # CI 상태

# Issue
gh issue create            # 만들기
gh issue list              # 목록
gh issue view 5            # 상세
gh issue close 5           # 닫기
gh issue comment 5 -b "..." # 코멘트
gh issue edit 5            # 수정

# Actions
gh run list                # 실행 목록
gh run view 12345          # 상세
gh run watch               # 실시간 모니터링

# Release
gh release create v1.0.0   # 릴리즈
gh release list            # 목록
gh release download v1.0.0 # 다운로드

# 검색
gh search repos "키워드"    # 저장소 검색
gh search issues "키워드"   # 이슈 검색
gh search prs "키워드"      # PR 검색

# API
gh api user                # API 호출
gh api user --jq '.login'  # JSON 필터링

실습 미션

  1. gh를 설치하고 gh auth login으로 로그인하세요
  2. gh repo create gh-practice --public -d "gh 연습용"으로 저장소를 만드세요
  3. 저장소를 clone하고 파일을 하나 만들어 push하세요
  4. 브랜치를 만들어 변경 후 gh pr create로 PR을 만드세요
  5. gh pr viewgh pr diff로 PR을 확인해 보세요
  6. gh pr merge로 PR을 병합해 보세요
  7. gh issue create로 이슈를 만들어 보세요
  8. gh release create v1.0.0으로 첫 릴리즈를 만들어 보세요

이전 장: 06-git-tips.md 다음 장: 08-git-troubleshooting.md - 문제 해결 가이드