본문으로 건너뛰기
AZ Tools

.gitignore 테스터

.gitignore는 순서가 있는 패턴 목록이고, 한 경로에 대해 마지막으로 일치한 규칙이 이깁니다. 그래서 "이 파일이 왜 무시되지?"의 답은 지금 보고 있는 줄이 아닌 경우가 많습니다. 이 도구는 .gitignore와 경로 목록을 받아 `git check-ignore -v`와 같은 방식으로 답합니다. 경로마다 무시 여부, 결정한 줄 번호, 그 패턴의 원문을 보여주고, 파일 자신이 아니라 상위 디렉터리 때문에 결정된 경우에는 그 디렉터리까지 함께 표시합니다. 마지막 항목이 대부분의 .gitignore 버그가 사는 곳입니다. git은 제외된 디렉터리 안으로 아예 내려가지 않기 때문에 `build/`가 무시되는 순간 `!build/keep.txt`는 죽은 문장이 됩니다. 파일은 상위 디렉터리 규칙으로 판정되고 그 부정 규칙은 읽히지도 않습니다. 이 도구는 바로 그 상황을 따로 경고하며, 붙여넣은 경로 중 어느 것과도 일치하지 않은 규칙도 목록으로 보여줍니다. 오래전 이름을 바꾼 coverage/ 같은 줄이 이때 드러납니다. 매칭은 셸 글로브가 아니라 git의 규칙을 그대로 따릅니다. 슬래시가 없는 패턴은 모든 깊이에서 파일 이름과 비교하고, 슬래시가 들어간 패턴은 .gitignore가 있는 디렉터리에 고정되며, 끝의 슬래시는 디렉터리만 대상으로 삼습니다. `*`는 슬래시를 넘지 못하지만 경로 구간 전체를 차지한 `**`는 넘습니다. [0-9]나 [!a-z] 같은 문자 클래스, 백슬래시로 지킨 끝 공백, 이스케이프한 #과 !, UTF-8 BOM과 CRLF 줄바꿈도 git과 동일하게 처리합니다. 붙여넣은 경로에는 파일 종류 정보가 없으므로 디렉터리는 끝에 슬래시를 붙여 주세요. `build/`는 디렉터리로, `build`는 파일로 판정되며 이 차이 하나로 디렉터리 전용 규칙의 결과가 뒤집힙니다. 알 수 없는 것도 있습니다. 이 도구는 .gitignore 한 개만 읽으므로 하위 디렉터리의 .gitignore, .git/info/exclude, core.excludesFile로 지정한 전역 파일은 고려하지 않으며, 그 셋은 모두 여기 결과를 뒤집을 수 있습니다. 또 리눅스의 git처럼 대소문자를 구분하므로 core.ignorecase가 켜진 macOS나 윈도우 저장소에서는 더 많이 무시될 수 있습니다. 모든 처리는 브라우저 안에서 이루어지고 파일도 경로도 서버로 올라가지 않습니다.

무시됨

5

무시 안 됨

3

규칙

7

죽은 규칙

1

아무 일도 하지 않는 부정 규칙

