기본 패턴
# 새 저장소를 sparse checkout으로 클론
git clone --filter=blob:none --no-checkout https://github.com/org/monorepo
cd monorepo
# cone 모드 활성화 및 필요한 디렉터리만 지정
git sparse-checkout init --cone
git sparse-checkout set apps/web packages/ui
# 파일 체크아웃
git checkout main설명
sparse checkout은 working tree에 체크아웃할 경로를 선택적으로 제한한다 — 대형 모노레포에서 필수다
git clone은 기본적으로 저장소의 모든 파일을 working tree에 체크아웃한다. 수백 개의 패키지가 있는 모노레포에서 내가 담당하는 두 세 개 패키지만 작업한다면, 나머지 수만 개 파일은 불필요하게 디스크를 차지하고 IDE의 파일 색인 속도를 떨어뜨린다. sparse checkout은 체크아웃할 경로 목록을 .git/info/sparse-checkout 파일에 기록해 working tree를 해당 경로로만 채운다. Git 오브젝트 데이터베이스에는 전체 히스토리가 있지만 working tree에는 필요한 부분만 존재한다.
# 기존 저장소에서 sparse checkout 활성화
git sparse-checkout init --cone
git sparse-checkout set apps/web packages/ui packages/shared
# 현재 설정 확인
git sparse-checkout list
# apps/web
# packages/shared
# packages/ui
# working tree 확인 — 지정 경로 외 디렉터리는 없음
ls
# apps/ packages/cone 모드는 디렉터리 단위로만 선택해 패턴 매칭 오버헤드를 없앤다 — non-cone 대비 성능이 확연히 다르다
non-cone 모드는 glob 패턴으로 파일을 선택할 수 있어 유연하지만, 모든 파일 경로를 패턴과 대조해야 해서 파일 수가 많을수록 느려진다. cone 모드는 경로 지정을 디렉터리 단위로만 허용하는 대신 "이 디렉터리의 모든 하위 파일을 포함한다"는 단순한 규칙을 쓰기 때문에 해시 테이블 조회로 처리할 수 있어 훨씬 빠르다. 수십만 파일이 있는 모노레포에서 non-cone과 cone의 checkout 속도 차이는 수십 배에 달한다. Git 2.26 이상에서 cone 모드가 도입됐고 현재는 기본값이 cone이다.
# cone 모드 (권장) — 디렉터리 단위만 지정 가능
git sparse-checkout init --cone
git sparse-checkout set apps/web # apps/web/ 전체 포함
# non-cone 모드 — 유연하지만 느림 (레거시 방식)
git sparse-checkout init # --cone 없이
# .git/info/sparse-checkout 파일을 직접 편집
# /apps/web/
# !/apps/web/legacy/
# cone 모드에서 파일 단위 지정은 불가
# ❌ git sparse-checkout set apps/web/src/index.ts (파일 단위 안 됨)
# ✅ git sparse-checkout set apps/web (디렉터리 단위만 가능)--filter=blob:none (partial clone)과 조합하면 네트워크·디스크 사용량을 모두 줄인다
sparse checkout만으로는 working tree를 줄일 뿐, 저장소 오브젝트 데이터베이스에는 전체 파일 blob이 다운로드된다. --filter=blob:none을 추가하면 partial clone 기능이 활성화되어 최초 클론 시 파일 내용(blob)을 제외하고 트리와 커밋 메타데이터만 받아온다. blob는 실제로 파일을 체크아웃하거나 git show로 내용을 볼 때 필요에 따라 lazy-fetch한다. sparse checkout과 함께 쓰면 필요한 경로의 blob만 요청하므로 클론 시간과 디스크 공간을 모두 절약한다. 서버가 partial clone을 지원해야 하며 GitHub, GitLab, Gitea 모두 지원한다.
# partial clone + sparse checkout 조합 (권장 패턴)
git clone \
--filter=blob:none \ # blob을 lazy-fetch
--no-checkout \ # 클론 직후 체크아웃 생략
https://github.com/org/monorepo
cd monorepo
git sparse-checkout init --cone
git sparse-checkout set apps/web packages/ui
git checkout main # 필요한 blob만 받아 체크아웃
# 효과 비교 (예시)
# 일반 clone: 2.1 GB, 4분 30초
# partial clone만: 400 MB, 55초
# partial + sparse: 18 MB, 6초팀 온보딩 스크립트에 sparse checkout을 자동화하면 초기 설정 비용을 없앤다
sparse checkout 명령을 매번 직접 입력하는 것은 팀원마다 설정이 달라질 가능성이 있다. 팀별 패키지 목록을 담은 셸 스크립트를 저장소에 포함시키면 온보딩 시 한 명령으로 환경을 재현할 수 있다. CI 환경에서도 필요한 경로만 체크아웃해 빌드 속도를 줄이는 데 활용할 수 있다.
# scripts/checkout-frontend.sh (저장소에 포함)
#!/bin/bash
set -e
REPO_URL="https://github.com/org/monorepo"
git clone --filter=blob:none --no-checkout "$REPO_URL" .
git sparse-checkout init --cone
git sparse-checkout set \
apps/web \
packages/ui \
packages/shared \
packages/config
git checkout main
echo "✓ frontend 작업 환경 준비 완료"
echo "포함된 경로:"
git sparse-checkout list
# CI에서 특정 앱만 빌드할 때
# git sparse-checkout set apps/web packages/ui packages/shared
# npm ci --workspace=apps/web
# npm run build --workspace=apps/web빠른 정리
| 상황 | 적합한 선택 |
|---|---|
| 모노레포에서 일부 패키지만 작업 | git sparse-checkout init --cone + set |
| 클론 시간과 디스크 모두 줄이기 | --filter=blob:none + sparse checkout |
| 파일 단위로 세밀하게 선택 | non-cone 모드 (속도 저하 감수) |
| 디렉터리 추가/제거 | git sparse-checkout add/set 재실행 |
| sparse checkout 해제, 전체 복원 | git sparse-checkout disable |
주의할 점
cone 모드에서는 파일 단위 include가 불가능하며, 디렉터리 단위로만 지정할 수 있습니다. 또한 sparse checkout으로 숨겨진 파일을 수정하면 예상치 못한 결과가 나올 수 있습니다.
# ❌ cone 모드에서 특정 파일만 지정하려 해도 동작하지 않음
git sparse-checkout set apps/web/src/index.ts
# → apps/web 전체가 포함되거나 오류 발생
# ✅ cone 모드에서는 디렉터리 단위로만 지정
git sparse-checkout set apps/web
# ❌ sparse checkout 상태에서 전체 파일 대상 명령 실행 주의
git grep "TODO" -- .
# → working tree에 없는 파일은 검색 안 됨
# ✅ 전체 저장소 대상 검색은 별도 옵션 필요
git grep "TODO" $(git rev-parse HEAD)sparse checkout은 working tree에만 영향을 주며 오브젝트 데이터베이스는 그대로입니다.
git log, git show 등 히스토리 명령은 평소와 동일하게 동작합니다.