Fundamentos

Git LFS: cómo guardar archivos grandes en un repositorio Git

Actualizado: · Skillaria.Top

Git LFS (Large File Storage) es una extensión de Git que guarda los archivos binarios grandes en un servidor aparte y en el repositorio deja solo pequeños archivos puntero. Clonar se vuelve rápido, el historial no se infla y el trabajo con los archivos sigue siendo el de siempre: git add, commit y push.

Qué es Git LFS y para qué sirve

Git LFS (Large File Storage) es la extensión oficial de Git para guardar archivos grandes: vídeos, maquetas PSD, datasets, modelos de redes neuronales o assets de videojuegos. En lugar del archivo en sí, en el commit entra un puntero de texto de unos 130 bytes, y el contenido va a un almacén LFS aparte en el servidor. Al hacer checkout, la extensión coloca el archivo real en el directorio de trabajo, así que para ti todo parece Git normal.

El problema que resuelve git lfs está en cómo funciona el propio Git. Cada versión de cada archivo se queda para siempre en el historial, y al clonar se descarga el historial completo. Si has cambiado diez veces un vídeo de 200 MB, el repositorio ya pesa unos 2 GB, y cada desarrollador nuevo descarga las diez versiones aunque solo necesite la última. La compresión y los deltas, que funcionan muy bien con texto, apenas sirven con archivos binarios.

Con LFS, al clonar solo se descargan las versiones de los archivos grandes del commit actual. Las versiones antiguas se quedan en el servidor y se traen cuando cambias a un commit antiguo.

Cómo funciona Git LFS por dentro

El mecanismo se basa en los filtros de Git clean y smudge. Cuando haces git add de un archivo que sigue LFS, se activa el filtro clean: guarda el contenido en la caché local .git/lfs/objects y pasa al índice un puntero. Al hacer checkout, el filtro smudge hace lo contrario: busca el objeto por su hash en la caché (o lo descarga del servidor) y escribe el archivo real.

Un puntero tiene este aspecto:

version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 209715200

Tres líneas: la versión de la especificación, el SHA-256 del contenido y el tamaño en bytes. Eso es lo que se guarda en el historial de Git, y por eso el historial sigue siendo ligero. Al hacer git push se dispara un hook pre-push: primero se suben los objetos nuevos mediante la API de LFS y luego se envían los commits por el protocolo normal.

Qué archivos se entregan a LFS lo decide el archivo .gitattributes en la raíz del repositorio. Se hace commit de él junto con el código, así que las reglas son las mismas para todo el equipo.

Cómo instalar Git LFS

En Git para Windows la extensión ya viene en el instalador. En macOS y Linux se instala como paquete:

# macOS (Homebrew)
brew install git-lfs

# Debian / Ubuntu
sudo apt install git-lfs

# Fedora
sudo dnf install git-lfs

Después de instalarlo, ejecuta una vez por usuario:

git lfs install

El comando registra los filtros de LFS en el ~/.gitconfig global e instala los hooks en el repositorio actual, si estás dentro de uno. Puedes comprobar que todo está en su sitio con git lfs version, y la configuración detallada (dirección del servidor, rutas de la caché) la muestra git lfs env.

Cómo empezar a seguir archivos grandes

El escenario típico en un proyecto nuevo:

git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "models/**"

git add .gitattributes
git add design/banner.psd
git commit -m "Añadir la maqueta del banner con LFS"
git push origin main

Las comillas alrededor del patrón son obligatorias: sin ellas, la shell expandirá *.psd a la lista de archivos de la carpeta actual y la regla no será la que esperas. Después de git lfs track aparecerá en .gitattributes una línea así:

*.psd filter=lfs diff=lfs merge=lfs -text

El atributo -text desactiva la conversión de finales de línea, que estropearía un archivo binario. El orden importa: primero la regla track y luego el git add del archivo. Si el archivo se añadió de forma normal antes de que existiera la regla, se quedó en el historial como un blob corriente.

Cómo comprobar que un archivo está realmente en LFS

git lfs ls-files
4d7a214614 * design/banner.psd
9c1e0b7a3f * video/intro.mp4

git lfs status

git lfs ls-files muestra los archivos del commit actual guardados en LFS. El asterisco indica que el contenido está descargado; el guion, que en la copia de trabajo solo hay un puntero. git lfs track sin argumentos lista los patrones seguidos, y una regla se quita con git lfs untrack "*.psd".

