Git LFS (Large File Storage)
Aprende Git LFS para mantener archivos binarios grandes fuera del historial del repositorio usando punteros ligeros. Configuración y comandos incluidos.
¿Qué es Git LFS?
Git LFS (Large File Storage) es una extensión de Git de código abierto que mantiene los archivos binarios grandes — vídeos, conjuntos de datos, recursos de diseño, arte de videojuegos — fuera del historial de Git. En lugar de almacenar un archivo de 500 MB en el repositorio, Git LFS guarda un pequeño puntero de texto y conserva el contenido real en un almacén LFS separado. El resultado: los clones se mantienen rápidos y el repositorio permanece pequeño, incluso cuando el proyecto incluye gigabytes de recursos.
Este capítulo cubre cuándo usar LFS, cómo instalar y rastrear archivos, qué contiene realmente un puntero, los comandos habituales, el bloqueo de archivos para binarios que no se pueden fusionar, y los errores más comunes.
Por qué los archivos grandes perjudican a Git
Git está diseñado para texto y almacena el historial completo de cada archivo. Además, almacena los archivos por contenido: cuando un binario cambia, Git suele guardar la copia nueva completa en lugar de un pequeño diff, porque los binarios no se pueden comparar fácilmente. Si confirmas un binario grande varias veces, cada clon debe descargar todas las versiones para siempre, incluso las que nadie necesita. El historial se infla, los clones van lentos y los envíos superan el tiempo límite. Git LFS evita esto versionando un pequeño puntero en lugar del contenido pesado.
Usa LFS cuando los archivos son grandes y cambian con el tiempo: fuentes de diseño, recursos compilados, conjuntos de datos, audio y vídeo. Para archivos que no necesitan versionado en absoluto, mantenlos fuera del repositorio con .gitignore.
Configuración
Primero instala Git y luego instala la extensión LFS. En la mayoría de sistemas, Git LFS se distribuye por separado (brew install git-lfs, apt install git-lfs, o el instalador de git-lfs.com). Actívalo una vez por máquina:
git lfs installUpdated Git hooks.
Git LFS initialized.Indica a LFS qué archivos debe gestionar rastreando patrones. Esto escribe reglas en .gitattributes:
git lfs track "*.psd"
git lfs track "*.mp4"
git add .gitattributes.gitattributes debe confirmarse para que todos los colaboradores tengan las mismas reglas. A partir de ahora, los archivos que coincidan con los patrones se almacenan a través de LFS automáticamente. Haz commit y push como de costumbre:
git add design.psd
git commit -m "Add hero design source"
git pushGit sube el puntero al repositorio y el contenido binario al almacén LFS. En un clon nuevo, los hooks de Git LFS se activan automáticamente y descargan el contenido real para el commit que está extraído.
Cómo es un puntero
En el repositorio, el archivo rastreado se reemplaza por un pequeño puntero de texto que registra el hash y el tamaño del contenido:
version https://git-lfs.github.com/spec/v1
oid sha256:9af1c2a3b4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f7
size 471859200Las tres líneas son la versión de la especificación, el identificador de objeto SHA-256 del contenido (oid) y el tamaño en bytes. Eso es todo lo que ocupa en el historial de Git: unos pocos cientos de bytes sin importar el tamaño del recurso. Cuando alguien extrae el archivo, Git LFS usa este puntero para obtener el contenido real bajo demanda.
Comandos habituales
| Comando | Descripción |
|---|---|
git lfs install | Activa LFS para tu usuario (ejecutar una sola vez). |
git lfs track "<pattern>" | Empieza a gestionar los archivos que coincidan con un patrón mediante LFS. |
git lfs untrack "<pattern>" | Deja de gestionar un patrón. |
git lfs ls-files | Lista los archivos rastreados actualmente por LFS. |
git lfs status | Muestra qué archivos LFS están en el área de preparación o modificados. |
git lfs pull | Descarga el contenido LFS para el checkout actual. |
git lfs fetch | Descarga objetos LFS sin actualizar el árbol de trabajo. |
git lfs prune | Elimina archivos LFS antiguos sin referencia del almacenamiento local. |
git lfs migrate | Reescribe el historial existente para mover archivos grandes a LFS. |
Para confirmar qué está gestionando LFS realmente, lista los archivos rastreados:
git lfs ls-files9af1c2a3b4 * design.psd
1c0ffee5d6 * intro.mp4Cada línea muestra el id de objeto abreviado, un * cuando el contenido real está presente localmente (- si solo está extraído el puntero) y la ruta.
Bloqueo de archivos
Los binarios como .psd o .fbx no se pueden fusionar: si dos personas editan el mismo archivo, uno de los conjuntos de cambios se pierde. Git LFS añade el bloqueo de archivos para que un compañero pueda reclamar un archivo antes de editarlo:
git lfs lock images/banner.psd
git lfs locks
git lfs unlock images/banner.psdMarca un patrón como bloqueable en .gitattributes para marcarlo como de solo lectura hasta que se bloquee, lo que evita ediciones accidentales:
git lfs track "*.psd" --lockableEl bloqueo requiere soporte del servidor (GitHub y GitLab lo proporcionan).
Mover archivos existentes a LFS
El rastreo solo afecta a los archivos confirmados después de añadir la regla. Los archivos que ya están en el historial permanecen en Git como binarios completos. Para moverlos, reescribe el historial con git lfs migrate:
git lfs migrate import --include="*.mp4"Esto reescribe los commits, por lo que cambia sus hashes. Coordínalo con tu equipo y fuerza el push después, como en cualquier reescritura del historial.
Aspectos a tener en cuenta
- Se requiere soporte del servidor. GitHub, GitLab y Bitbucket proporcionan LFS, a menudo con cuotas de almacenamiento y ancho de banda que pueden generar costes. Un repositorio puede superar su cuota de LFS aunque su tamaño en Git sea pequeño.
- Todos necesitan la extensión. Cualquier persona que clone el repositorio debe tener Git LFS instalado, o verá el texto del puntero en lugar del archivo real. Si eso ocurre, basta con instalar LFS y ejecutar
git lfs pull. - Los punteros son objetos Git normales. Las ramas, fusiones y comparaciones del puntero funcionan con normalidad; LFS solo sustituye el contenido real en el momento del checkout.