Guía11 min

git LFS para coding agents: track, pull y modelos fuera del repo

Resumen

Guía práctica de Git LFS para coding agents: qué archivos trackear (binarios, datasets, no texto), cómo diagnosticar con git lfs ls-files y status, los límites reales de GitHub (100 MB por objeto; 10 GiB en Free/Pro), cuándo usar migrate y por qué los modelos grandes viven en Hugging Face Hub, no en el repo. Con checklist para que el agente no confunda un pointer file con un archivo corrupto.

GitHub
Un repositorio Git con punteros a archivos grandes almacenados fuera del repo, con un coding agent consultando el estado de Git LFS

Qué resuelve

Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.

Git LFS (Large File Storage) reemplaza los archivos grandes del repositorio por punteros de texto y guarda el contenido real en un servidor externo. El repo conserva un pointer file de unos cientos de bytes; al clonar, Git usa ese puntero como mapa para descargar el archivo real. Para un coding agent el patrón es claro: trackear binarios con LFS, diagnosticar con git lfs ls-files y nunca tratar un puntero como un archivo corrupto.

Esta guía sigue a la serie de flujo Git para agentes: si ya dominas los worktrees y el diagnóstico de objetos, aquí cierras el caso de los archivos que no deberían estar en el historial.

Qué resuelve y qué no resuelve

Git está diseñado para texto que cambia incrementalmente. Un binario de 200 MB se guarda entero en cada commit que lo toca: un cambio de un byte crea un blob nuevo de 200 MB. LFS corta el problema con indirección: el commit guarda el puntero y el blob original vive en el storage LFS del servidor.

CasoSin LFSCon LFS
Clone de repo con binariosDescargas todo el historial de binariosDescargas punteros; el binario solo si lo necesitas
Commit que toca un binarioNuevo blob completo en el historialSolo cambia el puntero en el commit
git log / diffLíneas binarias ilegiblesDiff de puntero corto, el objeto real queda fuera
Almacenamiento del repoCrece sin límiteEl repo queda pequeño; el peso vive en el storage LFS

Lo que LFS no hace: no convierte archivos ya commiteados (necesitas git lfs migrate) y no es un CDN para modelos de IA. Para eso están Hugging Face Hub y los buckets de objetos.

Un coding agent reconoce punteros LFS y decide cuándo descargar el objeto real desde el storage

Qué trackear y qué dejar en Git

La regla de oro: si es binario y cambia poco, LFS; si es texto y lo vas a diffear, Git.

Tipo de archivoRecomendación
Imágenes, audio, video, PSD, PDFs grandesLFS
Datasets medianos, fixtures binarios de testsLFS
Modelos entrenados (cientos de MB o GB)Fuera del repo: Hugging Face Hub o bucket
Código, config, texto, MarkdownGit normal (nunca trackear texto con LFS)
Lockfiles, fuentes, SVGsGit normal

GitHub enforce el límite de 100 MB por objeto (con 1 MB como máximo recomendado para transferencias sanas); por encima de eso, LFS. Un dataset de 5 GB en el repo no se arregla trackeándolo: hay que sacarlo del historial.

Setup en tres comandos

Instalación local (una vez por máquina):

git lfs install

En cada repo donde quieras LFS, declaras los patrones y commiteas .gitattributes:

git lfs track "*.webp"
git lfs track "*.psd"
git add .gitattributes

Después de eso commiteas y haces push normal; LFS intercepta los archivos que matchean. Ojo: trackear un patrón no convierte archivos ya existentes en el historial; eso es trabajo de git lfs migrate, que reescribe commits y genera SHAs nuevos — no apto para ramas compartidas sin coordinación.

Diagnóstico: lo que un coding agent debe correr

Flujo de un archivo grande: el repo guarda el puntero y el objeto viaja al storage externo

Antes de resumir el estado de un repo o de "arreglar" un archivo raro, corre los comandos de inspección:

git lfs ls-files
git lfs status
git lfs ls-files --size

git lfs ls-files lista los archivos LFS del árbol actual: un * tras el OID significa que el objeto completo está presente; un -, que solo tienes el puntero (no es un error: el objeto aún no se descargó).

Errores típicos del agente:

  • No "corregir" un pointer file: un archivo de ~130 bytes con version https://git-lfs.github.com/spec/v1 es LFS, no un archivo dañado. El fix es git lfs pull, no editar el archivo.
  • No volcar binarios al contexto: si ls-files muestra un objeto de 800 MB, no lo leas. Reporta el OID y el tamaño y propón git lfs pull selectivo.
  • No commitees el binario "para que se suba solo": un git add de un archivo que matchea el patrón sube el puntero, no el contenido, a menos que el objeto esté presente y autenticado contra el servidor LFS.