Clonar y obtener los archivos

Un git clone normal funciona con LFS de forma transparente: si la extensión está instalada, los archivos grandes se descargan automáticamente. Pero si un compañero no tiene LFS instalado, en su copia de trabajo verá punteros de texto en lugar de imágenes: es el síntoma más habitual de «en vez del PSD tengo un texto raro». Se arregla instalándolo y ejecutando:

git lfs install
git lfs pull

git lfs pull descarga los objetos del commit actual y los coloca en el directorio de trabajo. Existe además git lfs fetch, que solo descarga a la caché sin tocar los archivos. Con la opción --all descarga los objetos de todas las referencias, algo útil para una copia de seguridad completa o para migrar a otro servidor.

Cómo clonar sin los archivos grandes

En CI, o cuando solo necesitas el código, descargar gigas de assets sobra. Una variable de entorno desactiva el filtro smudge:

GIT_LFS_SKIP_SMUDGE=1 git clone https://example.com/team/game.git
cd game
git lfs pull --include="textures/ui/**"

El repositorio se clona con punteros y luego traes de forma selectiva los archivos que necesitas con --include (también existe --exclude). Esto acelera mucho las compilaciones en los pipelines.

Cómo migrar archivos existentes a Git LFS

Situación frecuente: el repositorio ya está inflado y los archivos grandes están en el historial. git lfs track no actúa sobre el pasado, solo afecta a los commits nuevos. Para reescribir el historial usa git lfs migrate.

Primero mira qué ocupa espacio:

git lfs migrate info --everything --top=10

Después migra los tipos necesarios en todas las ramas:

git lfs migrate import --include="*.psd,*.mp4" --everything
git push --force --all
git push --force --tags

La migración reescribe cada commit en el que aparecían esos archivos, así que cambian todos los hashes. Es lo mismo que hacer rebase de ramas publicadas: hay que avisar a todo el equipo, y tras el push forzado tendrán que volver a clonar el repositorio o resetear sus ramas con fuerza. Antes de migrar, haz una copia de seguridad (git clone --mirror).

Si no se puede reescribir el historial, hay una variante suave: git lfs migrate import --no-rewrite ruta/al/archivo. Crea un commit nuevo que pasa los archivos a LFS desde ese momento. Las versiones antiguas seguirán en el historial, pero el repositorio dejará de crecer.

Bloqueo de archivos: protección contra conflictos en binarios

Dos diseñadores editan el mismo PSD y Git no podrá fusionar sus cambios: uno de los dos trabajos se perderá. Para estos archivos LFS ofrece bloqueos. Marca el tipo como bloqueable:

git lfs track "*.psd" --lockable

En .gitattributes se añadirá el atributo lockable, y esos archivos quedarán en solo lectura en la copia de trabajo hasta que los bloquees:

git lfs lock design/banner.psd
git lfs locks
design/banner.psd	anna	ID:123

# después de hacer push de los cambios
git lfs unlock design/banner.psd

Mientras el archivo esté bloqueado, se rechazará el push de cambios en él hecho por otra persona. Los bloqueos los gestiona el servidor, así que funcionan en los grandes hostings de Git, pero en un servidor propio puede que no existan. Un administrador puede quitar el bloqueo de otra persona con git lfs unlock --force.

Dónde se guardan los objetos LFS y cuánto cuesta

Los objetos LFS viven en un servidor que implementa la API de LFS. La implementan los hostings de Git más populares y las soluciones self-hosted, además de servidores independientes. Los hostings en la nube tienen límites de almacenamiento y de tráfico LFS, distintos según el servicio y el plan: revisa las condiciones vigentes de tu plataforma antes de subir datasets de cientos de gigas.

Ten en cuenta que el tráfico cuenta en cada descarga: un CI que clona el repositorio con archivos LFS en cada commit puede agotar el límite antes que las personas. Guarda en caché .git/lfs entre compilaciones o usa GIT_LFS_SKIP_SMUDGE.

En local la caché también crece. El comando git lfs prune borra los objetos antiguos que ya están en el servidor y no se necesitan para los commits actuales y recientes.

Cuándo conviene Git LFS y cuándo no

