Как удалить untracked-файлы в Git: безопасный git clean

Как безопасно удалить untracked-файлы в Git: сначала git clean -nd, потом -fd для каталогов и -x для игнорируемых — и почему clean ничего не удаляет.

HUMANавтор @mrsaynothing47d5 мин чтения

TL;DR: чтобы удалить untracked-файлы в git, выполните git clean -fd — но сначала всегда смотрите превью через git clean -nd, потому что clean удаляет навсегда: ни корзины, ни отката. -f — для файлов, -fd — для файлов и каталогов, -fdx — если заодно должен уйти игнорируемый build-выход. Самая частая жалоба — «git clean не удаляет мои untracked-файлы» — почти всегда означает, что файлы лежат внутри untracked-каталога (добавьте -d) или это игнорируемые файлы (добавьте -x). Untracked-мусор — нормальный побочный продукт экспериментов, сборок и скриптов рядом с клоном; этот гайд показывает, как посмотреть превью каждого удаления, вычистить одну директорию и какие комбинации никогда не запускать в репозитории, который вам дорог.

Что такое untracked-файлы в git status?

Untracked значит, что git видит файл на диске, но его никто не просил отслеживать — файла нет в индексе и нет в истории коммитов. git status раскладывает всё по трём корзинам:

$ git status --short
 M src/app.ts        # изменён: отслеживаемый, есть правки
?? notes.txt         # untracked: новый файл, git о нём не знает
?? build/            # untracked-каталог: для git совершенно новый

Это различие важно, потому что каждой корзине нужен свой инструмент удаления. Отслеживаемые, но изменённые файлы откатываются через git restore или просто коммитятся — git clean их не тронет. Территория git clean — только строки с ??. Игнорируемые файлы (всё, что матчится с .gitignore) — скрытая четвёртая корзина: они даже не показываются как ??, и git clean их пропускает, пока вы явно не включите -x.

Если ваша реальная проблема — отслеживаемый файл, который вообще не следовало коммитить, чистка тут не поможет: это работа для git rm --cached или отката последнего коммита, как разобрано в git undo last commit: keep the changes.

Как удалить все untracked-файлы и папки в git?

Базовая команда — 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, build-выход, .env).
  • -X — удаляет только игнорируемые файлы, оставляя untracked, но не игнорируемые.
  • -i — интерактивный режим; выручает, когда список из dry-run длинный.

Привычка, которую стоит скопировать: относитесь к git clean -nd как к git diff — перед коммитом вы смотрите diff, перед чисткой смотрите список.

Почему 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 их не удалит. Включайте явно:

git clean -fdx   # untracked + игнорируемые файлы и каталоги

3. На пути вложенный git-репозиторий или сабмодуль. Git никогда не удаляет содержимое чужого репозитория снаружи. Правильно удалите сабмодуль или передайте --force дважды (git clean -ffd) — но первый вариант лучше.

Если dry-run не показывает ничего, а git status всё ещё содержит ??, вы, скорее всего, не в том рабочем дереве — выполните git rev-parse --show-toplevel и проверьте, что находитесь внутри того репозитория, который собирались чистить.

Как удалить untracked-файлы только из одной директории?

Ограничьте чистку путём — всё остальное останется нетронутым:

git clean -fd build/          # только внутри build/
git clean -fd src/generated   # одно конкретное дерево

Это ответ на «хочу вычистить untracked-файлы и папки в build/, но сохранить свои черновые заметки в корне репозитория». Путь относительный: запустили из корня — чистится весь репозиторий, из подкаталога — это поддерево.

Как убрать untracked-файлы, не удаляя их?

Когда dry-run показывает файлы, которые могут пригодиться позже, не играйте в рулетку — сначала сохраните, потом чистите:

# Убираем 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 не существует: удалённое — удалено.

git clean vs git rm vs git restore: что и когда?

Команда Затрагивает Удаляет с диска Когда использовать
git clean -fd Untracked-файлы/каталоги Да Удалить файлы, которые git никогда не отслеживал
git clean -fdx Untracked + игнорируемые Да Полный сброс: включая node_modules, build-выход
git rm <file> Отслеживаемые файлы Да (stage + диск) Удалить файл и записать удаление в git
git rm --cached <file> Отслеживаемые файлы Нет Перестать отслеживать файл, оставив его на диске
git restore <file> Отслеживаемые файлы Нет Отменить локальные правки, файл оставить

Правило в одну строку: clean управляет тем, о чём git не знает; rm и restore — тем, о чём знает. Путаница между ними и стоит людям работы: достаточно запустить git clean -fdx, будучи уверенным, что это ведёт себя как git restore.

Что никогда не стоит чистить через git clean?

Две привычки, которые надо вычеркнуть сразу:

  1. Никогда не запускайте git clean -fdx вслепую в монорепозитории или воркспейсе. Он удаляет каждый игнорируемый каталог — это все node_modules, все виртуальные окружения, все локальные .env в дереве. Восстановление может обойтись в час переустановок, а удалённый .env может не восстановиться вообще.
  2. Никогда не делайте алиас для clean с вшитым force. git config alias.wipe "clean -fd" ощущается эффективным, пока вы не опечатаетесь в пути. Держите dry-run в одном нажатии (git clean -nd) и превратите чистку в ритуал из двух команд: сначала превью, потом удаление.

Кстати: чистка untracked-файлов прямо перед пуллом уменьшает поверхность слияния — а аккуратное дерево, самая дешёвая страховка от конфликтов, делается по шагам за один вечер.

Безопасный workflow git clean: кратко

git status --short        # что лежит в дереве?
git clean -nd             # превью: что БЫЛО бы удалено?
git clean -fd             # удалить untracked-файлы + каталоги
git clean -fdX            # (опционально) снести только игнорируемый build-выход
git status --short        # проверка: рабочее дерево чистое

Превью, удаление, проверка — тридцать секунд, ноль сожалений, и git status наконец снова читается как «чисто».