Terug naar de blog

Gitignore werkt niet? Dit is de echte fix

17 september 2026

TL;DR: als .gitignore niet werkt, wordt het bestand vrijwel altijd al gevolgd. Git negeert bestanden die het nooit zag — een bestand in de index is immuun voor elke regel die je schrijft. Vind de waarheid met git check-ignore -v <path>: stille output betekent dat het pad tracked is en geen regel geldt. Fix het met git rm --cached <path>, commit, en de ignore-regel werkt vanaf die commit. Regelvolgorde, negatievalkuilen en VS Code-rookgordijnen verklaren de rest.

Waarom werkt .gitignore niet?

Eén mechanisme dekt de meerderheid van de gevallen: het bestand was gecommit voordat de regel bestond. .gitignore is geen filter dat bestanden voor git verbergt — het is een regel over wat git add moet oppakken vanuit een untracked-status. Zit een bestand eenmaal in de index, dan volgt git zijn inhoudswijzigingen voor altijd, tot je het expliciet untrack. .gitignore achteraf bewerken verandert niets aan tracked bestanden — daarom verscheept de klassieke reeks ‘commit .env, paniek, .env aan .gitignore toevoegen, opnieuw committen’ het geheim bij elke push.

Dit bijt iedereen, omdat git bijna universeel is — de Stack Overflow-enquête van 2022 zette Git-gebruik op ruim 93% van professionele developers (survey.stackoverflow.co) — en elk van die developers schrijft ooit een regel voor een bestand dat vorige week gecommit werd.

De rest van dit bericht behandelt de minderheidsgevallen: fouten in regelvolgorde, negatievalkuilen, maprandgevallen en de IDE-vraag. Maar draai eerst de gezondheidscheck in de volgende sectie — negen van de tien keer eindigt daar het onderzoek.

Hoe zie ik welke gitignore-regel op een bestand matcht?

git check-ignore is het diagnostische gereedschap en zijn stilte is de diagnose:

# Prints the matching rule + file + line number when a rule applies
git check-ignore -v debug.log
# .gitignore:3:*.log    debug.log

# Prints NOTHING when no rule applies — the file is tracked (or no rule exists)
git check-ignore -v src/.env
# (silence = .gitignore is not ignoring this path, whatever you wrote)

# Exit codes: 0 = ignored, 1 = not ignored — scriptable
git check-ignore -q debug.log && echo "ignored" || echo "tracked or unruly"

Uitlezing van -v-output: de ignore-bron (.gitignore, .git/info/exclude, of je globale ignore-file), dan line-number:pattern, dan het pad. Verrast een latere regel je, onthoud de prioriteit: de laatst matchende regel wint, dus !important.log na *.log neemt dat ene bestand weer op.

Waarom werkt gitignore niet voor al gecommitte bestanden?

Untrack het bestand, houd het op schijf, commit de verwijdering:

# 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

Vanaf deze commit is .gitignore eigenaar van het pad: bewerkingen tonen niet meer in git status en git add . pakt het niet opnieuw op. Het bestand zit wél in de geschiedenis — was het een geheim, dan is het uit de laatste commit halen niet genoeg. Het credential roteren is de enige echte fix; geschiedenis herschrijven is de cosmetische (en de laatste commit ongedaan maken helpt alleen zolang de slechte commit nog de tip is).

Voor een repo vol eerder gecommitte rommel — build-output, editor-achterlatingen, node_modules dat vroeg binnenkroop — is de bulk-untrack een tweeregeliger:

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

Dit herbouwt de index tegen de huidige regels: genegeerde paden vallen eruit, al het restereden wordt onveranderd opnieuw toegevoegd. De diff oogt dramatisch (duizenden verwijderingen) maar verwijdert niets van schijf. Is je doel die bestanden écht verwijderen in plaats van alleen untracken, dan is dat git clean -fdx-gebied — zie untracked git-bestanden verwijderen, veilig.

Git negeert bestanden die het nooit zag. Een bestand dat al in de index zit is immuun voor .gitignore — geen enkele regel die je schrijft maakt het vergeten.

Waarom werkt gitignore niet voor een map?

Drie mapspecifieke valkuilen:

1. Schuine strepen achteraan zeggen iets over intentie, niet over matchen. build en build/ matchen allebei een map, maar build/ documenteert dat je een map bedoelt — een bestand genaamd build zou het overleven. De symmetrie faalt wel bij heropname (volgende valkuil).

2. Negatie kan bestanden in een uitgesloten map niet redden. De git-documenten zijn ondubbelzinnig: ‘Het is niet mogelijk een bestand opnieuw op te nemen als een bovenliggende map ervan uitgesloten is’ (git-scm.com/docs/gitignore). Dit is een performancebesluit — git slaat uitgesloten mappen geheel over in plaats van ze te doorlopen. Dus dit werkt niet:

build/
!build/keep.me        # dead rule — git never looks inside build/

De fix is de inhoud uitsluiten, niet de map:

