
SOFTMOA TECHNOLOGY
Git .gitignore 적용 안 될 때 추적 파일 확인 방법
소프트모아가 정리한 기술 기록입니다.
Contents
.gitignore에 파일을 추가했는데도 변경 목록에 계속 나온다면, 패턴을 고치기 전에 이미 추적 중인 파일인지 확인해야 합니다. .gitignore는 추적되지 않은 파일을 제외하는 규칙이라 기존 추적 파일에는 적용되지 않습니다.[1] 추적 여부와 규칙 일치 여부를 따로 조회한 뒤, 추적을 멈출 파일만 지정해 처리하면 저장소 전체를 다시 등록할 필요가 없습니다.
아래는 루트의 config.local.json을 관리 대상에서 빼려는 예시입니다. macOS의 Git 2.54.0(Apple Git-157)에서 원격 연결 없는 임시 저장소와 가상 설정 파일로 확인했습니다. 실제 프로젝트나 운영 설정은 바꾸지 않았습니다. 소프트모아의 개발 문서입니다.
같은 파일로 두 가지를 확인합니다
프로젝트 루트에서 다음 명령을 실행합니다. 첫 조회는 인덱스에 파일이 있는지, 나머지는 무시 규칙이 어떻게 적용되는지 확인합니다. 인덱스는 다음 커밋에 넣을 내용을 관리하는 영역입니다. git ls-files는 기본적으로 인덱스의 파일을 보여 줍니다.[3]
git --version
git ls-files -- config.local.json
git check-ignore -v -- config.local.json
git check-ignore -v --no-index -- config.local.json
루트 .gitignore의 첫 줄이 /config.local.json일 때, 테스트 저장소에서는 ls-files가 config.local.json을 출력했습니다. 일반 check-ignore는 아무것도 출력하지 않고 종료 코드 1을 반환했지만, --no-index를 붙인 조회는 아래 결과와 종료 코드 0을 반환했습니다.
.gitignore:1:/config.local.json config.local.json
이 결과는 규칙이 없어서 생긴 문제가 아닙니다. 파일은 이미 추적 중이고, 인덱스를 보지 않고 평가하면 무시 규칙에 맞습니다. 일반 check-ignore는 추적 파일을 기본적으로 표시하지 않습니다.[2] 빈 출력 하나만 보고 .gitignore가 잘못됐다고 판단하면 같은 규칙을 반복해서 추가하게 됩니다.
- ls-files가 경로를 출력하면 먼저 추적을 계속할 파일인지 결정합니다.
- 추적되지 않은 파일이라면 check-ignore -v로 규칙의 출처와 줄 번호를 확인합니다.[2]
- --no-index는 진단할 때만 씁니다. 이 옵션은 파일의 추적 상태를 변경하지 않습니다.[2]
규칙의 기준 위치도 확인해야 합니다
이번 예시의 .gitignore 내용은 두 줄입니다. 저장소 루트에 있는 파일이라는 조건을 함께 확인하세요.
/config.local.json
/build/
앞의 /는 이 .gitignore가 놓인 디렉터리를 기준으로 경로를 고정합니다. 루트에서 /config.local.json은 루트 파일을 대상으로 하며, 하위 디렉터리의 같은 이름까지 뜻하지 않습니다. /build/의 마지막 /는 디렉터리를 대상으로 한다는 뜻입니다.[1] 테스트에서는 추적되지 않은 build/result.txt를 조회했을 때 .gitignore:2:/build/와 경로가 표시됐습니다.
아직 추적되지 않았고 규칙에도 없는 notes.txt도 확인했습니다. ls-files와 check-ignore 모두 빈 출력이었지만, 앞의 config.local.json과 원인은 달랐습니다. 한쪽은 추적 여부, 다른 쪽은 규칙을 확인하는 명령이므로 결과를 묶어서 읽어야 합니다. 파일이 다른 디렉터리에 있거나 다른 .gitignore가 적용된다면 -v에 나온 출처부터 다시 확인합니다.
전체가 아니라 확인한 파일만 추적에서 뺍니다
config.local.json을 팀이 공유할 필요가 없다는 판단을 마쳤다면 먼저 로컬 변경을 확인하고 필요한 사본을 저장하세요. 아래 예시는 해당 파일에 별도 수정이나 스테이징된 변경이 없는 상태를 전제로 합니다. --cached는 인덱스에서만 제거하고 작업 디렉터리의 파일은 남깁니다. -n은 실제 제거 없이 대상을 보여 주는 옵션입니다.[4]
git rm -n --cached -- config.local.json
# 대상이 맞을 때만 다음 명령 실행
git rm --cached -- config.local.json
git add -- .gitignore
git diff --cached --name-status
git status --short --ignored -- config.local.json
임시 저장소에서는 제거 전후 파일 내용이 같았고, ls-files에서는 해당 경로가 사라졌습니다. status의 출력은 다음과 같았습니다.
D config.local.json
!! config.local.json
첫 줄의 D는 다음 커밋에 반영할 삭제가 인덱스에 준비됐다는 뜻이고, !!는 작업 디렉터리에 남은 파일이 무시된다는 표시입니다.[5] 실제 파일이 지워졌다는 뜻으로 두 줄을 합쳐 읽으면 안 됩니다. 테스트에서는 .gitignore 추가와 해당 경로 삭제만 확인한 뒤 임시 커밋을 만들었고, 그다음 조회에는 !! 한 줄만 남았습니다.
실제 저장소에서도 커밋 전에 변경 목록을 검토하세요. 다른 파일이 함께 들어 있으면 먼저 분리해야 합니다. rm이 로컬 변경 때문에 거부된다면 강제로 진행하지 말고 작업 파일과 인덱스의 차이를 확인합니다.[4] 저장소 전체를 대상으로 제거·재등록하는 방식은 이 한 파일의 문제를 해결하는 데 필요하지 않습니다.
추적 중단과 과거 기록 삭제는 다릅니다
이 절차는 앞으로 공유할 파일 목록을 정리하는 예시입니다. 이전 커밋의 내용을 지우는 절차는 아닙니다. 추적 중단이 로컬에서 파일을 남겼다고 해서 다른 작업자의 갱신 과정까지 파일 보존을 보장하지는 않으므로, 공유 설정을 개인 설정으로 전환할 때는 백업과 생성 방법을 먼저 안내하세요.
설정 파일에 실제 인증 정보가 들어 있었다면 무시 규칙 추가만으로 처리를 끝내지 말고 해당 인증 정보의 폐기·재발급과 이미 공유된 기록의 점검을 별도로 진행해야 합니다. 이번 테스트는 규칙 진단, 인덱스 제거, 로컬 파일 유지까지만 확인했으며 원격 저장소나 비밀정보 정리 결과를 검증한 것은 아닙니다.
확인한 공식 문서
- [1] gitignore: 추적 파일과 패턴 기준
- [2] git-check-ignore: --no-index와 진단 출력
- [3] git-ls-files: 인덱스 파일 조회
- [4] git-rm: --cached와 --dry-run
- [5] git-status: D와 !! 표시
소프트모아는 해당 시스템을 구축합니다. 문의하기
