.gitignore 작성법 및 패턴 매칭 규칙
와일드카드 glob, 슬래시 위치에 따른 동작 차이, ! 부정 규칙 사용 시 주의해야 할 디렉터리 함정 등 Git 무시 패턴의 전반적인 기술 사양 정리.
.gitignore 파일의 각 줄은 독립적인 무시 패턴을 정의하며, 3가지 기본 서식 규칙이 적용됩니다:
- 빈 줄은 완전히 무시되며, 가독성을 위한 구분선으로 자유롭게 활용할 수 있습니다.
- # 기호로 시작하는 줄은 주석으로 취급되어 버전 관리에 아무런 영향을 미치지 않습니다.
- 줄 끝의 공백은 무시됩니다. 공백을 패턴에 포함하려면 백슬래시(\ )로 이스케이프해야 합니다.
# Ignore compiled Python bytecode
__pycache__/
*.py[cod]
# Ignore local secret configurations
.env
.env.localGit은 단일 폴더 계층 내에서 셸 표준 glob 와일드카드를 지원합니다:
- * (별표): 단일 경로 세그먼트 내 0개 이상의 문자와 일치합니다. *.log는 error.log와 일치하지만, 경로가 고정된 경우 sub/error.log와는 일치하지 않습니다.
- ? (물음표): 정확히 1개의 문자와 일치합니다. test?.js는 test1.js와 일치하지만, test12.js와는 일치하지 않습니다.
- [abc] (문자 범위): 대괄호 안의 문자 중 하나와 일치합니다. *.[oa]는 .o 또는 .a 확장자 파일과 일치합니다.
슬래시(/)의 위치에 따라 Git이 패턴을 해석하는 방식이 완전히 달라집니다:
- 끝 슬래시 (logs/): 오직 디렉터리에만 매칭됩니다. logs/ 폴더는 무시되지만, 같은 이름의 일반 파일 logs는 무시되지 않습니다.
- 시작 슬래시 (/config.json): .gitignore 파일이 위치한 저장소 루트에 경로를 고정합니다. /config.json만 무시되며, 하위 폴더의 /sub/config.json은 추적 상태를 유지합니다.
- 중간 슬래시 (docs/*.html): 경로 중간에 슬래시가 있으면 .gitignore 위치를 기준으로 한 상대 경로로 해석됩니다.
이중 별표(**)를 사용하면 깊이에 상관없이 여러 하위 디렉터리를 가로질러 일치시킬 수 있습니다:
- **/cache: 저장소의 어느 위치에 있든 cache 이름의 폴더나 파일에 매칭됩니다 (cache, src/cache, a/b/c/cache 등).
- logs/**: logs/ 디렉터리 내부의 모든 파일 및 하위 폴더에 깊이와 관계없이 재귀 매칭됩니다.
- a/**/b: a/b, a/x/b, a/x/y/b 등 중간에 위치하는 임의의 폴더 경로와 일치합니다.
느낌표(!)를 패턴 시작 부분에 붙이면 이전 규칙으로 무시되었던 파일을 다시 추적 목록에 포함(화이트리스트 지정)할 수 있습니다.
성능상의 이유로 Git은 디렉터리 자체가 무시되면 해당 폴더의 하위 항목을 전혀 탐색하지 않습니다. 상위 폴더를 build/로 제외했다면, 그 안의 !build/important.txt 규칙은 절대 적용되지 않습니다.
제외된 폴더 안의 특정 파일만 다시 추적하려면, 폴더 자체가 아니라 '폴더 내부의 모든 파일'을 제외한 후 예외를 선언해야 합니다:
# INCORRECT: Will NOT work because parent directory is skipped
node_modules/
!node_modules/my-local-package
# CORRECT: Ignore contents of directory, then whitelist the specific target
node_modules/*
!node_modules/my-local-package/어떤 규칙에 의해 파일이 제외되고 있는지 확인하려면 Git의 진단 명령어를 -v 옵션과 함께 실행합니다:
# Shows the exact .gitignore file and line number responsible
git check-ignore -v src/temp/debug.log자주 묻는 질문 (FAQ)
.gitignore 규칙, 캐싱, 저장소 설정에 대해 개발자들이 가장 자주 묻는 질문과 실전 해결책입니다.
.gitignore에서 *과 **의 차이는 무엇인가요?
단일 별표(*)는 하나의 폴더 계층 내 문자에 일치합니다. 이중 별표(**)는 임의의 깊이로 중첩된 여러 하위 디렉터리를 가로질러 일치합니다.
폴더를 제외한 뒤 !폴더/파일.txt를 지정해도 적용되지 않는 이유는 무엇인가요?
Git은 상위 폴더가 제외되면 내부 탐색을 건너뜁니다. '폴더/*' 형식으로 내용물을 제외한 뒤 예외를 선언해야 정상 작동합니다.
특정 파일이 어떤 규칙에 의해 무시되고 있는지 확인하는 방법은?
'git check-ignore -v <경로>' 명령어를 실행하면 매칭된 .gitignore 파일명과 해당 규칙의 줄 번호가 즉시 출력됩니다.