프로젝트를 처음 깃에 올릴 때 git add .를 딱 쳤더니, node_modules 폴더 수천 개 파일이 우르르 올라가려는 걸 보고 식겁한 경험 다들 있죠. 비밀번호가 담긴 .env 파일이 그대로 커밋돼서 팀 채팅방에 비상이 걸리기도 하고요. 이런 사고를 막아주는 게 .gitignore(무시 목록) 파일이에요. "이 파일들은 깃이 아예 쳐다보지도 마" 하고 명단을 적어두는 거죠.

81.1 커밋하면 안 되는 파일이 따로 있나요?

있어요. 크게 세 종류예요. 첫째, 다시 만들 수 있는 것이에요. node_modules(설치하면 다시 생기는 라이브러리 폴더)나 build(빌드하면 나오는 결과물)는 명령어 한 번이면 되살아나니 저장소에 담을 이유가 없어요. 둘째, 비밀이에요. .env에 든 API 키나 DB 비밀번호가 깃 역사에 남으면 지우기도 까다롭고 위험하죠. 셋째, 내 컴퓨터에만 필요한 것이에요. 에디터 설정 폴더나 운영체제가 만드는 .DS_Store 같은 파일은 팀원한테 아무 쓸모가 없어요.


이런 것들이 저장소에 섞이면 용량만 불고, 코드 리뷰할 때 진짜 봐야 할 변경이 파묻혀요. 남이 올린 PR을 열었는데 바뀐 파일이 2천 개면 아무도 제대로 못 봐요. 그래서 프로젝트 시작하자마자 .gitignore부터 만드는 게 실무의 첫 단추예요.


다행히 하나하나 손으로 다 적을 필요는 없어요. 언어나 프레임워크마다 무시할 것들이 거의 정해져 있어서, 잘 만들어진 표준 .gitignore 모음을 가져다 시작한 뒤 우리 프로젝트에 맞게 몇 줄 더하는 식으로 써요. 노드 프로젝트면 node_modules.env가, 파이썬이면 __pycache__가 기본으로 들어가는 식이죠.

81.2 .gitignore는 어떻게 쓰나요?

프로젝트 최상위 폴더에 .gitignore라는 이름의 파일을 만들고, 무시할 패턴을 한 줄에 하나씩 적으면 끝이에요. 이렇게요.


node_modules/
*.log
*.env
!config.env


이 상태에서 git add -A 하고 상태를 보면, 무시 대상은 목록에서 아예 빠져요.


$ git status --short
A .gitignore
A app.js
A config.env
A src/index.js


node_modules 폴더도, error.log 같은 로그도, secret.env도 목록에 안 보이죠. 깃이 알아서 걸러준 거예요. 여기서 재밌는 건 config.env는 남아있다는 점인데, 이건 바로 다음에서 설명할게요.

81.3 패턴은 어떤 규칙으로 쓰나요?

핵심 기호 네 개만 알면 거의 다 돼요. 하나씩 볼게요.


첫째, *는 아무 글자나 대신해요. *.log는 "로그 확장자를 가진 모든 파일"이에요. 그리고 슬래시가 없는 이 패턴은 폴더 깊이와 상관없이 어디서든 걸려요. 실제로 확인해보면 이래요.


$ git check-ignore -v docs/readme.log src/logs/a.log
.gitignore:2:*.log docs/readme.log
.gitignore:2:*.log src/logs/a.log


깊숙한 폴더 안에 있어도 *.log 하나가 다 잡아내죠.


둘째, 맨 앞의 /는 "최상위 폴더 딱 여기"로 위치를 못 박아요. /build/라고 쓰면 루트의 build 폴더만 무시하고, 어쩌다 하위에 생긴 다른 build는 안 건드려요.


$ git check-ignore -v build/out.js
.gitignore:4:/build/ build/out.js


셋째, 맨 뒤의 /는 "이건 폴더예요"라는 뜻이에요. logs/는 logs 폴더 전체를 무시해요. 넷째, !는 예외를 만드는 되돌리기 기호예요. *.env로 전부 무시하되 !config.env로 이 하나만 살려두는 식이죠. 그래서 아까 config.env가 살아남았던 거예요. 다만 이미 무시된 폴더 안의 파일은 !로도 못 살리니, 이건 예외 규칙으로 기억해두세요.

