Guía

El archivo .gitignore: cómo excluir archivos de Git y quitar los que ya se añadieron

Actualizado: · Skillaria.Top

El archivo .gitignore en la raíz del repositorio enumera patrones de archivos y carpetas que Git no seguirá: dependencias, builds, logs, secretos. Solo afecta a archivos sin seguimiento, así que un archivo ya incluido en un commit hay que sacarlo del índice con git rm --cached.

El mecanismo de git ignore es la forma de decirle a Git: «no toques estos archivos, no los muestres en git status y no los añadas con git add .». Las reglas se escriben en el archivo de texto .gitignore, que se confirma junto con el proyecto y funciona para todo el equipo. El matiz principal: el ignorado solo afecta a archivos que Git todavía no sigue.

Qué se suele poner en .gitignore

  • Dependencias: node_modules/, vendor/, .venv/; las restaura el gestor de paquetes.
  • Resultados del build: dist/, build/, *.class, __pycache__/.
  • Logs y archivos temporales: *.log, tmp/, *.swp.
  • Secretos y ajustes locales: .env, claves, configuraciones locales.
  • Basura del sistema operativo y los editores: .DS_Store, Thumbs.db, .idea/, aunque es mejor tenerlos en el ignorado global, del que hablamos más abajo.

La regla es sencilla: en el repositorio debe estar lo que escriben las personas, no lo que generan los programas ni lo que depende de una máquina concreta.

Cómo crear un .gitignore

Es un archivo de texto normal en la raíz del repositorio. Créalo, escribe los patrones, uno por línea, y haz commit:

cat > .gitignore <<'EOF'
# dependencias
node_modules/
# build
dist/
# logs
*.log
# secretos
.env
EOF

git add .gitignore
git commit -m "chore: añadido .gitignore"

En el repositorio github/gitignore hay plantillas para los lenguajes y frameworks más populares; GitHub y GitLab te ofrecen elegir una al crear el proyecto. Úsalas como base y quita lo que sobre.

Sintaxis de los patrones de .gitignore

PatrónQué ignora
*.logtodos los archivos .log en cualquier carpeta
build/la carpeta build en cualquier nivel (barra al final = solo carpetas)
/buildsolo build en la raíz (la barra inicial lo ancla a la carpeta del .gitignore)
docs/*.pdflos pdf directamente en docs, pero no en docs/old/
docs/**/*.pdflos pdf en docs y en todas sus subcarpetas
**/temptemp en cualquier carpeta
!keep.logexcepción: no ignorar keep.log
file?.txt?: un carácter cualquiera
[ab].txta.txt o b.txt
# comentariolínea de comentario

Un matiz importante: un patrón sin barra en medio (config.json) se aplica en cualquier nivel, mientras que uno con barra al principio o en medio (/config.json, src/config.json) es relativo a la carpeta donde está ese .gitignore.

Excepciones con el signo de exclamación

*.log
!important.log

La trampa: no se puede «recuperar» un archivo si se ignora su carpeta padre. Git no entra en las carpetas ignoradas, así que esto no funciona:

logs/
!logs/keep.txt     # no funciona

Lo correcto es ignorar el contenido, no la carpeta:

logs/*
!logs/keep.txt

Con este mismo truco se conserva una carpeta vacía en el repositorio: Git no guarda directorios vacíos, así que se pone dentro un archivo .gitkeep y se permite solo ese.

Dónde más se puede definir el ignorado

UbicaciónAfecta aVa al repositorio
.gitignore en la raíz y subcarpetastodo el equiposí
.git/info/excludesolo este clonno
archivo global core.excludesFiletodos tus repositoriosno

Es razonable llevar la basura de tu sistema operativo y tu IDE al ignorado global para no ensuciar el .gitignore común:

git config --global core.excludesFile ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global
echo ".idea/" >> ~/.gitignore_global

Si core.excludesFile no está definido, Git lee ~/.config/git/ignore si existe.

Por qué .gitignore no funciona

La queja más frecuente: «he añadido el archivo a .gitignore y Git sigue mostrando cambios». El motivo casi siempre es el mismo: el archivo ya tiene seguimiento. El ignorado no afecta a archivos que alguna vez entraron en un commit.

Para comprobar qué regla se aplica (o por qué no), sirve git check-ignore:

git check-ignore -v logs/app.log
# .gitignore:3:*.log	logs/app.log

La salida muestra el archivo y la línea de la regla. Una salida vacía significa que el archivo no se ignora. Otra causa de fallos son los espacios al final de la línea del patrón o una codificación incorrecta del archivo (por ejemplo, UTF-16 al crearlo desde PowerShell).

Cómo quitar del repositorio un archivo ya confirmado: git rm --cached

El comando git rm elimina el archivo del índice y del disco. Con la opción --cached, solo del índice: el archivo se queda contigo, pero deja de tener seguimiento.

echo ".env" >> .gitignore
git rm --cached .env
git commit -m "chore: .env deja de tener seguimiento"
git push

Para una carpeta hace falta -r:

git rm -r --cached node_modules/

Si hay muchas reglas y no está claro qué ha entrado ya en el repositorio, puedes reconstruir el índice entero: git rm -r --cached ., luego git add . y un commit. Antes del commit revisa git status: ahí verás los archivos quitados del índice.

Atención: los secretos se quedan en el historial

git rm --cached quita el archivo de los commits siguientes, pero no de los anteriores. Si una contraseña o un token llegó al repositorio, cualquiera con un clon puede verlo en el historial. El secreto debe considerarse comprometido y hay que regenerarlo. Se puede reescribir el historial con herramientas como git filter-repo, pero eso cambia los hashes de todos los commits posteriores y requiere coordinarse con el equipo.

Otra consecuencia: a tus compañeros, tras un git pull, el archivo quitado del índice con --cached se les borrará del disco. Con .env, avisa al equipo con antelación o guarda una plantilla .env.example en el repositorio.

git rm: eliminar archivos

git rm old.py              # borrar del disco y del índice
git rm -r legacy/          # borrar una carpeta
git rm -n '*.tmp'          # dry run: mostrar qué se borrará
git rm -f changed.py       # borrar un archivo con cambios sin commit

Si borras un archivo con un rm normal, Git lo verá como «deleted» y tendrás que añadir el borrado con git add o git rm. git rm hace ambos pasos a la vez. Sin -f se negará a borrar un archivo con cambios sin commit: es una protección para no perder trabajo.

git mv: renombrar y mover

git mv utils.py helpers.py
git mv helpers.py src/helpers.py

git mv es un atajo de mv + git rm de la ruta antigua + git add de la nueva. Git no guarda el hecho del renombrado: lo deduce por la similitud del contenido al mostrar git status, git log --follow y git diff. Por eso renombrar con git mv o con un mv normal seguido de git add -A da el mismo resultado.

Consejo práctico: renombra y cambia el contenido del archivo en commits distintos. Si el archivo cambia mucho a la vez que se renombra, Git puede no reconocerlo como el mismo archivo y el historial con --follow se cortará.

Para cambiar solo mayúsculas y minúsculas del nombre en Windows y macOS (sistemas de archivos que no las distinguen), usa git mv readme.md README.md: un simple renombrado en el explorador puede pasar desapercibido para Git.

Orden de las reglas y prioridad

Dentro de un mismo archivo las reglas se leen de arriba abajo y gana la última que coincida. Por eso la excepción !keep.log debe ir debajo de la regla *.log; si no, quedará anulada. Entre archivos, la prioridad es esta: el .gitignore de una subcarpeta pesa más que el de la raíz, y el ignorado global y .git/info/exclude tienen la prioridad más baja.

Ejemplo de .gitignore para un proyecto web

Aquí tienes una versión funcional para un proyecto con Node.js y backend en Python. Fíjate en los comentarios: dentro de seis meses nadie recordará por qué se añadió cada regla.

# --- dependencias ---
node_modules/
.venv/

# --- build y cachés ---
/dist
/build
__pycache__/
*.pyc
.pytest_cache/
coverage/

# --- logs ---
*.log
npm-debug.log*

# --- entorno y secretos ---
.env
.env.*
!.env.example

# --- subidas de usuarios, pero conservamos la carpeta ---
uploads/*
!uploads/.gitkeep

Aquí se usan los dos trucos con excepciones: .env.* oculta todas las variantes locales del entorno, pero la plantilla .env.example se queda en el repositorio, y la carpeta uploads existe en el clon gracias a .gitkeep.

Qué no conviene ignorar

Pasarse con el ignorado también es perjudicial. Los archivos de bloqueo de dependencias (package-lock.json, poetry.lock, composer.lock) normalmente se confirman en las aplicaciones: garantizan que todos los desarrolladores y el CI instalen las mismas versiones de paquetes. Los ajustes comunes de formato (.editorconfig, configuraciones de linters) también deben estar en el repositorio.

Un caso discutible son los ajustes del IDE. La carpeta .vscode/ se suele ignorar entera, pero a veces se confirman las extensiones recomendadas y las tareas de build: .vscode/* y después !.vscode/extensions.json. Lo decide el equipo; lo importante es no tener en el repositorio común rutas personales ni claves.

Escenario: subiste node_modules por error

El error clásico de principiante: git add . antes de crear el .gitignore, y decenas de miles de archivos acaban en el commit. Se arregla en tres pasos:

echo "node_modules/" >> .gitignore
git rm -r --cached node_modules
git commit -m "chore: node_modules fuera del repositorio"

Si el commit aún no se ha subido al servidor, es más limpio reescribirlo para que los archivos pesados no se queden en el historial: git reset --soft HEAD~1, luego los mismos comandos y un commit nuevo. Tras el push, los archivos ya están en el historial y el tamaño del clon no bajará sin reescribirlo.

Para que no vuelva a pasar, crea el .gitignore antes del primer git add y acostúmbrate a mirar git status antes de cada commit: una lista sospechosamente larga de archivos nuevos es motivo para detenerse.

Conclusión

El archivo .gitignore es el primero que conviene confirmar en un proyecto nuevo: las dependencias, los builds, los logs y los secretos no deben estar en el repositorio. El ignorado solo funciona con archivos sin seguimiento, así que lo que ya se añadió se quita con git rm --cached, y las reglas se comprueban con git check-ignore -v. Para borrar y renombrar usa git rm y git mv, así los cambios llegan directamente al índice. El trabajo con el índice y el primer repositorio se practica en el curso de Git.

Preguntas frecuentes

¿Hay que hacer commit del propio .gitignore?

Sí, para que las reglas se apliquen a todo el equipo; las exclusiones personales ponlas en .git/info/exclude o en el ignorado global.

¿Se pueden tener varios archivos .gitignore?

Sí, puedes poner un .gitignore en cualquier subcarpeta; sus reglas se aplican relativas a esa carpeta y complementan las de la raíz.

¿Cómo añadir a un commit un archivo ignorado?

Usa git add -f ruta/al/archivo; a partir de ahí el archivo tiene seguimiento y .gitignore ya no le afecta.

¿Cómo ver todos los archivos ignorados del proyecto?

Ejecuta git status --ignored o git ls-files --others --ignored --exclude-standard.

¿Cómo dejar temporalmente de seguir los cambios de un archivo confirmado?

Para eso existe git update-index --skip-worktree archivo, pero es un ajuste local y no sustituye a .gitignore.

Aprende este tema en vídeo

Este tema se explica a fondo y con práctica en el curso «Git desde cero hasta desarrollador seguro».

Ir al curso