build/*
!build/keep.me        # works — build/ itself is still open for inspection

3. Geneste .gitignore-bestanden winnen binnen hun bereik. Regels in subdir/.gitignore overrulen het hoofdbestand voor paden onder subdir. Noemt git check-ignore -v een ignore-bron die je niet verwachtte, dan ligt dat meestal hieraan.

Waarom werkt gitignore niet in VS Code?

Vrijwel nooit om VS Code-redenen. De Source Control-view leest dezelfde index als git, dus het symptoom is identiek: het bestand was al gecommit en geen IDE-herstart verandert de index. Twee VS Code-adjacente realiteiten die je moet kennen:

  • Grijs in de Explorer = genegeerd; oranje/geel = tracked met wijzigingen. Een bestand dat nog als gewijzigd staat nadat je het negeerde, is je bevestiging dat het tracked is — draai de git rm --cached-fix hierboven.
  • Een ontbrekend .gitignore in de changed-lijst van de Explorer betekent dat de regel werkt — het verschijnt nooit als untracked bestand. Mensen melden vaak ‘VS Code negeert mijn gitignore’ terwijl de CLI-git status het niet eens is met een verouderde SCM-view; herlaad het venster (Cmd/Ctrl+Shift+P → ‘Reload Window’) voordat je git de schuld geeft.

.gitignore vs .git/info/exclude vs globaal: welke wanneer?

BestandBereikGecommit?Bedoeld voor
.gitignore (repo)Iedereen die clonetJaBuild-output, dependencies, .env — gedeelde regels
.git/info/excludeAlleen jouw cloneNeePersoonlijke rommel: .scratch/, editor-achterlatingen
core.excludesFile (globaal)Al je repo’sNeeOS-junk: .DS_Store, Thumbs.db, *.swp
.gitignore + negatieRepoJaUitzonderingen opnieuw opnemen voor tracked-config

Het globale bestand is degene die de meeste developers nooit zetten en zouden moeten:

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

Huisregel om over te nemen: helpt een regel het hele team, dan hoort hij in de repo; helpt hij alleen jou, dan hoort hij in exclude of het globale bestand. Persoonlijke ignore-regels committen is hoe .gitignore-bestanden 300 regels worden en niemand meer weet welke helft telt.

Hoe negeer ik wijzigingen aan een tracked bestand?

Soms wil je een tracked bestand (een config-template, een IDE-instellingenbestand) maar willen lokale bewerkingen niet meer in git status opduiken. Twee flags op git update-index, die geen van beide in een teamworkflow thuishoort:

git update-index --skip-worktree config/local.dev   # local edits go quiet
git update-index --no-skip-worktree config/local.dev  # ...and back

--skip-worktree is de verdedigbare — hij zegt ‘mijn lokale versie wijkt bewust af’. Zijn neef --assume-unchanged is een performancebelofte (‘dit bestand verandert niet’), geen ignore-mechanisme, en git kan hem stilletjes breken. Beide flags falen luid bij pull als upstream het bestand ook veranderde — de duurzame antwoorden zijn een local-only config via exclude bij aanmaak, of een template (config.example) die git volgt en jij kopieert.

De gezondheidscheck van 30 seconden

git check-ignore -v <path>        # which rule? (silence = tracked, no rule)
git ls-files --error-unmatch <path>  # is it tracked at all?
git rm --cached <path>            # untrack, keep on disk
git commit -m "stop tracking <path>"
git check-ignore -v <path>        # rule now shows

Diagnose, untrack, verifiëren. Het patroon achter elk ‘gitignore werkt niet’-rapport is hetzelfde bestand met twee hoeden — tracked aan de ene kant van de index, genegeerd aan de andere — en één --cached-flag haalt de tweede hoed af.

FAQ

Waarom werkt .gitignore niet?

In de meeste gevallen wordt het bestand al gevolgd. Git negeert alleen untracked bestanden; een bestand in de index is immuun voor .gitignore tot je het untrack met git rm --cached en commit.

Hoe zie ik welke gitignore-regel op een bestand matcht?

Draai git check-ignore -v <path>. Het print de exacte .gitignore-regel en het regelnummer, of eindigt stil wanneer het bestand tracked is en geen regel geldt.

Verwijdert git rm --cached mijn lokale bestand?

Nee. --cached haalt het bestand alleen uit de index; de kopie op schijf blijft staan. Commit de verwijdering en het bestand wordt untracked, waarna .gitignore geldt.

Waarom kan gitignore een bestand in een genegeerde map niet opnieuw opnemen?

Git slaat uitgesloten mappen geheel over voor performance. Volgens de git-documenten is het onmogelijk een bestand opnieuw op te nemen als een bovenliggende map ervan uitgesloten is.

— mrsaynothing

— mrsaynothing

Veldnotities over AI, Linux en self-hosting.

Bespreek deze post op dev.to dev.to ↗

De volgende how-to per e-mail

Eén e-mail per post. Fix het en ga door.

self-hosted · geen derden · uitschrijven met één klik

wat is dit?

Ollama gebruikt je GPU niet? Fix het op Linux, Windows en WSL

Schrijf je dit met plezier? Dit bouw ik professioneel. huur me in