메인 콘텐츠로 건너뛰기
코드를 고치다가 debug.log와 개인 메모인 local-notes.txt를 만들었어요. 둘 다 커밋에 담고 싶지 않아 .gitignore에 적었는데, 로그는 사라지고 메모는 여전히 변경 목록에 보여요. 같은 규칙을 넣었는데 왜 다를까요? 앞편에서는 이미 남긴 기록을 읽었어요. 이번에는 어떤 파일을 다음 기록에 포함할지 살펴봐요. 핵심은 제외 규칙보다 먼저 이미 추적하는 파일인지 확인하는 거예요.

.gitignore는 이미 추적하는 파일을 제외하지 않아요

새로 만든 파일과 이미 git add한 파일에 같은 제외 규칙을 적용해볼 거예요. 먼저 구분할 것은 추적 여부예요. 파일이 디스크에 있는지, 인덱스에 있는지, 과거 커밋에 있는지는 별개예요. 제외된 파일(ignored)은 커밋 다음에 도달하는 단계가 아니에요. 인덱스 설명과 연결해서 보면, 제외 규칙이 이미 인덱스에 있는 파일을 제거하지 않는다는 점이 핵심이에요. 추적과 미추적의 구분은 Pro Git의 변경 기록 설명, 제외 규칙의 적용 범위는 gitignore 공식 문서를 기준으로 해요.

시작 상태를 맞춰요

명령은 Bash 기준이며 저장소 루트에서 실행해요. 코드를 실행하지 않으므로 Node.js는 필요하지 않아요. 앞편을 마친 연습 저장소를 이어 써요. 다른 작업이나 제외 설정이 섞였다면 기존 파일을 지우지 말고 별도 연습 저장소를 준비해요. 실습은 별도 hook이나 커밋 서명 설정이 없고, 전역 제외 규칙이 예제 파일명에 영향을 주지 않는 환경을 기준으로 해요.
Git 설치는 첫 커밋 실습을 참고해요. git init -b main에는 Git 2.28 이상이 필요해요.기존 Git 저장소 밖에서 실행해요. 같은 이름의 폴더가 있어 mkdir가 실패하면 멈추고 새 이름을 골라요.
아래 >는 파일을 덮어써요. 방금 만든 빈 연습 폴더에서만 실행해요. 작성자 설정은 이 저장소에만 적용하고, 원격은 연결하지 않아요.
같은 터미널에서 시작 상태를 확인해요.
main과 working tree clean, 세 커밋이 보여야 해요. 파일은 차례로 console.log("hello world");, # Git practice이고 원격 출력은 없어야 해요. 출력이 별도 보기 화면으로 열리면 q로 나올 수 있어요.

같은 규칙인데 결과가 다른 이유를 관찰해요

1

메모만 먼저 기록하기

개인 메모를 실수로 기록한 상황을 만들어요. 실제 개인정보나 비밀값 대신 연습 문장을 써요. 아래 명령은 새 연습 파일 두 개를 만들어요. 같은 이름의 파일이 있다면 덮어쓰지 말고 시작 상태부터 확인해요.
첫 status에는 두 파일 모두 ??로 보여요. add 뒤에는 메모만 A 로 바뀌고 로그는 ??로 남아요. A는 추가가 스테이징됐다는 뜻이에요.커밋 뒤 ls-files에는 local-notes.txt만 나와요. 이 명령은 기본적으로 인덱스의 파일을 나열해요. 폴더의 모든 파일이나 과거 전체 이력을 나열하는 명령은 아니에요. git ls-files 공식 문서를 참고해요.
2

두 파일에 제외 규칙 적용하기

아래 명령은 새 .gitignore를 만들어요. 실제 프로젝트의 기존 .gitignore에 그대로 실행하면 규칙을 덮어쓰므로, 이번 연습 저장소에서만 실행해요.
일반 status에는 ?? .gitignore만 남아요. 로그는 제외됐고, 추적 중인 메모는 커밋 이후 바뀌지 않아 표시되지 않아요. 메모가 제외됐다고 판단하기에는 아직 일러요.--ignored를 붙이면 !! debug.log도 보여요. !!는 제외된 미추적 파일을 뜻해요. check-ignore -v에서는 .gitignore의 1번 줄 *.log가 이 파일과 일치한다는 정보를 읽을 수 있어요. 표시 방식은 git status 공식 문서를 참고해요.
3

추적 중인 메모를 다시 고치기

>>로 연습 메모에 한 줄을 덧붙여요. 실행 전에 메모가 변경 목록에 나올지 예상해보세요.
status에는 M local-notes.txt와 ?? .gitignore가 나와요. diff에는 +Practice note: inspect diff가 보여요. ls-files에도 메모가 남아 있어요. 규칙에 이름이 있어도 이미 추적 중인 파일의 변경은 계속 비교해요.일반 check-ignore는 추적 중인 파일을 보고하지 않아요. 여기서는 --no-index로 추적 여부를 검사에서 제외하고, 어떤 규칙과 일치하는지만 물었어요. 결과는 .gitignore의 2번 줄 /local-notes.txt예요. 이 출력이 추적 해제를 뜻하지는 않아요. git check-ignore 공식 문서에 두 동작의 차이가 설명되어 있어요.

