Capítulo 9 de 33 10 secciones 6 min

Por qué tu repositorio pesa quinientos megas

El .gitignore, y por qué no saca lo que ya estaba dentro

El <code>.gitignore</code> es una lista de lo que Git debe fingir que no ve. Lo que casi nadie sabe, y a mí me costó 18 MB de repositorio, es que <strong>solo funciona con archivos que Git todavía no conoce</strong>. Lo que ya se commiteó una vez sigue dentro aunque lo pongas en la lista 🪨

Qué nunca debe entrar a un repositorio

Tres familias, y las tres por motivos distintos:

  • Lo que tiene secretos. Archivos .env, claves, contraseñas. Este es el peligroso.
  • Lo que se genera solo. Carpetas de dependencias, archivos compilados, cachés. Ocupan muchísimo y se vuelven a crear en un comando.
  • Lo que es tuyo y de nadie más. La configuración de tu editor, archivos temporales del sistema.

Cómo se escribe la lista

mkdir tienda
cd tienda
git init -q
printf 'ciudad,monto\nLima,1200\n' > ventas.csv
mkdir cache
printf 'basura\n' > cache/temporal.txt
printf 'CLAVE=secreta123\n' > .env
git status --short
?? .env
?? cache/
?? ventas.csv

Ahí están los tres, y el .env con la clave a un git add . de irse a internet. Escribo la lista:

printf '.env\ncache/\n*.log\n' > .gitignore
cat .gitignore
git status --short
.env
cache/
*.log
?? .gitignore
?? ventas.csv

Desaparecieron. Ahora Git solo ve ventas.csv y el propio .gitignore, que sí se versiona porque el equipo entero tiene que compartir la misma lista.

Los cuatro patrones que uso

  • .env, un archivo con ese nombre exacto.
  • cache/, la carpeta entera con lo que tenga dentro.
  • *.log, todo lo que termine así.
  • !importante.log, la excepción: esto sí entra aunque el patrón de arriba lo excluya.

Preguntar por qué se ignora algo

git add ventas.csv .gitignore
git commit -q -m "Primeras ventas y la lista de ignorados"
git check-ignore -v cache/temporal.txt
.gitignore:2:cache/	cache/temporal.txt

Te dice qué archivo y qué línea lo está ignorando. Cuando un archivo no aparece y no entiendes por qué, este comando lo resuelve en un segundo 🔎

Y aquí viene lo importante

Meto una carpeta pesada al repositorio, como si no me hubiera dado cuenta:

mkdir librerias
printf 'un archivo enorme\n' > librerias/todo.js
git add librerias
git commit -q -m "Se sube la carpeta de librerias sin querer"
git ls-files
.gitignore
librerias/todo.js
ventas.csv

Ahora la agrego a la lista y miro qué pasa:

printf 'librerias/\n' >> .gitignore
git add .gitignore
git commit -q -m "Se ignora la carpeta de librerias"
git status --short
git ls-files
.gitignore
librerias/todo.js
ventas.csv

El estado dice que todo está limpio, así que parece que funcionó. Pero git ls-files, que lista lo que Git está siguiendo, sigue teniendo el archivo dentro.

Eso es exactamente lo que pasó en el repositorio de missyera.com: node_modules y staticfiles llevaban meses en el .gitignore y a la vez dentro. Eran 1.964 archivos y 18,6 MB que el servidor se bajaba en cada despliegue y no usaba nunca.

Sacar lo que ya entró

git rm -r --cached -q librerias
git commit -q -m "Se saca la carpeta de librerias del repositorio"
git ls-files
ls librerias
.gitignore
ventas.csv
todo.js

Fuera del repositorio y sigue en tu disco. Eso es lo que significa --cached: deja de versionarlo, no lo borra 🎯

El error de preguntar por algo que no se ignora

git check-ignore -v ventas.csv


Ni una palabra, y sin embargo falló: no imprime nada y devuelve un código de error, que es como Git dice "ese archivo no está ignorado por nadie".