81.4 이미 커밋한 파일은 왜 무시가 안 되죠?

이거 진짜 많이 걸려요. config.env를 이미 커밋해둔 뒤에 뒤늦게 .gitignore*.env를 추가했다고 해볼게요. 근데 상태를 보면 여전히 추적되고 있어요.


$ git status --short
A .gitignore


왜냐하면 .gitignore는 "아직 추적 안 하는 파일"에만 적용되거든요. 한 번 커밋해서 깃이 추적 중인 파일은 명단에 이름을 올려도 계속 따라와요. 이럴 땐 추적만 끊어줘야 해요.


$ git rm --cached config.env
rm 'config.env'


--cached는 "저장소에서만 빼고 내 컴퓨터의 실제 파일은 그대로 두라"는 옵션이에요. 이걸 커밋하면 그때부터 config.env는 무시되기 시작해요. 파일 자체는 안 지워지니 안심하고 쓰세요. 만약 --cached를 빼고 그냥 git rm을 하면 실제 파일까지 삭제되니까, 이 옵션은 꼭 챙겨야 해요.


한 가지 더 알아두면 좋은 게 있어요. 이미 커밋된 .env에 비밀번호가 들어있었다면, 지금 추적을 끊어도 과거 커밋 기록에는 그 비밀번호가 남아있어요. 그래서 진짜 민감한 값이 새어 나갔다면, 추적을 끊는 걸로 끝내지 말고 그 비밀번호 자체를 즉시 새 값으로 바꾸는 게 정답이에요. 깃 역사에서 완전히 지우는 건 훨씬 번거롭거든요.

81.5 무시되는지 미리 확인할 수 있나요?

패턴을 적어놓고도 "이게 진짜 먹히나?" 싶을 때가 있죠. 그럴 땐 git check-ignore -v에 파일 이름을 주면, 몇 번째 줄 어떤 규칙 때문에 무시되는지 딱 짚어줘요. 위에서 본 것처럼요. 무시 안 되는 파일을 물으면 아무것도 안 나오고요. 반대로 지금 무시되고 있는 것 전체가 궁금하면 git status --ignored를 써요.


$ git status --ignored --short
!! node_modules/
!! secret.env


앞의 !! 표시가 "무시 중"이라는 뜻이에요. 커밋 전에 이걸 한 번 훑으면 "어? 이게 왜 무시되지?" 하는 사고를 미리 잡을 수 있어요.


참고로 내 에디터 설정이나 .DS_Store처럼 나 개인한테만 필요한 무시 목록은, 프로젝트 .gitignore에 넣지 말고 내 컴퓨터 전체에 적용되는 전역 무시 파일에 따로 두는 게 매너예요. 팀 공용 .gitignore에 내 에디터 설정을 적어두면 다른 팀원한테는 뜬금없는 줄이 되거든요. 공용 파일에는 프로젝트라면 누구나 무시해야 할 것만, 개인 취향은 전역으로. 이 구분만 지켜도 협업이 한결 깔끔해져요.

81.6 오늘 정리

정리할게요. 프로젝트 시작하면 최상위에 .gitignore부터 만들고, 다시 만들 수 있는 것, 비밀, 내 PC 전용 파일을 걸러요. 패턴은 *(아무 글자), 맨 앞 /(루트 고정), 맨 뒤 /(폴더), !(예외) 네 가지가 뼈대예요. 이미 커밋한 파일은 git rm --cached로 추적을 끊어야 하고, 헷갈리면 git check-ignore -v로 확인하면 돼요. .gitignore 잘 짜두는 것만으로 비밀 유출과 저장소 비대화라는 두 사고를 동시에 막을 수 있어요. 커밋 버튼 누르기 전에 "지금 올라가는 목록에 이상한 게 없나" 딱 한 번 확인하는 습관, 이게 사고를 절반으로 줄여줘요.