동작하는 코드
예제 1: .gitignore 기본 작성
cat > .gitignore << 'EOF'
# 의존성
node_modules/
# 환경 변수 (절대 커밋 금지!)
.env
.env.local
.env.*.local
# 빌드 결과물
dist/
build/
*.min.js
# 에디터 설정
.vscode/
.idea/
*.swp
# OS 파일
.DS_Store
Thumbs.db
# 로그
*.log
npm-debug.log*
EOF
확인:
git add .gitignore
git commit -m "chore: .gitignore 추가"
.env 파일 만들기:
echo "API_KEY=secret123" > .env
git status
출력:
nothing to commit, working tree clean
.env가 무시됩니다.
예제 2: stash로 작업 임시 저장
# 작업 중...
echo "미완성 기능" > feature.txt
git add feature.txt
# 긴급 버그 수정 요청!
git stash
git status
출력:
nothing to commit, working tree clean
버그 수정 후 작업 복원:
git stash pop
git status
출력:
Changes to be committed:
new file: feature.txt
직접 수정하기
.gitignore 패턴 문법 상세
# 기본 패턴
*.log # 모든 .log 파일 (재귀적)
!important.log # 예외: important.log는 무시하지 않음
# 슬래시(/)의 의미
/TODO # 루트의 TODO만 무시
TODO # 모든 디렉토리의 TODO 무시
build/ # build 디렉토리 무시 (슬래시 끝 = 디렉토리)
doc/ # doc 디렉토리와 그 안의 모든 파일
# ** (글로브 패턴)
**/*.log # 모든 하위 디렉토리의 .log 파일
**/node_modules # 모든 node_modules 디렉토리
doc/**/*.txt # doc 아래 모든 .txt 파일
# 구체적인 파일
.env # 정확히 이 이름
.env.* # .env.로 시작하는 모든 파일
.env.local
.env.production
! 예외 패턴:
# 모든 .txt 무시하되
*.txt
# README.txt는 허용
!README.txt
주의: 이미 무시된 디렉토리 내의 파일은 !로 허용할 수 없습니다.
여러 stash 관리
# 설명 있는 stash
git stash push -m "로그인 기능 작업 중"
git stash push -m "디자인 수정 중"
# stash 목록
git stash list
출력:
stash@{0}: On main: 디자인 수정 중
stash@{1}: On main: 로그인 기능 작업 중
# 특정 stash 확인
git stash show stash@{1}
# 내용까지 확인
git stash show -p stash@{1}
# 특정 stash 적용 (삭제 안 함)
git stash apply stash@{1}
# 특정 stash 적용 + 삭제
git stash pop stash@{1}
# 특정 stash 삭제
git stash drop stash@{0}
# 모든 stash 삭제
git stash clear
stash를 새 브랜치로 꺼내기:
# stash 내용을 새 브랜치에서 적용
git stash branch feature-login stash@{0}
이 방법은 stash를 만든 시점의 커밋을 기반으로 새 브랜치를 만들고 stash를 적용합니다.
"왜?" — .gitignore가 중요한 이유
git에 올리지 말아야 할 파일들:
| 종류 | 이유 |
| -------------------- | ------------------------------------ |
| .env | API 키, 비밀번호 — 보안 사고 |
| node_modules/ | 수백 MB, npm install로 재생성 가능 |
| *.log | 자동 생성, 환경마다 다름 |
| .DS_Store | macOS 시스템 파일 |
| dist/ | 소스에서 자동 생성 |
| .idea/, .vscode/ | 개발자마다 다른 에디터 설정 |
비밀키가 git에 올라갔을 때 대처:
# 이미 커밋된 경우
# 1. 즉시 해당 키를 GitHub/AWS 등에서 삭제/재발급
# 2. git 히스토리에서 제거 (복잡)
# 3. 새 키로 교체
# 예방이 최선
echo ".env" >> .gitignore
이미 추적 중인 파일을 .gitignore에 추가
.gitignore는 이미 추적 중인 파일을 무시하지 않습니다:
# 이미 커밋된 .env를 추후 무시하려면
echo ".env" >> .gitignore # 이걸로는 부족
# 캐시에서 제거 (파일은 로컬에 유지)
git rm --cached .env
git commit -m "chore: .env 추적 중단"
git rm --cached는 Git의 추적 목록에서만 제거하고 파일 자체는 유지합니다.
흔한 실수
실수 1: .gitignore를 나중에 추가
# 처음부터 .gitignore 없이 node_modules 커밋
git add .
git commit -m "init" # node_modules 포함됨!
# 나중에 .gitignore 추가해도 이미 추적 중
# git rm --cached -r node_modules/ 로 제거 필요
프로젝트 시작 시 첫 번째로 할 일이 .gitignore 만들기입니다.
실수 2: stash pop과 apply 혼동
git stash pop # 적용 + stash 목록에서 삭제
git stash apply # 적용만, stash는 유지 (여러 곳에 적용할 때)
실수 3: stash 충돌 무시
git stash pop
# CONFLICT: 충돌 발생
stash pop도 충돌이 날 수 있습니다. 충돌 해결 후 git add, git stash drop으로 정리하세요.
실수 4: .gitignore에 이미 커밋된 파일 추가
# 효과 없음
echo "secrets.txt" >> .gitignore
git status # secrets.txt 여전히 추적됨
# 올바른 방법
git rm --cached secrets.txt
git commit -m "chore: 민감 파일 추적 중단"
심화 학습
글로벌 .gitignore 설정
모든 프로젝트에서 공통으로 무시할 파일:
git config --global core.excludesfile ~/.gitignore_global
cat > ~/.gitignore_global << 'EOF'
# macOS
.DS_Store
.AppleDouble
# 에디터
.vscode/
*.swp
*.swo
.idea/
# 기타
*.log
.env
EOF
gitignore.io로 자동 생성
gitignore.io에서 언어/환경별 .gitignore를 자동 생성:
curl -sL https://www.toptal.com/developers/gitignore/api/node,macos,vscode > .gitignore
또는 gh 확장:
gh extension install github/gh-gitignore
gh gitignore list
gh gitignore create Node macOS >> .gitignore
stash와 함께 추적되지 않은 파일 저장
기본 git stash는 추적 중인 파일만 저장합니다:
# 추적되지 않은 파일도 포함
git stash push -u # --include-untracked
# 무시된 파일까지 포함
git stash push -a # --all
.gitignore를 만들어*.log,.env,node_modules/를 추가하세요.echo "KEY=secret" > .env후git status로 무시되는지 확인하세요.echo "임시 작업" > temp.txt && git add temp.txt로 작업을 시작하세요.git stash push -m "임시 작업 저장"으로 저장하고git status로 깨끗해졌는지 확인하세요.git stash list로 목록을 보고git stash pop으로 복원하세요.
Q1. 이미 git이 추적 중인 파일을 .gitignore에 추가했지만 여전히 추적됩니다. 추적을 중단하려면?
- A)
git ignore 파일명 - B)
git rm --cached 파일명 - C)
git remove 파일명 - D)
.gitignore에 추가하면 자동으로 해결