Назад до блога

Gitignore не працює? Ось справжнє виправлення

17 вересня 2026 р.

TL;DR: якщо .gitignore не працює, файл майже завжди вже відстежується. Git ігнорує файли, яких ніколи не бачив — файл в індексі імунний до будь-якого правила, яке ви напишете. Спитайте правду через git check-ignore -v <path>: тиша означає, що шлях відстежується і правило не діє. Виправлення — git rm --cached <path>, коміт, і правило починає працювати з цього коміта. Порядок правил, пастки заперечень і червоні оселедці з VS Code пояснюють решту випадків.

Чому .gitignore не працює?

Один механізм покриває більшість: файл був закомічений до появи правила. .gitignore — не фільтр, що ховає файли від git; це правило про те, що git add має підбирати з невідстежуваного стану. Щойно файл в індексі — git стежить за його змінами вічно, поки ви явно не знімете відстеження. Редагування .gitignore постфактум нічого не змінює для відстежуваних файлів — тому класична послідовність «закомітив .env, паніка, додав .env у .gitignore, закомітив знову» досі вантажить секрет у кожен пуш.

Це кусає всіх, бо git майже універсальний — опитування Stack Overflow 2022 нарахувало Git у понад 93% професійних розробників (survey.stackoverflow.co) — і кожен із них рано чи пізно пише правило для файлу, закоміченого минулого тижня.

Решта статті — про меншість випадків: помилки порядку правил, пастки заперечень, крайні випадки тек і питання IDE. Але спершу прогоніть health-check з наступного розділу — понад дев’ять разів із десяти він закінчує розслідування.

Як дізнатися, яке правило gitignore матчить файл?

git check-ignore — діагностичний інструмент, і його тиша — діагноз:

# Друкує правило + файл + номер рядка, коли правило діє
git check-ignore -v debug.log
# .gitignore:3:*.log    debug.log

# НЕ друкує нічого, коли правило не діє — файл відстежується (чи правила немає)
git check-ignore -v src/.env
# (тиша = .gitignore не ігнорує цей шлях, що б ви там не написали)

# Коди виходу: 0 = ігнорується, 1 = ні — скриптується
git check-ignore -q debug.log && echo "ignored" || echo "tracked or unruly"

Читання виводу -v: джерело ігнорування (.gitignore, .git/info/exclude чи глобальний файл), потім номер-рядка:шаблон, потім шлях. Якщо пізніше правило здивувало — пам’ятайте: останнє матчине правило перемагає, тож !important.log після *.log повертає саме той один файл.

Чому gitignore не працює для вже закомічених файлів?

Зніміть файл з відстеження, лишіть на диску, закомітьте видалення:

# Зняти відстеження одного файлу (локальна копія живе — --cached торкається лише індексу)
git rm --cached .env
git commit -m "stop tracking .env"

# Перевірити, що правило тепер діє
git check-ignore -v .env

Від цього коміта далі .gitignore володіє шляхом: правки більше не показуються у git status, і git add . не підхопить його знову. Але файл лишається в історії — якщо це був секрет, прибрати його з останнього коміта недостатньо. Ротація креденшалів — єдине справжнє лікування; перезапис історії — косметика (а скасування останнього коміта помагає лише поки поганий коміт — вершина).

Для репозиторію, повного раніше закоміченого сміття — артефактів збирання, обрізків редактора, node_modules, що просочилися рано — масове зняття відстеження у два рядки:

git rm -r --cached .
git add .
git commit -m "apply .gitignore to tracked files"

Це перебудовує індекс за чинними правилами: ігноровані шляхи випадають, усе інше перезаписується без змін. Диф виглядає драматично (тисячі видалень), але з диска не зникає нічого. Якщо ціль — саме видаляти ті файли, а не лише знімати відстеження, то це територія git clean -fdx — дивіться git remove untracked files, safely.

Git ігнорує файли, яких ніколи не бачив. Файл, вже в індексі, імунний до .gitignore — жодне правило не змусить його забути.

Чому gitignore не працює для теки?

Три текові пастки:

1. Кінцеві слеші — про намір, не про матчинг. build і build/ обидва матчать каталог, але build/ документує, що ви маєте на увазі лише каталог — файл з ім’ям build його переживе. Однак симетрія ламається на повторному включенні (наступна пастка).

2. Заперечення не рятує файли всередині виключеної теки. Документація git однозначна: “It is not possible to re-include a file if a parent directory of that file is excluded” (git-scm.com/docs/gitignore). Це рішення про продуктивність — git пропускає виключені каталоги цілком, а не прогулюється ними. Тому це не працює:

build/
!build/keep.me        # мертве правило — git ніколи не дивиться всередину build/

Виправлення — виключати вміст, а не каталог:

