Si .gitignore «no funciona», un solo mecanismo explica la mayoría de los casos: el archivo se comprometió antes de que existiera la regla. .gitignore no es un filtro que oculta archivos a git — es una regla sobre qué git add captura desde un estado sin rastrear. Una vez que un archivo está en el índice, git rastrea sus cambios de contenido para siempre, hasta que lo saques explícitamente del rastreo. Por eso la secuencia clásica «commit .env, pánico, add .env a .gitignore, commit otra vez» sigue enviando el secreto en cada push.
.gitignore «no funciona» casi siempre significa que el archivo ya está rastreado — un archivo en el índice es inmune a cualquier regla que escribas.
git check-ignore -v <path> lo decide: regla impresa = problema de reglas; silencio = rastreado y sin regla aplicable.
Arreglo: git rm --cached <path>, commit — la regla funciona a partir de ese commit.
Un comando, dos desenlaces — git check-ignore -v te lleva por uno de los dos:
PUERTA 1 · imprime una regla
$ git check-ignore -v debug.log
.gitignore:3:*.log debug.log
hay una regla aplicada — la equivocada, o en el ámbito equivocado. El problema vive en el archivo .gitignore: orden de reglas, trampas de negación, o qué archivo de ignore es dueño de la ruta.
PUERTA 2 · silencio
$ git check-ignore -v src/.env
$ # (nothing — no rule applies)
el archivo está rastreado igualmente. Confírmalo con git ls-files --error-unmatch <path>, luego git rm --cached <path> y haz commit de la eliminación. El silencio es el diagnóstico.
los códigos de salida son scriptables: 0 = ignorado, 1 = no ignorado — git check-ignore -q debug.log && echo ignored || echo tracked-or-unruly
La trampa de la negación, anotada. Por qué !build/keep.me nunca rescata el archivo:
build/ignora el directorio entero — git nunca vuelve a mirar dentro!build/keep.meletra muerta: no puedes re-incluir un archivo dentro de un directorio excluidobuild/*el arreglo — ignora el contenido, no el directorio!build/keep.meahora vivo: la ruta padre es transitable, la excepción aplica*.log luego !important.loggana la última regla que coincide — la negación tras la regla re-incluye ese único archivo| Síntoma | Causa real | Arreglo |
|---|---|---|
El archivo ignorado sigue apareciendo en git status | Comprometido antes de la regla — en el índice | git rm --cached + commit |
git add . lo sigue re-añadiendo | Igual: rastrear gana a ignorar | En masa: git rm -r --cached . → git add . |
!build/keep.me nunca rescata el archivo | Directorio padre excluido — git lo salta entero | build/* + !build/keep.me |
| Una regla posterior aplasta la tuya | Gana la última regla que coincide | Reordena, o lee a la ganadora vía check-ignore -v |
| La regla funciona para tus compañeros, no para ti (o al revés) | .gitignore anidado / exclude / global que no coinciden | Coteja con la tabla de ámbitos de abajo |
| VS Code lo muestra modificado tras ignorarlo | Rastreado — o una vista SCM obsoleta | git rm --cached; recarga la ventana primero |
| Quieres ediciones silenciosas, archivo sigue rastreado | Divergencia local intencionada | git update-index --skip-worktree |
Las reglas pueden vivir en tres sitios, y «funciona para los compañeros, no para mí» casi siempre es un desajuste de ámbito:
.gitignore en el repositorio — comprometido, compartido con todos. Casa por defecto para salidas de build y directorios de dependencias..git/info/exclude — por clon, nunca comprometido. Para tus archivos personales de trabajo en este checkout.core.excludesFile) — por máquina, en todos los repos. La casa clásica de .DS_Store y desechos del editor.Leer check-ignore -v nombra la fuente directamente: el archivo de ignore, luego line-number:pattern, luego la ruta — así, cuando gana una regla sorpresa, la ganadora se identifica.
verificación: 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
A partir de este commit, .gitignore es dueño de la ruta: las ediciones dejan de aparecer en git status, y git add . ya no volverá a capturar el archivo.
Si era un secreto, desrastrear no es el arreglo. El archivo permanece en el historial — quitarlo del último commit no basta. Rotar la credencial es el arreglo real; reescribir el historial es el cosmético.
fin de las dos puertas · nada traído con fetch · todo local