La trampa

Tu repositorio pesa 400 MB y tarda una eternidad en subir. Te das cuenta de que hay carpetas enormes que no deberían estar, las pones en el .gitignore y respiras tranquila.

$ echo "node_modules/" >> .gitignore
$ git add .gitignore
$ git commit -m "Se ignora node_modules"
$ git status

On branch main
nothing to commit, working tree clean
Qué está mal

Sigue pesando 400 MB 🪨

El .gitignore solo sirve para los archivos que Git todavía no conoce. Lo que ya se commiteó una vez, ya entró, y agregarlo a la lista no lo saca: por eso el estado dice que todo está limpio, y parece que funcionó.

Esto pasó en el repositorio de missyera.com. node_modules y staticfiles llevaban meses en el .gitignore y a la vez dentro del repositorio: 1.964 archivos y 18,6 MB que el servidor se bajaba en cada despliegue y no usaba nunca.

Se saca con git rm -r --cached, que deja de versionarlos sin borrarlos de tu disco, y recién entonces el .gitignore hace su trabajo.

Comprueba que se entendió

Comprueba que lo tienes

Subiste sin querer un archivo con claves hace tres commits. ¿Qué haces primero?

  • Lo agrego al .gitignore
  • Cambio la clave en el proveedor
  • Borro el archivo y hago un commit
  • Uso git rm --cached

Ejercicios

1. Ignora por extensión

Crea dos archivos de registro y haz que Git ignore todos los que terminen en .log.

printf 'error\n' > ventas.log
printf 'error\n' > pedidos.log
printf '*.log\n' >> .gitignore
git status --short
 M .gitignore

Solo aparece el .gitignore modificado. Los dos registros desaparecieron del radar con una sola línea 🧽

2. La excepción a la regla

Haz que uno de esos registros sí entre, con la admiración.

printf '!ventas.log\n' >> .gitignore
git status --short
 M .gitignore
?? ventas.log

La admiración da la vuelta al patrón anterior. El orden importa: la excepción tiene que ir después de la regla que anula.

3. Pregunta quién ignora qué

Averigua qué línea del archivo está ignorando pedidos.log.

git check-ignore -v pedidos.log
.gitignore:5:*.log	pedidos.log

Archivo, número de línea y patrón. Con esto se acaban las discusiones sobre por qué algo no aparece.

4. Lista todo lo que Git está siguiendo

Pide los archivos versionados, que no es lo mismo que los archivos que hay.

git ls-files
.gitignore
ventas.csv

Esta lista es la verdad sobre tu repositorio. El .gitignore dice intenciones; ls-files dice hechos 📋

5. Mete algo que no debía y sácalo

Versiona un archivo de caché y después quítalo sin borrarlo del disco.

printf 'temporal\n' > basura.tmp
git add -f basura.tmp
git commit -q -m "Se sube un temporal sin querer"
git rm --cached -q basura.tmp
git commit -q -m "Se saca el temporal del repositorio"
git ls-files
ls basura.tmp
.gitignore
ventas.csv
basura.tmp

Fuera de la lista de Git y presente en la carpeta. Ese -f del principio es lo que fuerza a agregar algo ignorado, y por eso conviene desconfiar cuando lo veas en un tutorial 🚩

6. Cuánto pesa lo que estás versionando

Cuenta cuántos archivos sigue Git en este repositorio.

git ls-files | wc -l
2

En un proyecto tuyo este número debería caber en tu cabeza. Si sale en miles, casi seguro entró una carpeta que no debía.

7. Un archivo que nadie ignora

Pregunta por el CSV de ventas, que sí tiene que entrar.

git check-ignore -v ventas.csv

Silencio y código de error. En este caso es la respuesta correcta: ese archivo es justo el que quieres versionar 📊

Lo que te llevas

El .gitignore solo vale para lo que Git todavía no conoce. Lo que ya entró se saca con git rm --cached.

¿Tienes alguna duda o consulta?