Huny's Dev Blog
huny.dev

Git .gitignore가 적용되지 않을 때: 추적 파일을 남기고 git rm --cached로 해제하기

gitignore에 넣어도 변경이 남는 원인을 인덱스와 추적 상태로 설명한다. 임시 Git 저장소의 8개 검증으로 로컬 파일 보존, 규칙 진단과 과거 이력의 경계를 확인한다.

Hun Jang
Hun Jang Nov 3, 2026

.gitignore에 파일을 넣었는데도 Git 변경 목록에 계속 나타난다면, 먼저 그 파일이 이미 추적 중인지 확인한다. 무시 규칙은 기존 추적을 자동으로 해제하지 않는다. 로컬 파일을 남기고 앞으로의 추적을 중단하려면 해당 경로만 git rm --cached로 인덱스에서 제거하고, 무시 규칙과 함께 검토·커밋한다. 이 작업은 이전 커밋의 내용까지 지우지는 않는다.

로컬 문서는 남겨 두고 추적 연결만 끊으며 보관함에는 이전 사본이 남는 모습을 표현한 개념 일러스트. 실제 Git 내부 구조도는 아니다.

작성·문서 확인: 2026-11-03. 실행 검증: Git 2.51.1, Python 3.12.14, Linux의 임시 저장소. 예제 값은 모두 가짜 설정이며 사용자 저장소·원격 서버·실제 비밀정보에는 접근하지 않았다.

패턴 문제인지, 추적 상태 문제인지 먼저 구분한다

Git 공식 gitignore 문서는 이미 추적 중인 파일이 무시 규칙의 영향을 받지 않는다고 설명한다. .gitignore가 고장 난 것이 아니라, 규칙과 현재 인덱스 상태가 서로 다른 역할을 하는 상황이다.

작업 트리는 로컬 파일이고, 인덱스는 다음 커밋에 넣을 내용을 준비하는 영역이다. 커밋은 별도의 과거 스냅샷이다. 예제에서는 세 영역을 나눠 확인한다.

진단 명령
확인할 것
해석
git ls-files -- .env
현재 인덱스에 경로가 있는가
출력되면 추적 상태부터 살핀다
git check-ignore -v -- .env
일반 무시 검사
추적 파일은 기본적으로 출력에서 제외된다
git check-ignore -v --no-index -- .env
인덱스를 무시하고 적용 규칙 검사
어느 파일·행·패턴이 매칭되는지 확인한다

--no-index는 추적을 해제하는 옵션이 아니라 진단 옵션이다. -v 결과에 !로 시작하는 부정 패턴이 있다면, 단순히 출력됐다는 이유만으로 “무시된다”고 판단하지 않는다. check-ignore 공식 문서

재현 코드: 파일은 남고, 다음 커밋에서는 빠진다

아래를 gitignore_demo.py로 저장하고 python gitignore_demo.py로 실행한다. Python 표준 라이브러리와 Git이 필요하다. 스크립트는 임시 저장소에서 두 번 커밋하고 종료 시 해당 임시 디렉터리를 정리한다. 전역 Git 설정을 수정하거나 원격 저장소로 전송하지 않는다.

예제의 루트 .gitignore에 쓰는 /.env는 루트의 해당 파일을 대상으로 한다. 다른 디렉터리의 동명 파일까지 같은 결과라고 일반화하지 않는다.

실제 출력과 검증 범위

여덟 검사는 추적 여부, 규칙 추가 후 변경 표시, 일반 검사 종료 코드, 인덱스를 제외한 규칙 매칭, 추적 해제 후 로컬 내용 보존, 삭제로 준비된 변경, 커밋 후 무시 상태, 이전 커밋 내용 보존이다. !! .env는 무시된 로컬 파일을 확인한 결과이며, 이 출력만으로 과거 기록이 사라졌다는 뜻은 아니다.

이 환경에서 일반 check-ignore가 추적 파일에 대해 종료 코드 1을 반환하는 것도 확인했다. 따라서 셸 스크립트가 “출력 없음”만 보고 패턴을 계속 바꾸면 원인을 놓칠 수 있다.

기존 저장소에 적용할 때는 경로 하나부터 검토한다

먼저 변경 상태와 필요한 로컬 파일의 보관 여부를 확인한다. 루트 .env가 의도한 대상이고 .gitignore에 /.env를 추가했다면, 다음 순서로 해당 경로의 변경만 준비·검토한다. 아래 명령은 기존 사용자 저장소에서 실행하지 않았다.

git rm 공식 문서에 따르면 --cached는 작업 트리 파일을 남기고 인덱스에서 제거한다. 커밋 전 D .env가 준비된 것은 다음 스냅샷에서 그 경로를 뺀다는 뜻이다. 확인 후 의도한 변경만 커밋한다. 이미 다른 내용이 스테이징돼 있다면 그 내용도 다음 커밋에 포함될 수 있으므로 전체 준비 목록을 검토해야 한다.

명령이 스테이징 상태 때문에 거부되면 곧바로 강제 옵션을 붙이지 말고 인덱스·현재 파일·이전 커밋의 차이를 확인한다. 저장소 전체의 인덱스를 지웠다가 다시 추가하는 작업은 이 문제의 필수 해결 단계가 아니다.

로컬 보존과 이력 보존의 경계

  • git rm --cached가 파일을 남긴다는 설명은 명령을 실행한 현재 작업 트리에 대한 것이다. 다른 사람이 삭제 커밋을 반영할 때 로컬 설정까지 자동 보존되는 계약은 아니다. 팀에는 변경 의도와 설정 생성·복구 방법을 함께 전달한다.
  • 신규 체크아웃에는 추적 해제한 설정 파일이 없으므로, 필요한 값의 이름과 기본값을 담은 비밀정보 없는 예제 파일이나 설정 절차를 별도로 관리한다.
  • 예제는 이전 커밋에서 원본 설정을 다시 읽었다. 실제 비밀정보가 노출됐다면 무시 규칙 추가만으로 끝내지 않는다. GitHub 공식 안내는 우선 자격증명 폐기·교체를 안내하며, 이력 재작성은 협업자와 부작용을 고려한 별도 절차다.
  • 강제 추가, 다른 무시 파일, 부정 패턴이 결과에 영향을 줄 수 있다. 규칙 출처와 현재 인덱스를 함께 확인한다.

이 글은 로컬 단일 저장소 동작을 검증했다. 협업자의 pull·merge, 원격 이력 정리, 자격증명 교체, 서브모듈·sparse checkout은 실행 시험하지 않았다.

English version: Git .gitignore Not Working? Stop Tracking a File with git rm --cachedGit .gitignore Not Working? Stop Tracking a File with git rm --cached

추천 글