Idioma:Español
HERRAMIENTA DEV

Gitignore Debugger

Descubre exactamente por qué Git no ignora tu archivo.

Pega una ruta de archivo y tus reglas .gitignore. Te mostramos qué regla coincide, y por qué.

Todo se ejecuta en tu navegador. Tus archivos nunca se envían.

¿Qué es un archivo .gitignore?

Un archivo .gitignore es un archivo de texto que le dice a Git qué archivos dejar fuera del control de versiones. Cada línea es un patrón — *.log, node_modules/, .env — y cualquier ruta sin seguimiento que coincida con un patrón desaparece de git status, es omitida por git add . y nunca se confirma.

La expresión sin seguimiento carga con casi todo el significado de esa frase, y por sí sola explica más casos de «gitignore no funciona» que todos los errores de patrón juntos. Git solo consulta .gitignore para archivos a los que aún no hace seguimiento. En cuanto un archivo se ha confirmado, Git sigue rastreándolo indefinidamente, por mucho que añadas después a .gitignore.

Qué hace el Gitignore Debugger

Pega una ruta de archivo y el contenido de tu .gitignore: este depurador de .gitignore emite el mismo veredicto que Git —ignorado o no ignorado— junto con la regla exacta y el número de línea responsables. Después enumera todas las reglas que coinciden con la ruta, en el orden en que Git las evalúa, y señala la que realmente decidió.

Esa última parte es la que un simple comprobador de gitignore deja fuera. Saber que un archivo está ignorado rara vez es lo difícil. Saber cuál de tus cuarenta reglas lo hizo —y por qué perdió la que esperabas— sí lo es. Funciona en ambos sentidos: por qué Git ignora tu archivo cuando quieres confirmarlo, y por qué no ignora el que quieres quitar de en medio.

El motor reimplementa las reglas de coincidencia de patrones de Git: patrones por nombre base frente a anclados, * que nunca cruza una /, las tres formas de **, los sufijos / solo para directorios, las clases de caracteres, los espacios finales escapados. Su comportamiento se verifica contra la salida real de git check-ignore, no se supone.

Cómo usarlo

  1. Introduce la ruta tal como aparece en tu repositorio, relativa a la raíz — src/config/local.json, no C:\projects\app\src\config\local.json. Usa barras inclinadas; las barras invertidas de Windows se convierten por ti.
  2. Pega todo tu .gitignore. No lo reduzcas a la única regla que sospechas: la precedencia entre reglas suele ser el error real, y recortar el archivo tira esa información a la basura.
  3. Lee el veredicto y luego la cadena de reglas que hay debajo. Ahí es donde una regla de gitignore que no funciona deja de ser un misterio.

Para probar reglas de gitignore sobre un directorio en lugar de un archivo, termina la ruta con una barra inclinada — build/. La distinción importa, porque una regla que termina en / solo coincide con directorios.

Por qué las reglas de gitignore a veces no funcionan

Los culpables, más o menos por orden de frecuencia:

Precedencia de reglas en gitignore: gana la última coincidencia

Esta es la que pilla a todo el mundo. Dentro de un mismo .gitignore, el último patrón que coincide con una ruta decide su destino, no el primero. Estos dos archivos contienen reglas idénticas y dan resultados opuestos para important.log:

*.log
!important.log        → important.log se guarda en Git
!important.log
*.log                 → important.log se ignora

Así que pon primero las reglas amplias y después las excepciones. Entre archivos, un .gitignore situado en un subdirectorio gana a otro más arriba para las rutas que están por debajo. Git también lee .git/info/exclude, propio del repositorio y nunca confirmado, y tu core.excludesFile global. Una regla que no encuentras en ningún .gitignore a menudo se esconde en uno de esos dos sitios: git check-ignore -v muestra el archivo y la línea que decidieron.

Reglas de negación, y por qué ! falla tan a menudo

Poner ! delante de un patrón vuelve a incluir algo que una regla anterior había ignorado. Tiene dos límites, y el segundo explica casi todos los casos de «la negación de gitignore no funciona».

Primero, algo anterior tiene que haber ignorado la ruta. !important.log por sí solo no hace nada, porque nunca hubo nada que anular.

Segundo, y bastante más sorprendente: no puedes volver a incluir un archivo que está dentro de un directorio ignorado. Esto no funciona, y ningún reordenamiento lo arregla:

build/
!build/keep.txt

Cuando build/ está ignorado, Git nunca entra. No examina build/keep.txt, así que nunca llega a la línea 2. Ignora en su lugar el contenido del directorio, lo que deja el directorio en sí recorrible:

build/*
!build/keep.txt

Para rescatar algo más profundo, cada directorio intermedio también tiene que seguir siendo accesible — build/*, luego !build/assets/, luego !build/assets/logo.svg.

Directorios padre ignorados

El recorrido de directorios de Git se detiene en el primer directorio ignorado que encuentra, y todo lo que hay debajo hereda el veredicto sin ser examinado. Por eso un padre ignorado gana a cualquier regla escrita para el archivo en sí, por específica que parezca.

En ese caso el depurador nombra al padre que bloqueó el recorrido en lugar de decir simplemente que el archivo está ignorado, y sigue mostrando las reglas de negación que escribiste para el archivo, marcadas como inalcanzables, porque Git nunca llegó lo bastante lejos para tenerlas en cuenta. Arregla primero el directorio y las reglas de debajo vuelven a funcionar por sí solas.

Errores comunes de .gitignore

Unos cuantos ejemplos reales

La ruta src/logs/debug.log frente a estas reglas no está ignorada. La negación es la última coincidencia y ningún directorio padre bloquea el recorrido, así que se alcanza y gana:

*.log
!src/logs/debug.log

La ruta build/keep.txt frente a estas reglas sí está ignorada, por build/ en la línea 1, que coincide con el directorio padre. La línea 2 nunca se activa:

build/
!build/keep.txt

La ruta docs/api/notes.md frente a esta regla no está ignorada, porque el patrón está anclado por su barra inclinada y * no cruzará la de api/notes.md. Lo que se quería era docs/**/*.md:

docs/*.md

Pega cualquiera de estos ejemplos en el probador de gitignore de arriba para ver la cadena completa de reglas. De vuelta en la terminal, git check-ignore -v path/to/file es el equivalente integrado: nombra el archivo de origen, el número de línea y el patrón que decidieron, y merece la pena conocerlo.

Preguntas frecuentes

¿Por qué Git ignora mi archivo?

Algún patrón coincide con él, y a menudo no es el que estás mirando. Los culpables habituales son un .gitignore en un subdirectorio, un directorio padre ignorado o tu archivo de exclusión global. Ejecuta git check-ignore -v path/to/file: imprime exactamente el archivo de origen, el número de línea y el patrón que decidieron. Pegar la ruta y las reglas en el depurador de arriba muestra lo mismo, más las reglas que coincidían y perdieron.

¿Por qué no funciona mi regla de .gitignore?

Cuatro causas cubren casi todos los casos, más o menos por orden de frecuencia: el archivo ya tiene seguimiento, así que la regla se omite por completo; una regla posterior la anuló, porque gana la última coincidencia; un directorio padre está ignorado, así que Git nunca llegó a la regla; o el patrón está anclado de otra forma de la que creías — una barra inclinada en cualquier posición que no sea el final ancla un patrón al directorio que contiene el .gitignore.

¿Por qué ! no vuelve a incluir mi archivo?

O bien nada anterior había ignorado la ruta, y por tanto la negación no tenía nada que anular, o bien —mucho más probable— el archivo está dentro de un directorio ignorado. Git no entra en los directorios ignorados, así que nunca ve el archivo y nunca evalúa tu regla !.

Ignora el contenido del directorio en lugar del directorio mismo: cambia build/ por build/*, mantén !build/keep.txt después y la negación se alcanza.

¿Gana la última regla de .gitignore?

Sí. Dentro de un archivo, el último patrón que coincide con una ruta decide su destino: no el primero ni el más específico. *.log seguido de !important.log conserva important.log; intercambia esas dos líneas y queda ignorado. Pon primero las reglas amplias y después las excepciones.

¿Por qué una carpeta ignorada impide que funcione una regla de negación?

Porque el recorrido de directorios de Git se detiene en el primer directorio ignorado. Cuando build/ coincide, Git marca todo el subárbol como ignorado sin listar lo que hay dentro, así que !build/keep.txt no queda anulado: simplemente nunca se alcanza. Reordenar no cambia nada; lo único que cambia algo es volver a hacer el directorio recorrible, y eso es lo que hace build/*.

¿Cómo pruebo una regla de .gitignore?

Pega la ruta del archivo y tus reglas en el depurador que hay al principio de esta página. Te da el veredicto, la regla y la línea decisivas, y todas las reglas que coincidieron por el camino, incluidas las negaciones que nunca podrían haber surtido efecto.

En un repositorio real, git check-ignore -v path/to/file nombra el archivo de origen, la línea y el patrón responsables, y git status --ignored enumera todo lo que está ignorado ahora mismo.

¿Afecta .gitignore a los archivos que ya tienen seguimiento?

No. .gitignore solo se aplica a rutas sin seguimiento. En cuanto un archivo se ha confirmado, Git sigue rastreándolo y la regla se omite: es la razón más frecuente por la que una regla perfectamente correcta parece no hacer nada. Para dejar de seguir un archivo sin borrarlo, ejecuta git rm --cached path/to/file y confirma ese cambio.

Un detalle que despista: git check-ignore seguirá informando de una coincidencia para un archivo con seguimiento, porque prueba los patrones sin consultar el índice. Un «sí, ignorado» de ese comando no significa que Git haya dejado de seguir el archivo.

¿Pueden las reglas de .gitignore contener espacios?

Sí, en el medio. my logs/ coincide con un directorio cuyo nombre contiene un espacio, sin necesidad de escaparlo. Los espacios finales son otra historia: Git los recorta, así que *.log seguido de un espacio se comporta exactamente igual que *.log. Para coincidir con un nombre de archivo que realmente acaba en espacio, escápalo — foo\ .

Los espacios iniciales sí son significativos y nunca se recortan, así que una regla indentada por accidente solo coincide con rutas que empiezan por ese espacio. Si una regla parece inerte sin motivo, comprueba que no tenga sangría de más.

¿Dónde busca Git reglas de exclusión aparte de .gitignore?

En tres sitios más, consultados en este orden de precedencia: los propios archivos .gitignore, donde gana el directorio más profundo; luego .git/info/exclude, propio del repositorio y nunca confirmado; luego lo que apunte core.excludesFile, tu lista de exclusión global.

Así que una regla que no encuentras en ninguna parte del repositorio suele estar en uno de esos dos últimos. git config --get core.excludesFile revela la ruta global, y git check-ignore -v nombra el archivo que realmente decidió.

¿Cuál es la diferencia entre * y **?

* coincide con cualquier secuencia de caracteres excepto /, así que nunca sale de un único segmento de ruta. src/*/test.js baja exactamente un nivel.

** cruza separadores, pero solo en las tres posiciones que Git reconoce: un **/ inicial para cualquier profundidad, un /** final para todo lo que hay dentro de un directorio y /**/ en el medio para cero o más directorios. En cualquier otro sitio, como en a**b, los asteriscos extra se comportan como un solo *.