build/*
!build/keep.me        # працює — сама build/ лишається відкритою для огляду

3. Вкладені .gitignore перемагають у своєму обсязі. Правила з subdir/.gitignore перекривають кореневий файл для шляхів під subdir. Коли git check-ignore -v називає несподіване джерело ігнорування — зазвичай саме тому.

Чому gitignore не працює у VS Code?

Майже ніколи через VS Code. Source Control у редакторі читає той самий індекс, що й git, тож симптом ідентичний: файл був закомічений, і рестарт IDE індекс не змінює. Дві реальності біля VS Code, вартий знання:

  • Сіре в Explorer = ігнорується; помаранчеве/жовте = відстежується зі змінами. Файл, що виглядає зміненим після вашого ігнорування, — ваше підтвердження, що він відстежується: запускайте виправлення git rm --cached вище.
  • Відсутність .gitignore у списку змінених означає, що правило працює — він просто ніколи не показувався невідстежуваним. Люди часто звітують «VS Code ігнорує мій gitignore», поки CLI git status розходиться з застарілим SCM-виглядом; перезавантажте вікно (Cmd/Ctrl+Shift+P → «Reload Window»), перш ніж звинувачувати git.

.gitignore vs .git/info/exclude vs глобальний: який коли?

ФайлОбсягКомітиться?Для чого
.gitignore (репозиторій)Усі, хто клонеТакАртефакти збирання, залежності, .env — спільні правила
.git/info/excludeЛише ваш клонНіОсобисте мотлох: .scratch/, обрізки редактора
core.excludesFile (глобальний)Усі ваші репозиторіїНіОС-й мотлох: .DS_Store, Thumbs.db, *.swp
.gitignore + запереченняРепозиторійТакПовторне включення винятків для відстежуваного конфігу

Глобальний файл — те, чого більшість розробників не виставляє і мусила б:

git config --global core.excludesFile ~/.gitignore_global
printf '.DS_Store\nThumbs.db\n*.swp\n' >> ~/.gitignore_global

Домашнє правило, варте копіювання: якщо правило корисне всій команді — йому місце в репозиторії; якщо лише вам — в exclude чи глобальному файлі. Коміт особистих правил ігнорування — це спосіб, як .gitignore виростає до 300 рядків, і ніхто не знає, яка половина досі жива.

Як ігнорувати зміни відстежуваного файлу?

Іноді ви хочете відстежуваний файл (шаблон конфігу, налаштування IDE), але хочете, щоб локальні правки перестали показуватися у git status. Два прапорці git update-index, і жоден не належить командному workflow:

git update-index --skip-worktree config/local.dev   # локальні правки затихають
git update-index --no-skip-worktree config/local.dev  # ...і повертаються

--skip-worktree — відстоюваний варіант: він каже «моя локальна версія розходиться навмисно». Родич --assume-unchanged — обіцянка продуктивності («цей файл не зміниться»), не механізм ігнорування, і git може мовчки порушити обіцянку. Обидва прапорці гучно падають на pull, якщо upstream теж змінив файл — довговічні відповіді: локальний конфіг через exclude від народження, або шаблонний файл (config.example), який git відстежує, а ви копіюєте.

Health-check gitignore за 30 секунд

git check-ignore -v <path>        # яке правило? (тиша = відстежується, правила немає)
git ls-files --error-unmatch <path>  # він узагалі відстежується?
git rm --cached <path>            # зняти відстеження, лишити на диску
git commit -m "stop tracking <path>"
git check-ignore -v <path>        # правило тепер видно

Діагностика, зняття відстеження, перевірка. Патерн за кожним звітом «gitignore not working» — один і той самий файл у двох капелюхах: відстежуваний з одного боку індексу й ігнорований з іншого, і один прапорець --cached знімає другий капелюх.

FAQ

Чому .gitignore не працює?

У більшості випадків файл уже відстежується. Git ігнорує лише невідстежувані файли; файл в індексі імунний до .gitignore, поки ви не знімете відстеження через git rm --cached і не закомітите.

Як перевірити, яке правило gitignore збігається з файлом?

Виконайте git check-ignore -v <path>. Він друкує точний рядок .gitignore і номер правила, або мовчить, коли файл відстежується і жодне правило не діє.

Чи видаляє git rm --cached мій локальний файл?

Ні. --cached прибирає файл лише з індексу; копія на диску лишається. Закомітьте видалення — файл стане невідстежуваним, і тоді .gitignore запрацює.

Чому gitignore не може знову включити файл всередині ігнорованої теки?

Заради продуктивності Git пропускає виключені теки цілком. За документацією git, неможливо знову включити файл, якщо батьківська тека цього файла виключена.

— mrsaynothing

— mrsaynothing

Польові нотатки про ШІ, Linux і self-hosting.

Обговорити пост на dev.to dev.to ↗

Наступний гайд — на email

Один лист на пост. Полагодили — і далі.

self-hosted · без третіх сторін · відписка в один клік

що це таке?

Ollama не використовує GPU? Виправлення на Linux, Windows і WSL

Читається добре? Таке я будую за гроші. найміть мене