Cómo usar .gitignore: qué es y qué ignorar en Git
Guía junior para usar .gitignore: sintaxis de patrones, qué ignorar siempre y por qué tu .env sigue apareciendo aunque ya lo añadiste.
Instalas las dependencias de tu primer proyecto de verdad, ejecutas git status y Git te muestra de golpe miles de archivos que tú no has escrito: la carpeta node_modules entera. Si los subes al repositorio, cometes uno de los errores más comunes de novato, y tiene consecuencias reales: repos que pesan cientos de megas, merges imposibles y, en el peor caso, una clave secreta filtrada. Para evitar todo eso existe .gitignore. Doy por hecho que ya sabes hacer git add, git commit y git push; si aún no, empieza por los primeros pasos con Git y vuelve luego.
¿Qué es un archivo .gitignore?
.gitignore es un archivo de texto que colocas en la raíz de tu repositorio y que contiene una lista de patrones. Cuando un archivo o una carpeta coincide con uno de esos patrones, Git lo salta al calcular qué hay para comitear: no aparece en git status y no se puede añadir con git add por accidente. Es la lista de “aquí no mires” que le pasas a Git para que deje de molestarte con el ruido (cosas que se regeneran solas o que no deben salir de tu máquina).
Hay un matiz que es la raíz de casi toda la confusión con esta herramienta, y conviene decirlo ya: .gitignore solo tiene efecto sobre archivos que Git todavía no rastrea [1]. Un archivo que ya está bajo control de versiones (porque en algún momento hiciste git add y lo comiteaste) sigue rastreándose aunque después lo metas en .gitignore. Volveremos a esto, porque es donde más gente se atasca.
¿Cómo funciona la sintaxis de .gitignore?
La regla base es sencilla: un patrón por línea. Cada línea describe qué archivos ignorar, y hay unos pocos símbolos que cambian el comportamiento del patrón [1]. Estos son los que vas a usar casi siempre:
- Una línea normal (
config.local.js) ignora cualquier archivo con ese nombre. - El asterisco
*es un comodín que coincide con cualquier cosa menos con la barra/. Así,*.logignora todos los archivos que terminen en.log. - Una barra final
/limita el patrón a carpetas.build/ignora la carpetabuildy todo lo que hay dentro, pero no un archivo suelto llamadobuild. - Una línea que empieza por
#es un comentario. Git la ignora entera, y te sirve para dejar notas a tu yo del futuro. - Una barra inicial
/ancla el patrón a la raíz del repositorio./config.local.jssolo coincide con ese archivo si está en la raíz, no con uno igual dentro de una subcarpeta. - El signo
!niega un patrón anterior: vuelve a incluir algo que una línea previa había excluido.
Con eso ya puedes escribir un .gitignore decente para un proyecto Node. Este cubre los casos típicos, comentado línea a línea:
# Dependencias: se reinstalan con "npm install", no van al repo
node_modules/
# Artefactos de build: se regeneran al compilar
dist/
# Variables de entorno y secretos: NUNCA se suben
.env
# Todos los logs
*.log
# Archivo del sistema que crea macOS en cada carpeta
.DS_Store
El caso de la negación merece un ejemplo aparte, porque es el que menos gente entiende. Imagina que quieres ignorar todos los logs menos uno concreto que sí te interesa versionar:
# Ignora todos los archivos .log...
*.log
# ...pero mantén este bajo control de versiones
!important.log
El orden importa: la regla ! tiene que ir después del patrón que la excluyó. Y ojo con un límite de Git: si has ignorado una carpeta entera, no puedes volver a incluir un archivo de dentro con !, porque Git ni siquiera entra a mirar esa carpeta [1].
Para que veas de un vistazo cómo se comporta cada patrón, esta tabla resume los ejemplos anteriores:
| Patrón | Qué coincide |
|---|---|
node_modules/ | La carpeta node_modules y absolutamente todo su contenido, esté donde esté en el proyecto |
*.log | Cualquier archivo terminado en .log (error.log, debug.log, npm-debug.log) |
/config.local.js | Solo config.local.js en la raíz del repo; un config.local.js dentro de src/ no se ignora |
build/ | La carpeta build completa |
!keep.txt | Vuelve a incluir keep.txt aunque una línea anterior lo hubiera ignorado |
¿Qué deberías ignorar siempre?
Hay cuatro categorías de archivos que casi ningún proyecto quiere en el repositorio. Aprendértelas de memoria te ahorra pensar cada vez.
Las dependencias son la primera y la más ruidosa. En Node es la carpeta node_modules/, que puede tener decenas de miles de archivos. No los versionas porque cualquiera puede regenerarlos con npm install a partir de tu package.json.
Los artefactos de build son la segunda. Cuando compilas, el resultado suele acabar en carpetas como dist/ o build/. Es código derivado del tuyo que se regenera al volver a compilar, así que no aporta nada guardarlo.
La tercera categoría es la importante de verdad: los secretos. El caso típico es un archivo .env con claves de API, contraseñas de base de datos o tokens. Eso no puede salir de tu máquina bajo ningún concepto, y por eso la primera línea que escribo en cualquier .gitignore nuevo es .env.
Y la cuarta son los archivos del sistema y del editor: .DS_Store que crea macOS en cada carpeta, o la carpeta .vscode/ con la configuración personal de tu editor. No son de nadie más del equipo, así que fuera.
¿Por qué nunca debes comitear secretos?
Un secreto que entra en un commit se queda en el historial de Git para siempre, aunque lo borres en el commit siguiente. Esto no es un fallo de configuración: es cómo funciona Git por diseño. Cada commit guarda una foto del proyecto en ese instante, y esas fotos antiguas no desaparecen porque tú edites el archivo hoy.
Ese es el detalle que casi nadie ve venir. Borras la clave de tu .env, haces un commit nuevo y crees que ya está a salvo. Pero cualquiera con acceso al repositorio puede viajar a un commit antiguo y leer la clave tal cual la escribiste. Si el repo es público en GitHub, hay bots rastreando exactamente eso.
Cuando expones una credencial, editar el archivo no basta. La única solución fiable es rotar la clave: entras en el panel del servicio (tu proveedor de base de datos, tu pasarela de pago, lo que sea), invalidas la clave filtrada y generas una nueva. A partir de ese momento, la que quedó en el historial ya no abre ninguna puerta. Existen herramientas para reescribir el historial, pero son delicadas y no te salvan si alguien ya copió la clave. Rotar la clave es lo único que cierra el agujero.
”Lo añadí a .gitignore pero sigue apareciendo”
Si un archivo sigue apareciendo en git status después de meterlo en .gitignore, es porque Git ya lo estaba rastreando antes de que escribieras la regla. Y .gitignore no toca los archivos que ya se rastrean, solo evita que empiecen a rastrearse los nuevos.
El ejemplo clásico: creaste el proyecto, hiciste git add . sin pensar, y con ese punto añadiste tu .env al índice. Días después te das cuenta y lo añades al .gitignore. No pasa nada: Git sigue rastreándolo porque ya lo tenía fichado.
La solución es sacarlo del índice de Git sin borrarlo de tu disco, y eso es justo lo que hace git rm --cached. El flag --cached le dice a Git que quite el archivo solo del índice y deje intacta la copia que tienes en tu carpeta [2]:
# Saca .env del índice de Git, pero NO lo borra de tu disco
git rm --cached .env
# Confirma el cambio: a partir de aquí Git deja de rastrear .env
git commit -m "Deja de rastrear .env"
Tras ese git rm --cached, Git deja de seguir el archivo y, como ahora coincide con la regla del .gitignore, ya sí queda ignorado. Tu .env sigue en tu máquina funcionando como siempre; lo único que cambia es que Git ya no lo mira. Y recuerda: si ese .env llegó a subirse a un remoto en algún commit anterior, sacarlo del índice hoy no lo borra del historial. Ahí vuelve a aplicar lo de rotar la clave.
Antes de seguir, prueba tú mismo la lógica de qué ignora Git y qué no. Este ejercicio interactivo te deja practicar el caso del archivo ya rastreado sin tocar tu propio repositorio:
Cargando ejercicio...
¿Dónde consigo un .gitignore para mi proyecto?
No hace falta escribirlo desde cero. GitHub mantiene una colección oficial de plantillas por lenguaje y framework en su repositorio github/gitignore [3]. Buscas la de Node, Python, o lo que uses, y copias su contenido: vienen con los patrones típicos ya pensados por gente que se ha tropezado con todos los casos raros antes que tú. Además, herramientas como create-next-app o Vite te generan uno razonable de serie al crear el proyecto. Empieza con una plantilla oficial y añade tus líneas propias encima según las vayas necesitando.
Errores comunes
Comitear node_modules
Es el error de novato por excelencia. El repo pasa de pesar unos kilobytes a decenas de megas, los clones tardan una eternidad y, cuando dos personas actualizan dependencias a la vez, Git intenta hacer merge de miles de archivos generados y salen conflictos absurdos que no significan nada. La regla node_modules/ en la primera línea del .gitignore te ahorra todo eso.
Creer que .env ya está a salvo por estar en .gitignore
Si comiteaste el .env antes de ignorarlo, la regla no lo protege: Git lo sigue rastreando. Necesitas git rm --cached .env y, si la clave llegó a un remoto, rotarla. Editar .gitignore nunca limpia lo que Git ya seguía; el archivo solo actúa hacia adelante, sobre lo que aún no se rastrea.
Usar rutas absolutas de tu máquina
Un patrón como /Users/sofia/proyecto/.env no funciona: Git interpreta la barra inicial como la raíz del repositorio, no de tu disco. Los patrones son relativos al repo y se comparten con todo el equipo, así que una ruta de tu ordenador no le sirve a nadie más. Escribe siempre patrones relativos, como .env o config/local.json.
Complicar el patrón sin necesidad
Para ignorar tu .env, la línea .env ya lo hace. A veces se ve gente poniendo *.env pensando que es “más seguro”. El comodín también coge .env, sí, pero además captura production.env, test.env y cualquier otro, lo que puede que no sea lo que quieres. Si solo tienes un archivo, el patrón sin comodín es más claro para quien venga detrás.
Checklist rápido
- El
.gitignoreestá en la raíz del repositorio -
node_modules/y las carpetas de build (dist/,build/) están ignoradas -
.envy cualquier archivo con secretos aparecen en el.gitignore - Los archivos que ya rastreabas por error los has sacado con
git rm --cached - Ninguna clave que se haya subido sigue activa (la has rotado)
- Los patrones son relativos, sin rutas absolutas de tu máquina
Si quieres coger soltura con esto sin miedo a romper nada, el curso Git de cero a profesional te lleva por el flujo completo (staging, commits, ramas y un .gitignore bien puesto) con ejercicios guiados donde practicas cada comando en un repositorio de mentira antes de aplicarlo en el tuyo.
Fuentes
- Documentación oficial de Git: gitignore: sintaxis de patrones (comodines, negación, anclaje, barra final) y el hecho de que los archivos ya rastreados no se ven afectados.
- Documentación oficial de Git: git rm: el flag
--cachedquita el archivo solo del índice y deja intacta la copia del disco. - Colección oficial de plantillas de .gitignore (GitHub): plantillas por lenguaje y framework listas para copiar.
Preguntas Frecuentes
¿.gitignore distingue mayúsculas de minúsculas?
Por defecto sí: Config.js y config.js se tratan como patrones distintos. La excepción es que en sistemas de archivos que no distinguen mayúsculas (los de macOS y Windows suelen venir así de fábrica) el resultado puede variar según tu configuración de Git. Para no llevarte sorpresas, escribe el patrón exactamente igual que el nombre real del archivo.
¿Puedo tener varios .gitignore en un mismo repo?
Sí. Puedes poner un .gitignore en cualquier subcarpeta, y sus reglas aplican a esa carpeta y a lo que hay debajo. Las reglas de una carpeta más profunda pueden anular las de una superior. En proyectos pequeños te basta con uno en la raíz, pero es útil saber que la opción existe cuando una parte concreta del proyecto necesita reglas propias.
¿Cómo compruebo por qué un archivo está siendo ignorado?
Con git check-ignore -v <archivo>. Ese comando te dice qué regla exacta está ignorando el archivo, e incluso en qué .gitignore y en qué número de línea está esa regla. Por ejemplo, git check-ignore -v app.log te devolvería algo como .gitignore:4:*.log app.log. Es la forma más rápida de depurar cuando un patrón no hace lo que esperabas.
¿El .gitignore se sube al repo?
Sí, y debe subirse. El propio .gitignore es un archivo más que se versiona con git add y git commit, para que todo el equipo comparta las mismas reglas. El archivo que no se sube es tu .env, no el .gitignore.
Ya subí un secreto, ¿basta con borrarlo en el siguiente commit?
No. Borrar el archivo en un commit nuevo no lo elimina del historial: cualquiera puede recuperar la versión antigua y leer la clave. Lo único que de verdad cierra el problema es rotar la credencial, es decir, invalidar la clave expuesta y generar una nueva en el panel del servicio afectado.
¿Te ha resultado útil? Suscríbete y te aviso cuando publique guías nuevas de Git y de cómo dirigir la IA con criterio técnico.