git은 제외된 디렉터리 안으로 내려가지 않으므로 그 아래의 ! 규칙은 읽히지 않습니다. 디렉터리(dir/) 대신 내용물(dir/*)을 제외하면 의도대로 동작합니다.

  • .vscode/settings.json — !.vscode/settings.json (줄 10) · 제외된 상위 디렉터리 .vscode/
경로결과결정한 규칙
src/index.ts무시 안 됨일치한 규칙 없음
node_modules/react/index.js무시됨2node_modules/제외된 상위 디렉터리 node_modules/
dist/무시됨3dist/
dist/app.js무시됨3dist/제외된 상위 디렉터리 dist/
debug.log무시 안 됨6!debug.log
logs/debug.log무시 안 됨6!debug.log
server.log무시됨5*.log
.vscode/settings.json무시됨9.vscode/제외된 상위 디렉터리 .vscode/이 ! 규칙은 효력이 없습니다
아무것도 일치하지 않은 규칙

위 경로 중 어느 것도 이 줄들과 일치하지 않았습니다. 경로 목록이 대표성을 가진다면 삭제 후보입니다.

  • 줄 4 coverage/

대소문자를 구분하는 파일 시스템에서, 저장소 루트의 .gitignore 하나를 기준으로 판정합니다.

사용법

  1. 첫 번째 상자에 .gitignore를 디스크에 있는 그대로 붙여넣습니다. 주석, 빈 줄, CRLF 줄바꿈, BOM 모두 git과 같은 방식으로 처리됩니다.
  2. 두 번째 상자에 확인할 경로를 저장소 루트 기준으로 한 줄에 하나씩 적습니다. 디렉터리는 줄 끝에 슬래시를 붙이세요. `logs/` 같은 디렉터리 전용 규칙의 판정이 여기에 달려 있습니다.
  3. 표를 읽습니다. 각 행은 무시 여부, 결정한 줄 번호, 규칙 원문을 보여 줍니다. `git check-ignore -v`가 출력하는 세 가지에 제외된 상위 디렉터리가 더해진 형태입니다.
  4. 주황색 안내를 확인하세요. `!` 규칙이 경로와 일치하지만 상위 디렉터리가 이미 제외되어 효력이 없을 때 나타납니다. 부정 규칙이 맞아 보이는데 아무 일도 하지 않는 전형적인 이유입니다.
  5. 맨 아래 죽은 규칙 목록을 봅니다. 붙여넣은 경로 어느 것과도 일치하지 않은 줄이며, 경로 목록이 대표성을 가진다면 지워도 되는 후보입니다.

자주 묻는 질문

! 규칙을 썼는데 파일이 왜 돌아오지 않나요?
git이 그 파일을 아예 보지 않았기 때문입니다. 트리를 훑다가 어떤 디렉터리가 제외된 것을 확인하면 git은 거기서 멈추고 안으로 내려가지 않습니다. 그래서 그 디렉터리 안쪽에 관한 규칙은 평가조차 되지 않습니다. 공식 문서도 "상위 디렉터리가 제외된 파일은 다시 포함할 수 없다"고 못 박고 있습니다. `logs/`와 `!logs/important.log`를 같이 쓰면 로그는 계속 무시되고, 이 도구는 결정이 디렉터리 규칙에서 나왔음을 보여 줍니다. 해결책은 디렉터리 대신 내용물을 제외하는 것입니다. `logs/*` 다음에 `!logs/important.log`를 쓰면 됩니다. 하위 트리 전체라면 `/logs/**`, `!/logs/keep/`, `!/logs/keep/**` 순서가 정석입니다.
build와 /build는 무엇이 다른가요?
패턴 안에 슬래시가 하나도 없으면 모든 깊이에서 경로의 마지막 이름과 비교합니다. 그래서 `build`는 /build, /src/build, /a/b/c/build를 모두 무시합니다. 반대로 마지막 글자가 아닌 위치에 슬래시가 하나라도 있으면 그 패턴은 .gitignore가 놓인 디렉터리에 고정됩니다. `/build`와 `docs/output`은 그 디렉터리 기준으로만 일치합니다. 루트 .gitignore에 그냥 `node_modules`라고 적으면 중첩 패키지의 node_modules까지 숨겨지는 이유가 이것입니다. 대개는 원하는 동작이지만 의도해서 쓴 경우는 드뭅니다. "여기서만"이라고 말하려면 앞에 슬래시를 붙이면 됩니다.
logs/는 logs라는 파일도 무시하나요?
아닙니다. 끝의 슬래시는 디렉터리만 대상으로 한다는 뜻이라, logs라는 이름의 일반 파일은 그대로 남고 어느 깊이에 있든 logs 디렉터리는 그 안의 모든 것과 함께 무시됩니다. 붙여넣은 경로 목록에는 종류 정보가 없다는 점이 여기서 중요합니다. git은 실제 파일 시스템을 보고 판단하지만 이 도구는 알려 주어야 합니다. 디렉터리는 `logs/`, 파일은 `logs`로 적으세요. 같은 문자열이라도 슬래시 유무에 따라 정반대 결과가 나오며, 이는 도구의 특이한 점이 아니라 아직 존재하지 않는 경로에서 `git check-ignore`가 예상과 다르게 답하는 이유이기도 합니다.
**의 세 가지 형태는 각각 무슨 뜻인가요?
`**`는 경로 구간 전체를 차지할 때만 특별한 뜻을 가집니다. 맨 앞의 `**/foo`는 모든 깊이의 foo와 일치하며, 슬래시 없는 패턴이 이미 하는 일을 명시적으로 쓴 형태입니다. 끝의 `foo/**`는 foo 안의 모든 것과 일치하지만 foo 자신과는 일치하지 않습니다. 앞서 소개한 재포함 방법이 통하는 이유가 바로 이것입니다. 가운데의 `a/**/b`는 a/b, a/x/b, a/x/y/b를 모두 포함해 디렉터리 0개 이상과 일치합니다. 그 밖의 자리에서는 그냥 별입니다. `a**b`는 `a*b`와 같고, 별 하나는 슬래시를 넘지 않으므로 `src/*.c`는 src/main.c와는 일치해도 src/lib/main.c와는 일치하지 않습니다.
규칙은 맞는데 git이 계속 파일 변경을 보여 줍니다.
.gitignore는 git이 아직 추적하지 않는 파일에만 적용됩니다. 한 번 커밋된 파일은 나중에 패턴을 추가해도 달라지지 않아서 변경 사항이 계속 보고되고 계속 커밋됩니다. 먼저 `git rm --cached 경로`로 추적을 끊고(작업 디렉터리의 파일은 그대로 남습니다) 그 삭제를 커밋하세요. 다음 커밋부터 무시 규칙이 적용됩니다. 이 도구는 `check-ignore`와 마찬가지로 추적되지 않는 파일에 대한 질문에 답하므로, 인덱스에 들어 있는 경로라면 여기서 무시라고 나와도 `git status`에는 그대로 보일 수 있습니다. 둘이 어긋날 때 가장 먼저 확인할 점입니다.
.gitignore가 여러 개면 어느 것이 이기나요?
git은 정해진 순서로 여러 출처를 읽고 더 구체적인 쪽이 이깁니다. 명령줄 패턴이 가장 앞이고, 그다음이 .gitignore 파일들인데 더 깊은 디렉터리의 파일이 위쪽 파일을 덮어씁니다. 그다음이 공유되지 않는 저장소 전용 규칙인 .git/info/exclude이고, 마지막이 core.excludesFile로 지정한 전역 파일입니다. 한 파일 안에서는 마지막으로 일치한 줄이 결정합니다. 이 도구는 .gitignore 하나만 모델링하므로 결과가 실제 저장소와 다르다면 하위 .gitignore, info/exclude 항목, 전역 파일이 원인일 가능성이 큽니다. 그곳에서 `git check-ignore -v`를 실행하면 출처 열이 파일 이름을 알려 줍니다.

관련 도구