.gitignore не работает: правило не достаёт до индекса
check-ignore -v решает всё за тридцать секунд — напечатанное правило значит беду с правилами, тишина значит, что файл уже отслеживается, а rm --cached ставит точку.
■ space · полоса прозы
.gitignore «не работает» почти всегда означает, что файл уже отслеживается — файл в индексе невосприимчив к любому правилу, которое вы напишете.
git check-ignore -v <path> даёт ответ: напечатанное правило = проблема с правилами; тишина = файл отслеживается и ни одно правило не действует.
Лечение: git rm --cached <path>, commit — правило работает начиная с этого коммита.
ДВЕ ДВЕРИ
Одна команда, два исхода — git check-ignore -v проводит вас через одну из них:
ДВЕРЬ 1 · печатает правило
$ git check-ignore -v debug.log
.gitignore:3:*.log debug.log
правило действует — не то, или не в той области видимости. Проблема живёт в файле .gitignore: порядок правил, ловушки отрицания или то, какой ignore-файл владеет путём.
ДВЕРЬ 2 · тишина
$ git check-ignore -v src/.env
$ # (nothing — no rule applies)
файл всё равно отслеживается. Проверьте через git ls-files --error-unmatch <path>, затем git rm --cached <path> и закоммитьте удаление. Тишина — это и есть диагноз.
коды выхода скриптуются: 0 = игнорируется, 1 = не игнорируется — git check-ignore -q debug.log && echo ignored || echo tracked-or-unruly
ЭКЗЕМПЛЯР — GITIGNORE, СТРОКА ЗА СТРОКОЙ
Ловушка отрицания, с аннотациями. Почему !build/keep.me никогда не спасает файл:
build/игнорирует каталог целиком — git больше никогда не заглядывает внутрь!build/keep.meмёртвая буква: нельзя заново включить файл внутри исключённого каталогаbuild/*лекарство — игнорируйте содержимое, а не каталог!build/keep.meтеперь живо: родительский путь проходим, исключение действует*.log затем !important.logпобеждает последнее совпавшее правило — отрицание после правила заново включает единственный файлПОЛНАЯ ТАБЛИЦА ПРИЧИН
| Симптом | Настоящая причина | Лечение |
|---|---|---|
Игнорируемый файл всё ещё виден в git status | Закоммичен до правила — в индексе | git rm --cached + commit |
git add . снова и снова его добавляет | То же: отслеживание сильнее игнорирования | Массово: git rm -r --cached . → git add . |
!build/keep.me никогда не спасает файл | Родительский каталог исключён — git пропускает его целиком | build/* + !build/keep.me |
| Позже идущее правило затирает ваше | Побеждает последнее совпавшее правило | Переставьте или прочитайте победителя через check-ignore -v |
| Правило работает у коллег, но не у вас (или наоборот) | .gitignore вложенный / exclude / глобальный — рассинхрон | Сверьтесь с таблицей областей видимости ниже |
| VS Code показывает его изменённым после игнорирования | Отслеживается — или устаревший вид SCM | git rm --cached; сначала перезагрузите окно |
| Нужны тихие правки при отслеживаемом файле | Осознанное локальное расхождение | git update-index --skip-worktree |
ТРИ ОБЛАСТИ ВИДИМОСТИ
Правила могут жить в трёх местах, и «у коллег работает, у меня нет» почти всегда означает несовпадение области видимости:
.gitignoreв репозитории — закоммичен, доступен всем. Дом по умолчанию для результатов сборки и каталогов зависимостей..git/info/exclude— на клон, никогда не коммитится. Для ваших личных рабочих файлов в этом конкретном checkout.- Ваш глобальный ignore-файл (
core.excludesFile) — на машину, во всех репозиториях. Классический дом для.DS_Storeи мусора от редакторов.
В выводе check-ignore -v источник называется прямо: файл ignore, затем line-number:pattern, затем путь — так что когда побеждает неожиданное правило, победитель сам себя называет.
проверка: git check-ignore -v debug.log → .gitignore:3:*.log debug.log
УБИРАЕМ ИЗ ОТСЛЕЖИВАНИЯ, ШАГ ЗА ШАГОМ
# untrack one file (the local copy survives — --cached touches the index only)
git rm --cached .env
git commit -m "stop tracking .env"
# verify the ignore rule now applies
git check-ignore -v .env
Начиная с этого коммита, .gitignore владеет путём: правки больше не видны в git status, а git add . больше не подхватит файл.
Если это был секрет, убрать из отслеживания — не решение. Файл остаётся в истории — удалить его из последнего коммита недостаточно. Настоящее лечение — ротация секрета; переписывание истории — косметика.
конец двух дверей · ничего не fetchили · всё локально