Situación¿Conviene LFS?Comentario
Assets de juegos, maquetas, audio, vídeoSíEl caso clásico: binarios que cambian a menudo
Modelos de ML y datasets medianos junto al códigoSí, vigilando las cuotasPara datos muy grandes son más cómodas las herramientas especializadas de versionado de datos
Artefactos compiladosNoSu sitio es un registro de artefactos o las releases, no Git
Dependencias (node_modules, vendor)NoLas instala el gestor de paquetes; añádelas a .gitignore
Archivos de texto grandes (volcados SQL, CSV)DependeGit guarda el texto con deltas de forma eficiente; LFS hace falta si son enormes y apenas se leen en un diff
Secretos y claves privadasNuncaLFS no cifra los datos, no es un almacén de secretos

Errores frecuentes y cómo solucionarlos

En la copia de trabajo hay un puntero de texto en lugar del archivo

LFS no está instalado o el clon se hizo con GIT_LFS_SKIP_SMUDGE=1. Ejecuta git lfs install y git lfs pull.

Un archivo entró en el historial sin pasar por LFS

La regla track se añadió después del git add. Si el commit aún no se ha enviado, quita el archivo del índice (git rm --cached archivo), comprueba que la regla está en .gitattributes y vuelve a añadirlo. Si ya se envió, usa git lfs migrate import. Para encontrar estos archivos ayuda git lfs fsck --pointers.

El push se rechaza por el tamaño del archivo

Muchos hostings limitan el tamaño de un objeto individual en Git normal. Un mensaje como «this exceeds the file size limit» significa que ese archivo debía ir a LFS. Reescribe el último commit o el historial como se ha explicado: un simple commit de «borrar archivo» no sirve, porque seguirá en los commits anteriores.

Después de git lfs migrate a mis compañeros se les ha roto todo

Sus ramas locales se basan en los hashes antiguos. Lo más fiable es volver a clonar el repositorio; si tienen trabajo sin subir, pueden llevarlo con cherry-pick a las ramas nuevas.

Chuleta de comandos de Git LFS

ComandoQué hace
git lfs installConfigura los filtros y los hooks
git lfs track "*.ext"Añade un patrón a .gitattributes
git lfs untrack "*.ext"Quita un patrón
git lfs ls-filesArchivos en LFS del commit actual
git lfs pullDescargar y colocar los objetos
git lfs fetch --allDescargar a la caché los objetos de todas las referencias
git lfs migrate import --include="..." --everythingPasar archivos del historial a LFS
git lfs lock / unlock / locksGestionar bloqueos
git lfs pruneLimpiar la caché local de objetos antiguos
git lfs envDiagnóstico de la configuración

Resumen

Git LFS saca los archivos binarios grandes del historial a un almacén aparte y deja en los commits punteros ligeros. La regla principal es configurar git lfs track antes del primer commit de archivos grandes, hacer commit de .gitattributes y vigilar las cuotas del hosting. Si los archivos ya están en el historial, te ayudará git lfs migrate, pero eso es reescribir el historial con todas sus consecuencias. El trabajo con el historial, rebase y otras herramientas avanzadas de Git se practica en el curso de Git.

Preguntas frecuentes

¿Git LFS es gratis?

La extensión en sí es libre y gratuita. Puede que tengas que pagar almacenamiento y tráfico al hosting de Git si superas los límites gratuitos de tu plan.

¿A partir de qué tamaño un archivo se considera grande para LFS?

No hay un límite fijo; normalmente se envían a LFS binarios de varios megabytes que cambian a menudo. Los archivos de texto, incluso grandes, Git los guarda de forma eficiente sin LFS.

¿Se puede dejar de usar Git LFS y devolver los archivos a Git normal?

Sí, con git lfs migrate export --include="*.psd" --everything, que reescribe el historial a la inversa. Después hay que quitar las reglas de .gitattributes y hacer un force push.

¿Funciona git diff con archivos en LFS?

Git mostrará el cambio del puntero, no del contenido, porque los archivos son binarios. Para imágenes y documentos la comparación se hace con herramientas externas.

¿Cada miembro del equipo necesita LFS?

Sí; de lo contrario, quien no tenga la extensión verá punteros en lugar de archivos en su copia de trabajo, y sus commits pueden añadir por accidente archivos grandes sin pasar por LFS.

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