Fetch y pull para el agente

git lfs pull descarga los objetos del ref actual y actualiza el working copy — equivale a git lfs fetch + git lfs checkout. Con Git 2.42+ en un repo no bare, solo descarga objetos que estén en el index y matcheen un filtro de .gitattributes presente en el index o el working tree; en repos con sparse checkout conviene tener los .gitattributes de HEAD disponibles o usar GIT_ATTR_SOURCE=HEAD.

En clones shallow o parciales, decide si necesitas el contenido: para entender el código basta status y ls-files; para tests que dependen de fixtures, git lfs pull.

Cuotas y coste: lo que nadie lee hasta que bloquea

GitHub abandonó los data packs prepagados y pasó a metered billing: cada cuenta incluye una cuota gratuita mensual, y el excedente se cobra por uso. Cifras verificadas hoy:

PlanAncho de bandaAlmacenamiento
GitHub Free / Pro10 GiB/mes10 GiB
GitHub Team250 GiB/mes250 GiB
GitHub Enterprise Cloud250 GiB/mes250 GiB

Detalles que importan en producción:

  • El storage se mide por horas: borrar un objeto a mitad de mes no recalcula el mes actual; el contador se resetea el primero del mes siguiente.
  • Cada push de un archivo cuenta como storage completo: un cambio de 1 byte en un archivo de 500 MB consume otros 500 MB de la cuota del dueño del repo (no la del que pushea).
  • El bandwidth se cobra al dueño del repo cuando alguien descarga, incluyendo GitHub Actions: un job de CI que baja fixtures LFS grandes consume tu cuota.
  • Presupuesto en $0 + cuota superada = LFS bloqueado el resto del mes; con método de pago, se factura el excedente.

Para un agente de CI esto es oro: git lfs pull de 10 giB de fixtures puede volcar la cuenta del repo. Prefiere descargar solo lo necesario o mantener los fixtures en un bucket con acceso firmado.

Blindaje de cuotas: ancho de banda y almacenamiento limitan cuánto LFS puede consumir un equipo

Modelos y datasets: fuera del repo

El caso más común de "LFS mal usado" en proyectos de IA: un modelo de 7 GB commiteado con git lfs track "*". Resultado: cuota reventada en un push y clones lentísimos. La práctica correcta:

  • Modelos y datasets grandes → Hugging Face Hub (o bucket de objetos). El repo referencia el modelo por nombre/versión, no por blob.
  • Datasets medianos o fixtures de tests → LFS, si el equipo los necesita en CI.
  • Nunca trackear todo con *: lista explícita de extensiones.

Antes de proponer LFS, pregunta si el archivo es un artefacto (regenerable, fuera del repo) o un asset (necesario para el producto, candidato a LFS).

Migrar historial existente: git lfs migrate

git lfs migrate tiene tres modos: import (convierte blobs a LFS), export (lo inverso) e info (resume qué tipos de archivo pesan). El modo info es la puerta de entrada para diagnosticar antes de tocar nada:

git lfs migrate info

El import reescribe el historial, genera SHAs nuevos y trabaja solo sobre tu repo local, nunca sobre remotos. Si la rama ya es compartida, reescribirla exige coordinar a todo el equipo; jamás apliques force-push para "arreglar" historial ajeno. Igual que en git revert: primero entiende el alcance, después actúa.

Checklist antes de cerrar

  1. git lfs ls-files --size confirma qué hay trackeado y con qué tamaño.
  2. git lfs status muestra qué está pendiente de subir (punteros sin objeto o viceversa).
  3. .gitattributes está commiteado en main — sin él, los patrones se pierden al clonar.
  4. Los modelos grandes viven en Hugging Face Hub, no en LFS.
  5. Los jobs de CI no descargan más LFS del necesario.
  6. Nadie reescribe historial compartido con force-push.

FAQ

¿Por qué un archivo grande aparece como texto corto en el diff? Porque estás viendo el puntero LFS, no el contenido: el texto es el manifiesto del puntero (version, oid, size). El objeto real está en el servidor LFS.

¿Puedo borrar un objeto LFS para recuperar storage? Borrar el archivo y el puntero reduce el storage del mes siguiente; el del mes actual no se recalcula. Y el objeto sigue contando mientras exista en el historial: hay que purgarlo o usar la API de GitHub para eliminarlo.

¿LFS sirve para un modelo de IA de 7 GB en el repo? No. Un objeto así revienta la cuota de 10 GiB de Free en un solo push y enlentece cada clon. Publícalo en Hugging Face Hub, referencia la versión en el código y arranca el patrón correcto desde el curso.

Con Git LFS bien configurado, el repo queda liviano, los clones rápidos y el agente sabe distinguir un puntero de un error — la fricción que no debería detener tu automatización.