Probador de .gitignore
Un .gitignore es una lista ordenada de patrones y gana el ÚLTIMO que coincide con una ruta, así que la respuesta a «¿por qué se ignora este archivo?» casi nunca está en la línea que estás mirando. Esta herramienta toma el archivo y una lista de rutas y responde como lo hace `git check-ignore -v`: para cada ruta, el veredicto, el número de línea y el texto del patrón que decidió, más el directorio padre cuando la decisión vino de él y no del archivo. Ahí vive la mayoría de los errores de .gitignore. Git nunca entra en un directorio excluido, de modo que en cuanto `build/` queda ignorado, `!build/keep.txt` es texto muerto: el archivo se juzga a través de su padre y la negación ni siquiera se consulta. La herramienta señala ese caso en lugar de dejarte adivinar, y además enumera las reglas que no coincidieron con ninguna de las rutas pegadas, que es como sale a la luz un Thumbs.db heredado o un coverage/ que renombraste hace años. La comparación sigue la lectura del formato que hace git y no un glob de shell: un patrón sin barras se compara con el nombre base a cualquier profundidad; uno con barra queda anclado al directorio que contiene el .gitignore; una barra final lo limita a directorios; `*` se detiene en la barra mientras que un `**` que ocupa un segmento entero la cruza; funcionan las clases de caracteres como [0-9] y [!a-z]; los espacios finales se descartan salvo que los escapes con una barra invertida; se pueden escapar el # y el ! iniciales, y se eliminan la marca BOM y los finales de línea CRLF antes de analizar nada. Como una lista pegada de rutas no lleva tipos, marca los directorios con una barra final: `build/` se juzga como directorio y `build` como archivo, y solo eso invierte la respuesta de cualquier regla de directorio. Dos cosas que no puede decirte. Lee un único .gitignore, así que los archivos por directorio más abajo en el árbol, .git/info/exclude y el global de core.excludesFile quedan fuera, y cualquiera de ellos puede cambiar lo que ves aquí. Y compara distinguiendo mayúsculas, como git en Linux, por lo que un repositorio con core.ignorecase en macOS o Windows puede ignorar más de lo que muestra esta tabla. Todo se ejecuta en el navegador: ni el archivo ni las rutas se suben a ningún sitio.
Ignoradas
5
No ignoradas
3
Reglas
7
Reglas muertas
1
Git no entra en un directorio excluido, así que una regla ! por debajo nunca se consulta. Excluye el contenido (dir/*) en lugar del directorio (dir/) para que surta efecto.
- .vscode/settings.json — !.vscode/settings.json (Línea 10) · por el padre excluido .vscode/
| Ruta | Veredicto | Línea | Regla decisiva |
|---|---|---|---|
| src/index.ts | No ignorada | — | Ninguna regla coincide |
| node_modules/react/index.js | Ignorada | 2 | node_modules/por el padre excluido node_modules/ |
| dist/ | Ignorada | 3 | dist/ |
| dist/app.js | Ignorada | 3 | dist/por el padre excluido dist/ |
| debug.log | No ignorada | 6 | !debug.log |
| logs/debug.log | No ignorada | 6 | !debug.log |
| server.log | Ignorada | 5 | *.log |
| .vscode/settings.json | Ignorada | 9 | .vscode/por el padre excluido .vscode/esta regla ! no puede surtir efecto |
Ninguna de las rutas de arriba coincide con estas líneas. Con una lista representativa, son candidatas a borrarse.
- Línea 4 coverage/
La comparación sigue a git en un sistema de archivos sensible a mayúsculas, con un único .gitignore en la raíz.
Cómo usar
- Pega tu .gitignore en el primer recuadro tal como está en el disco: los comentarios, las líneas en blanco, los finales CRLF y la marca BOM se tratan como los trata git.
- Escribe en el segundo recuadro las rutas que quieres probar, una por línea y relativas a la raíz del repositorio. Termina la línea con una barra para indicar que es un directorio: de eso dependen las reglas como `logs/`.
- Lee la tabla. Cada fila da el veredicto, el número de línea que decidió y el texto de la regla, los mismos tres datos que imprime `git check-ignore -v`, más el padre excluido si lo hay.
- Revisa el aviso ámbar. Aparece cuando una regla `!` coincide con una ruta pero no puede surtir efecto porque un directorio padre ya está excluido, el motivo habitual de que una negación parezca correcta y no haga nada.
- Mira la lista de reglas muertas al final: las que no coincidieron con ninguna ruta pegada. Con una lista de rutas representativa, son las líneas que conviene borrar.
Preguntas frecuentes
- ¿Por qué mi regla ! no recupera el archivo?
- Porque git nunca llegó a mirar el archivo. Cuando recorre el árbol y descubre que un directorio está excluido, se detiene ahí y no entra, así que ninguna regla sobre algo de dentro llega a evaluarse; la documentación lo dice sin rodeos: no es posible volver a incluir un archivo si un directorio padre suyo está excluido. Con `logs/` y `!logs/important.log`, el registro sigue ignorado, y esta herramienta muestra que la decisión viene de la regla del directorio. La solución es excluir el contenido y no el directorio: `logs/*` seguido de `!logs/important.log` funciona, porque `logs/*` coincide con lo que hay dentro sin excluir logs. Para un subárbol entero la receta es `/logs/**`, luego `!/logs/keep/` y luego `!/logs/keep/**`.
- ¿Qué diferencia hay entre build y /build?
- Un patrón sin ninguna barra se compara con el nombre base de cada ruta, a cualquier profundidad, así que `build` ignora por igual /build, /src/build y /a/b/c/build. En cuanto el patrón contiene una barra que no sea su último carácter, queda anclado al directorio que contiene el .gitignore, de modo que `/build` y `docs/output` solo coinciden desde esa raíz hacia abajo. Por eso un `node_modules` a secas en el .gitignore de la raíz también oculta el node_modules de un paquete anidado: suele ser lo que la gente quiere, pero rara vez lo que escribió a propósito. La barra inicial es la forma de decir «solo aquí».
- ¿`logs/` coincide con un archivo llamado logs?
- No. Una barra final significa que el patrón solo coincide con directorios, así que un archivo normal llamado logs se queda tranquilo mientras que un directorio logs, a cualquier profundidad, se ignora junto con todo su contenido. Esto importa aquí porque una lista pegada de rutas no lleva información de tipo: git decide mirando el sistema de archivos real y a esta herramienta hay que decírselo. Escribe `logs/` para el directorio y `logs` para el archivo; la misma cadena con y sin barra puede recibir veredictos opuestos, y eso no es una rareza de la herramienta sino la razón de que `git check-ignore` sorprenda cuando la ruta todavía no existe.
- ¿Qué significan de verdad las tres formas de **?
- Un `**` solo tiene significado especial cuando ocupa un segmento entero de la ruta. `**/foo` al principio coincide con foo a cualquier profundidad y es la forma explícita de lo que ya hace un patrón sin barras. Un `foo/**` final coincide con todo lo que hay dentro de foo, pero no con foo mismo, que es justamente por lo que funciona la receta de reinclusión. Y `a/**/b` en medio coincide con a/b, a/x/b y a/x/y/b, es decir, con cero o más directorios. En cualquier otra posición son asteriscos corrientes: `a**b` es igual que `a*b`, y un `*` solo nunca cruza una barra, así que `src/*.c` coincide con src/main.c pero no con src/lib/main.c.
- La regla parece correcta, pero git sigue mostrando el archivo como modificado.
- El .gitignore solo se aplica a archivos que git todavía no sigue. Una vez que un archivo se ha confirmado, añadir un patrón no cambia nada: git sigue informando de sus cambios y sigue confirmándolos. Deja de seguirlo primero con `git rm --cached ruta` (que conserva la copia de trabajo) y confirma esa eliminación; a partir del siguiente commit manda la regla de ignorado. Esta herramienta responde a la pregunta sobre archivos no seguidos, la misma que responde `check-ignore`, así que una ruta que aquí sale como ignorada puede seguir apareciendo en `git status` si está en el índice, y eso es lo primero que hay que comprobar cuando ambos discrepan.
- ¿Qué .gitignore gana cuando hay varios?
- Git lee varias fuentes en un orden fijo y gana la más específica: los patrones de la línea de órdenes, después los archivos .gitignore, donde uno de un directorio más profundo sustituye al de arriba, luego .git/info/exclude para reglas locales del repositorio que no se comparten y, por último, el archivo global que nombra core.excludesFile. Dentro de un mismo archivo decide la última línea que coincide. Esta herramienta modela un solo .gitignore, así que si su veredicto no cuadra con tu repositorio, lo más probable es un .gitignore anidado, una entrada de info/exclude o tu archivo global: ejecuta allí `git check-ignore -v` y la columna de origen te dirá qué archivo fue.
Herramientas relacionadas
Probador de EditorConfig
Pega un .editorconfig y unas rutas de archivo: verás las propiedades que resuelve cada archivo y qué sección y línea decidió cada valor.
Generador de .gitignore
Marca lenguajes, frameworks, editores y sistemas operativos que usas — obtén un `.gitignore` combinado listo para soltar en un repo nuevo.
Probador de patrones glob
Prueba rutas de archivo contra un patrón glob (*, **, ?, [...], {a,b}) en tu navegador.
Inspector de módulos WebAssembly
Analiza un .wasm en el navegador: tamaño de cada sección, importaciones y exportaciones con tipos, páginas de memoria y secciones personalizadas.
Validador de JSON Schema
Comprueba un documento JSON contra un JSON Schema en el navegador: cada error trae su JSON Pointer, la línea donde cae y la palabra clave que falló.
Inspector de parches y diffs
Lee un diff unificado o un archivo .patch: archivos tocados, inserciones y eliminaciones por archivo, y los hunks malformados que hacen fallar a git apply.