■ пространство · прозаическая полоса
git clean -nd показывает, git clean -fd удаляет — clean необратим; корзина тут ни при чём.
Clean ничего не удаляет? Файлы сидят внутри неотслеживаемого каталога (добавьте -d)) либо они игнорируемые (добавьте -x).
Хотите, чтобы их можно было вернуть? git stash -u перед очисткой — отмены не будет после -f.
ЗОНА ПОРАЖЕНИЯ
Каждый файл в вашем дереве живёт в одной из трёх зон — и каждый флаг clean достаёт ровно до одного круга:
clean их не трогает. Правки: git restore. Удаление: git rm.
достаются через clean -f, и через -d внутри неотслеживаемых каталогов
достаются только с -x (или -X для игнорируемых)
четвёртый ящик — ловушка: игнорируемые файлы даже не показываются как ?? — простой clean молча их пропускает, вот почему он «ничего не удаляет»
ЧТО ЗНАЧИТ «НЕОТСЛЕЖИВАЕМЫЙ»
Неотслеживаемый означает, что git видит файл на диске, но ему никогда не говорили его отслеживать — нет в индексе, нет истории коммитов. git status раскладывает всё по ящикам, и каждому нужен свой инструмент удаления:
$ git status --short
M src/app.ts # modified: tracked, changed
?? notes.txt # untracked: new file git doesn't know
?? build/ # untracked directory: entirely new to git
Отслеживаемые-изменённые файлы откатываются через git restore или уходят в commit — git clean их не трогает. Только ?? строки — территория clean. Если ваша реальная проблема — файл отслеживаемый которого никогда не следовало коммитить, clean — не тот инструмент, это работа для git rm --cached или reset последнего коммита.
РИТУАЛ
# 1. see exactly what will be deleted (dry run — deletes nothing)
git clean -nd
# Would remove:
# notes.txt
# build/
# 2. confirm nothing precious is in the list, then delete for real
git clean -fd
verify: git clean -nd → печатает «Would remove notes.txt build/» · после -fd: git status --short не содержит строк ??
Привычка, которую стоит перенять: относитесь к git clean -nd как к git diff — вы смотрите перед коммитом, смотрите перед чисткой. Флаг за флагом:
-f/--force— обязателен. На самом деле удаляет неотслеживаемые файлы. Без него git откажется и напечатает предупреждение — сознательно встроенная защита.-d— заходить внутрь неотслеживаемых каталогов. Простой-fубирает лишь неотслеживаемые файлы верхнего уровня и сообщает каталоги, куда отказался лезть.-n/--dry-run— показать, что будет удалено. Всегда первым шагом.-x— удалить и игнорируемые файлы (node_modules, вывод сборки,.env).-X— удалять только игнорируемые файлы, сохраняя неотслеживаемые-но-не-игнорируемые.-i— интерактивный режим; полезен, когда список dry-run длинный.-e <path>— исключить — «убери всё кроме notes.txt» этоgit clean -fd -e notes.txt.
«CLEAN НИЧЕГО НЕ УДАЛЯЕТ» — ТРИ ПРИЧИНЫ
- Файлы лежат внутри неотслеживаемого каталога. С одним лишь
-f, git убирает одиночные файлы, но останавливается на каталогах — и даже печатаетWould remove build/не удаляя его в реальном запуске.-d:git clean -fd. - Файлы gitignored.
node_modules/,dist/,.venv/— игнорируемые пути невидимы для простого clean; dry run их тоже не покажет. Просите их явно:git clean -fdx. - Вложенный git-репозиторий или сабмодуль мешает. Git никогда не удаляет содержимое чужого репозитория снаружи. Уберите сабмодуль как следует или передайте
--forceдважды (git clean -ffd) — лучше первый вариант.
Если dry run ничего не показывает, но git status продолжает показывать ?? строк, вы, вероятно, в чужом рабочем дереве — git rev-parse --show-toplevel и проверьте, что вы в том репозитории, который собирались чистить.
ОДИН КАТАЛОГ ЗА РАЗ
Ограничьте чистку, передав путь — всё остальное остаётся нетронутым. Путь относителен текущему каталогу: из корня репозитория охватит весь репозиторий; из подкаталога — его поддерево:
git clean -fd build/ # only inside build/
git clean -fd src/generated # one specific tree
УБРАТЬ, НЕ УДАЛЯЯ
Когда dry run показывает файлы, которые могут понадобиться позже, не рискуйте — сохраните сначала, чистите потом. git stash -u уводит неотслеживаемые файлы из дерева, оставляя их восстановимыми — это и есть та самая семантика «убрать, не удаляя», которую люди ищут на самом деле:
# stash untracked files (including ignored with -a) without deleting
git stash push --include-untracked
git clean -fd # tree is clean
git stash pop # bring them back when needed
verify: git stash list → stash@{0} хранит то, что поднял git stash -u
Для предпросмотра, который можно сохранить: git clean -nd > clean-plan.txt. Отмены не будет после git clean -f: удалённый — значит пропавший — корзина тут ни при чём.
CLEAN VS RM VS RESTORE
| Команда | Затрагивает | Убирает с диска | Когда применять |
|---|---|---|---|
git clean -fd | Неотслеживаемые файлы/каталоги | Да | Удалить файлы, которые git никогда не отслеживал |
git clean -fdx | Неотслеживаемые + игнорируемые | Да | Полный сброс, включая node_modules, вывод сборки |
git rm <file> | Отслеживаемые файлы | Да (в индексе) | Удалить файл и записать удаление в git |
git rm --cached <file> | Отслеживаемые файлы | Нет | Перестать отслеживать файл, оставить его на диске |
git restore <file> | Отслеживаемые файлы | Нет | Отбросить локальные правки, оставить файл |
Правило в одну строку: clean управляет тем, чего git не знает; rm и restore — тем, что знает. Перепутать их — вот так и теряют работу — запустить git clean -fdx , думая, что он ведёт себя как git restore.
08ЧЕГО НИКОГДА НЕ ЗАПУСКАТЬ
- Никогда не запускайте
git clean -fdxвслепую в монорепозитории или workspace. Оно удаляет каждый игнорируемый каталог — каждыйnode_modules, каждый virtualenv, каждый локальный.envв дереве..envможет вообще не восстановиться. - Не встраивайте force в алиас для clean.
git config alias.wipe "clean -fd"кажется эффективным, пока вы не опечатаетесь в пути. Держите dry run на одном нажатии клавиши и превратите его в ритуал из двух команд: предпросмотр, потом удаление.
Весь workflow, сжато:
git status --short # what's in the tree?
git clean -nd # preview: what WOULD go?
git clean -fd # delete untracked files + directories
git clean -fdX # (optional) clear only ignored build output
git status --short # confirm: working tree clean
Предпросмотр, удаление, проверка — тридцать секунд, ноль сожалений, и git status наконец снова читается чисто. Двоюродный брат этой проблемы: .gitignore правила, которые, кажется, ничего не делают — если ваши правила игнорируются, обычно дело в отслеживаемых файлах, а не в синтаксисе. А опрятное дерево прямо перед fork sync держит поверхность слияния малой — самая дешёвая страховка от конфликтов.
git status --short выше показан в том виде, в котором его реально печатает любой репозиторий.конец страницы clean · ничего не скачано · всё локально