본문 바로가기

복사금지 블로그 짜증나서 만든 개발문서

gitignore에 추가했는데 파일이 계속 올라온다면 확인할 것

반응형

환경  Git 2.55 기준 · 2026-07-31 공식 문서 확인

무시 규칙을 아무리 고쳐도 같은 파일이 계속 커밋에 딸려 온다면, 규칙이 아니라 그 파일이 이미 추적 중이라는 뜻입니다. 작업 파일은 건드리지 않고 추적만 끊는 순서를 정리했습니다.

무시 규칙은 추적되지 않는 파일에만 적용된다

Git 공식 gitignore 문서는 첫 문단에서 범위를 못박습니다. gitignore 파일은 의도적으로 추적하지 않을 파일을 지정하는 것이고, 이미 Git 이 추적 중인 파일은 영향을 받지 않는다고 명시합니다.

즉 한 번이라도 커밋되어 인덱스에 올라간 파일은 그 시점부터 추적 대상이 됩니다. 이후에 .gitignore 에 같은 경로를 적어도 Git 은 이미 알고 있는 파일이라 계속 변경을 따라갑니다.

그래서 이 상황은 규칙을 고쳐서 풀 문제가 아니라, 인덱스에서 그 파일을 내려야 풀리는 문제입니다.

# 이 파일이 정말 추적 중인지부터 확인한다
git ls-files --error-unmatch config/local.json

# 무시 규칙이 어느 줄에 걸리는지도 같이 본다
git check-ignore -v config/local.json

ls-files 에서 경로가 출력되면 추적 중이라는 뜻입니다. check-ignore 는 규칙 자체는 맞게 걸려 있음을 확인해 줍니다.

규칙이 맞는데도 계속 올라온다면, 규칙이 아니라 인덱스를 봐야 합니다.

작업 파일은 남기고 인덱스에서만 내리기

공식 문서 NOTES 는 해결 절차를 한 줄로 안내합니다. 현재 추적 중인 파일의 추적을 멈추려면 git rm --cached 로 인덱스에서 제거하고, 그 뒤에 파일명을 .gitignore 에 추가해 이후 커밋에 다시 들어오지 않게 하라는 것입니다.

여기서 --cached 가 핵심입니다. 이 옵션이 없으면 git rm 은 작업 디렉터리의 실제 파일까지 지웁니다. 설정 파일이나 로컬 자격 증명이라면 복구가 번거로워집니다.

폴더 단위로 내릴 때는 -r 을 함께 씁니다. 삭제 대상이 많을 때는 먼저 -n 으로 무엇이 빠지는지 확인하고 실행하는 편이 안전합니다.

# 무엇이 인덱스에서 빠지는지 먼저 확인 (실제로 지우지 않음)
git rm --cached -n config/local.json

# 확인했으면 인덱스에서만 제거 — 작업 파일은 그대로 남는다
git rm --cached config/local.json

# 폴더 전체라면
git rm --cached -r .idea/

-n(--dry-run)으로 목록을 먼저 보고 실행하면 실수로 넓은 범위를 내리는 일을 막을 수 있습니다.

--cached 를 빼먹으면 작업 파일까지 사라집니다. 이 옵션 하나가 안전장치입니다.

커밋해야 추적 해제가 확정된다

git rm --cached 는 인덱스만 바꿉니다. 이 상태에서 git status 를 보면 해당 파일이 deleted 로 스테이징되어 있고, 동시에 untracked 목록에도 나타납니다. 얼핏 파일이 지워진 것처럼 보이지만 작업 디렉터리에는 그대로 있습니다.

이 변경을 커밋해야 다음부터 Git 이 그 파일을 신경 쓰지 않습니다. 커밋하지 않은 채 브랜치를 옮기거나 다른 작업을 이어가면 인덱스 상태가 흔들려 원래대로 돌아온 것처럼 보일 수 있습니다.

커밋 메시지에는 파일을 삭제한 게 아니라 추적만 끊었다는 점을 남겨 두는 편이 좋습니다. 나중에 히스토리를 볼 사람이 실제 삭제로 오해하지 않습니다.

git status --short
# D  config/local.json      ← 인덱스에서 제거됨(스테이징)
# ?? config/local.json      ← 작업 디렉터리에는 그대로

git commit -m "chore: config/local.json 추적 해제 (파일은 로컬에 유지)"

D 와 ?? 가 같이 보이는 것이 정상입니다. 파일이 사라진 게 아닙니다.

이미 올라간 내용은 히스토리에 남아 있다

여기까지 하면 앞으로의 커밋에서는 파일이 빠집니다. 다만 과거 커밋에 담긴 내용은 그대로 남아 있습니다. 원격에 올라간 뒤라면 그 시점의 값은 이미 노출된 것으로 봐야 합니다.

설정 파일 정도라면 추적 해제로 충분하지만, API 키나 토큰이 들어 있었다면 순서가 다릅니다. 히스토리를 정리하기 전에 해당 자격 증명을 먼저 폐기하고 새로 발급하는 것이 우선입니다. 히스토리 재작성은 시간이 걸리고 그 사이에도 값은 유효하기 때문입니다.

히스토리에서 완전히 지워야 한다면 git filter-repo 같은 도구가 필요하고, 이미 공유된 브랜치라면 협업자 전원이 다시 클론해야 합니다. 범위가 커지므로 별도 작업으로 다루는 편이 낫습니다.

키가 들어 있었다면 히스토리 정리보다 키 재발급이 먼저입니다.

조치 후 확인할 것

  • git ls-files --error-unmatch <경로> 가 아무것도 출력하지 않으면 추적이 끊긴 것입니다.
  • 작업 디렉터리에 파일이 그대로 있는지 확인하세요. --cached 를 빠뜨렸다면 여기서 드러납니다.
  • 새 커밋을 하나 만들어 보고 해당 파일이 포함되지 않는지 봅니다.
  • 민감한 값이 들어 있었다면 히스토리 정리와 별개로 자격 증명을 재발급했는지 확인합니다.

확인한 문서

정리하면 순서는 하나입니다. 추적 중인지 확인하고, --cached 로 인덱스에서만 내리고, 커밋으로 확정합니다. .gitignore 는 그 뒤부터 제 역할을 합니다.

반응형