한 줄 요약: git에서 untracked 파일을 지우려면 git clean -fd — 단, git clean -nd로 미리보기를 먼저 실행하세요. clean은 영구 삭제이고, 지워진 파일은 휴지통조차 거치지 않습니다. 파일은 -f, 파일과 디렉터리는 -fd, gitignore된 빌드 출력까지 지우려면 -fdx입니다. 가장 흔한 불만 — “git clean이 untracked 파일을 안 지운다” — 은 거의 항상 파일이 untracked 디렉터리 안에 있거나(-d 추가) 무시된 파일이라는(-x 추가) 뜻입니다. untracked 잔재는 실험, 빌드, 클론 부근 스크립트의 지극히 정상적인 부산물입니다. 이 글은 모든 삭제를 미리보는 법, 한 디렉터리에서만 파일을 지우는 법, 그리고 소중한 저장소에서 절대 실행하면 안 되는 조합이 무엇인지 보여줍니다.
git status에서 “untracked 파일”이란?
Untracked는 git이 디스크에서는 파일을 보지만 추적하라는 지시를 받은 적이 없다는 뜻입니다 — 인덱스에도 없고 커밋 이력도 없습니다. git status는 모든 것을 세 부류로 나눕니다:
$ git status --short
M src/app.ts # modified: 추적 중, 변경됨
?? notes.txt # untracked: git이 모르는 새 파일
?? build/ # untracked 디렉터리: git에게 완전히 새로운 존재 이 구분이 중요한 이유는 부류마다 필요한 삭제 도구가 다르기 때문입니다. 추적 중이지만 변경된 파일은 git restore로 되돌리거나 커밋으로 처리합니다 — git clean은 손대지 않습니다. ?? 줄만이 git clean의 영역입니다. 무시된 파일(.gitignore에 걸리는 모든 것)은 숨은 네 번째 부류입니다: ??로조차 표시되지 않고, -x로 명시적으로 opt-in하지 않으면 git clean이 건너뜁니다.
진짜 문제가 애초에 커밋되면 안 됐던 추적 중인 파일이라면, clean은 잘못된 도구입니다 — 그건 git rm --cached의 일이거나, git undo last commit: keep the changes에서 다룬 마지막 커밋 리셋의 일입니다.
git에서 untracked 파일을 삭제하는 방법은?
핵심 명령은 git clean -f입니다. -f 없이는 git이 아무것도 지우기를 거부하고 경고만 출력합니다 — 의도된 안전 장치입니다. 전체 루틴은 이렇습니다:
# 1. 무엇이 삭제될지 정확히 확인 (dry run — 아무것도 지우지 않음)
git clean -nd
# 삭제될 목록:
# notes.txt
# build/
# scratch/
# 2. 목록에 소중한 게 없는지 확인한 뒤 진짜로 삭제
git clean -fd 플래그 하나씩:
-f/--force— 필수. untracked 파일을 실제로 삭제합니다.-d— untracked 디렉터리 안까지 재귀적으로 들어갑니다.-f만 쓰면 최상위 untracked 파일만 지우고, 건드리기를 거부한 디렉터리는 보고만 합니다.-n/--dry-run— 무엇이 지워질 예정인지 보여줍니다. 항상 먼저 실행하세요.-x— 무시된 파일도 삭제합니다(node_modules, 빌드 출력,.env).-X— 무시된 파일만 삭제하고, 무시되지 않은 untracked는 유지합니다.-i— 대화형 모드; dry-run 목록이 길 때 유용합니다.
따둘 만한 습관: git clean -nd를 git diff처럼 다루세요 — 커밋 전에 diff를 보듯, clean 전에 미리보기를 봅니다.
git clean이 untracked 파일을 지우지 않는 이유는?
실제 원인 셋, 자주 부딪히는 순서대로:
1. 파일이 untracked 디렉터리 안에 있다. -f만으로는 git이 떠돌이 untracked 파일은 지우지만 디렉터리 앞에서 멈춥니다 — 실제 실행에서는 지우지 않으면서 Would remove build/라고 보고만 합니다. -d를 추가하세요:
git clean -fd 2. 파일이 gitignore되어 있다. node_modules/, dist/, .venv/ — 무시된 경로는 평범한 clean에 보이지 않습니다. dry run 목록에도 없고, clean이 지우지도 않습니다. 명시적으로 opt-in하세요:
git clean -fdx # untracked + 무시된 파일과 디렉터리 3. 중첩된 git 저장소나 서브모듈이 가로막고 있다. Git은 다른 저장소의 내용을 밖에서 지우지 않습니다. 서브모듈을 제대로 제거하거나 --force를 두 번 넘기세요(git clean -ffd) — 첫 번째 방법이 낫습니다.
dry run은 아무것도 안 뽑는데 git status에는 여전히 ??가 있다면, 잘못된 작업 트리에 있을 가능성이 큽니다 — git rev-parse --show-toplevel을 실행해 의도했던 저장소 안인지 확인하세요.
특정 디렉터리의 untracked 파일만 지우는 방법은?
경로를 넘겨 clean의 범위를 한정합니다 — 나머지는 그대로 둡니다:
git clean -fd build/ # build/ 안만
git clean -fd src/generated # 특정 트리 하나만 “build/ 안의 untracked 파일과 폴더는 지우되 저장소 루트의 스크래치 노트는 남기고 싶다”의 답이 이것입니다. 경로는 현재 디렉터리 기준 상대 경로라서, 저장소 루트에서 실행하면 전체 저장소가, 서브디렉터리에서 실행하면 그 하위 트리가 범위가 됩니다.
삭제하지 않고 untracked 파일을 치우는 방법은?
dry run에 나중에 필요할지도 모르는 파일이 보이면 도박하지 마세요 — 보존이 먼저, clean은 그다음입니다:
# 삭제하지 않고 untracked 파일을 stash (-a를 붙이면 무시된 파일까지)
git stash push --include-untracked
git clean -fd # 트리가 깨끗해짐
git stash pop # 필요할 때 다시 꺼냄 git stash -u는 untracked 파일을 트리 밖으로 옮기되 복구 가능하게 유지합니다 — 사람들이 실제로 찾는 “삭제 없이 치우기”의 의미가 이것입니다. 보관해둘 수 있는 미리보기로는 git clean -nd > clean-plan.txt가 아무것도 확정하기 전에 정확한 목록을 줍니다. git clean -f 뒤에는 undo가 없습니다: 지워졌다는 건 사라졌다는 뜻입니다.
git clean vs git rm vs git restore: 언제 무엇을?
| 명령 | 대상 | 디스크에서 삭제 | 이럴 때 사용 |
|---|---|---|---|
git clean -fd | Untracked 파일/디렉터리 | 예 | git이 한 번도 추적한 적 없는 파일 삭제 |
git clean -fdx | Untracked + 무시됨 | 예 | node_modules, 빌드 출력까지 포함한 전체 리셋 |
git rm <file> | 추적 중인 파일 | 예 (staged) | 파일을 지우면서 그 삭제를 git에 기록 |
git rm --cached <file> | 추적 중인 파일 | 아니오 | 추적은 멈추고 파일은 디스크에 유지 |
git restore <file> | 추적 중인 파일 | 아니오 | 로컬 수정은 버리고 파일은 유지 |
한 줄 규칙: clean은 git이 모르는 것을, rm과 restore는 git이 아는 것을 다룹니다. 이 둘을 헷갈리는 게 작업을 잃는 길입니다 — git restore처럼 동작한다고 믿으며 git clean -fdx를 실행하는 일.
git clean을 절대 실행하면 안 되는 상황은?
즉시 걷어내야 할 습관 둘:
- 모노레포나 워크스페이스에서
git clean -fdx를 무작정 실행하지 마세요. 모든 무시된 디렉터리를 지웁니다 — 트리 안의 모든node_modules, 모든 virtualenv, 모든 로컬.env. 되살리는 데 한 시간 재설치가 걸릴 수 있고, 지워진.env는 아예 복구 불가능할 수 있습니다. - force가 박힌 clean 별칭을 만들지 마세요.
git config alias.wipe "clean -fd"는 경로를 오타 내기 전까지만 효율적으로 느껴집니다. dry run을 키 한 번 거리(git clean -nd)에 두고, 미리보기-삭제의 두 커맨드 의식으로 만드세요.
참고로: untracked 파일을 정리한 직후 [sync a fork with upstream] 풀을 하면 머지 노출 면이 작아집니다 — 깔끔한 트리가 가장 싼 충돌 보험입니다: sync a fork with upstream, step by step.
안전한 git clean 워크플로우, 요약
git status --short # 트리에 뭐가 있지?
git clean -nd # 미리보기: 뭐가 지워질 예정이지?
git clean -fd # untracked 파일 + 디렉터리 삭제
git clean -fdX # (선택) 무시된 빌드 출력만 정리
git status --short # 확인: 작업 트리 깨끗 미리보고, 지우고, 확인합니다 — 30초, 후회 0, 그리고 git status가 드디어 깨끗하게 다시 읽힙니다.
— mrsaynothing
Get the next one by email
One email per post. No spam, no algorithms.
what is this?rsync vs scp: 어떤 Linux 복사 명령어를 써야 할까
글이 마음에 드셨나요? 제 본업이 바로 이런 일입니다. 저를 고용하세요