파일은 남겨두고 다음 기록에서 빼봐요

현재 메모는 작업 트리에 두 줄, 인덱스와 마지막 커밋에는 한 줄이 있어요. 이번에는 이 연습 파일 하나만 인덱스에서 제거해요. 제외 규칙도 함께 커밋하면 이후에는 보통의 추가 대상에서 빠져요.
git rm --cached는 현재 작업 파일을 보존하지만, 다음 커밋에는 해당 경로의 삭제를 기록해요. --cached를 생략한 git rm은 작업 파일도 삭제 대상으로 삼아요. 과거 커밋의 내용은 어느 쪽도 지우지 않아요.파일 보존은 이 명령을 실행한 현재 작업 트리에 대한 설명이에요. 삭제 커밋을 공유하면 동료의 추적 중인 파일도 업데이트 과정에서 삭제될 수 있어요. 실제 팀 설정 파일이라면 백업과 대체 파일 준비를 먼저 조율해요. 이번 실습에는 원격이 없어요.
cat에는 메모 두 줄이 그대로 나와요. status의 D는 인덱스에 삭제가 스테이징됐다는 뜻이에요. 디스크의 파일까지 사라졌다는 뜻은 아니에요. 함께 보이는 ?? .gitignore는 아직 추가하지 않은 제외 규칙이에요. 스테이징된 삭제 패치에는 마지막 커밋에 있던 Practice note: inspect greeting 한 줄이 나와요. 새로 덧붙인 줄은 한 번도 스테이징하지 않았으므로 삭제 패치에도 없어요. ls-files 출력은 비고, 이제 일반 check-ignore로도 메모의 제외 규칙을 찾을 수 있어요. 이 예제에서는 인덱스의 메모가 HEAD와 같아서 rm --cached가 실행돼요. 인덱스 내용이 HEAD와 작업 파일 양쪽 모두와 다르면 거절될 수 있어요. 그때는 -f를 붙이기 전에 두 diff를 확인하고 필요한 내용을 별도로 보존해요. 실행 조건은 git rm 공식 문서를 참고해요. 이제 제외 규칙을 스테이징하고 규칙 추가와 메모 삭제만 들어가는지 확인한 뒤 커밋해요.
이번에 git add한 경로는 .gitignore뿐이에요. 메모 삭제는 앞의 rm --cached에서 이미 스테이징했어요.

제외 규칙은 어디까지 적용될까요?

아래 표는 저장소 루트에 둔 .gitignore를 기준으로 해요. 앞의 두 규칙을 실습에 사용했고, 뒤의 두 규칙은 문법을 비교하는 예예요. 프로젝트 전체에서 공유할 규칙은 .gitignore에 넣고 커밋해요. 이 저장소에서 나만 쓸 규칙은 일반적인 단일 작업 트리 저장소의 .git/info/exclude, 여러 저장소에 적용할 개인 규칙은 core.excludesFile 설정으로 관리할 수 있어요. 규칙이 예상과 다르면 check-ignore -v로 실제 출처부터 확인해요. 자세한 패턴과 우선순위는 gitignore 공식 문서를 참고해요. 제외는 접근 통제나 비밀값 보호 기능이 아니에요. 명시적인 git add -f로 제외된 파일도 추가할 수 있어요. 이미 비밀값을 커밋했다면 .gitignore 추가나 추적 해제만으로 해결되지 않아요. 실제 자격 증명은 폐기·재발급하고, 이력 정리는 별도의 범위로 판단해야 해요. 이번 예제에는 실제 비밀값을 사용하지 않았어요.

끝난 상태와 과거 기록을 함께 확인해요

  • 브랜치는 main이고 커밋은 총 다섯 개예요. index.js와 README.md는 시작할 때와 같아요.
  • 일반 status는 working tree clean이지만, --ignored에는 !! local-notes.txt와 !! debug.log가 보여요.
  • ls-files에는 .gitignore, README.md, index.js만 있어요. 두 미커밋 diff는 비어 있어요.
  • 디스크에는 메모 두 줄과 로그가 그대로 있어요. 원격 저장소는 없어요.
  • git show HEAD~1:local-notes.txt에는 첫 메모 한 줄이 나와요. 추적 해제가 과거 기록까지 지우지는 않았어요.
“상태가 깨끗하다”는 말이 폴더의 모든 파일을 커밋했다는 뜻은 아니에요. 이번에는 메모와 로그가 제외된 채 남아 있어요. 파일의 존재, 추적 여부, 규칙의 일치, 과거 기록을 나누어 확인하면 .gitignore를 수정할지, 이미 추적 중인 파일을 다룰지 판단할 수 있어요.

예상과 다른 결과가 나왔다면

브랜치로 작업 위치를 나눠봐요

브랜치를 만들면 폴더가 복사될까요?

이 실습의 다섯 커밋을 이어서 사용해요. 새 브랜치와 HEAD, switch 전후의 파일을 비교하고 미커밋 변경의 이동 조건을 확인해봐요.