13 puntos por GN⁺ 2025-08-16 | 1 comentarios | Compartir por WhatsApp
  • El proyecto Git recientemente comenzó oficialmente a resolver por sí mismo el problema de gestionar archivos grandes
  • Git LFS es una solución temporal que genera varios costos y dependencia del proveedor para los usuarios
  • Con la función reciente de partial clone, ahora Git por sí solo puede reemplazar la mayor parte de lo que hacía LFS
  • Hacia adelante, también se está preparando la integración en Git oficial de una nueva solución llamada large object promisor
  • Con estos cambios, todo apunta a que la solución definitiva para gestionar archivos grandes no será una extensión externa, sino Git mismo

El problema de los archivos grandes en Git y lo que está cambiando

  • Si Git tiene un mayor enemigo, son precisamente los archivos grandes
  • Los archivos grandes hinchan el repositorio, ralentizan git clone y también afectan negativamente a la mayoría de los entornos de hosting

La llegada de Git LFS y sus límites

  • En 2015, GitHub lanzó Git LFS para esquivar el problema de los archivos grandes
  • Pero Git LFS en sí mismo añadió nueva complejidad y costos de almacenamiento
  • La comunidad de Git ha estado pensando silenciosamente en el problema de fondo de los archivos grandes y, recientemente, las versiones oficiales de Git han comenzado a mostrar una nueva dirección para gestionarlos sin LFS

Lo que ya se puede hacer hoy: reemplazar Git LFS con partial clone

  • Cómo funciona partial clone

    • Git LFS: los archivos grandes se dejan fuera del repositorio y se trabaja descargando solo los archivos necesarios
    • Git partial clone (introducido en 2017):
      • clona excluyendo blobs por encima del tamaño deseado con la opción --filter
      • solo descarga desde el servidor ese archivo grande cuando hace falta

      Partial clone puede reducir el tiempo de descarga y el uso de disco porque evita descargar por adelantado [large binary assets] durante Clone y Fetch

  • Qué comparten partial clone y LFS

    • 1. Checkout mínimo: recibe solo la versión más reciente y omite el historial completo del archivo
    • 2. Clonado rápido: como no hay transferencia de archivos grandes, clone es más veloz
    • 3. Configuración rápida: a diferencia de shallow clone, permite acceder al historial completo del proyecto
  • Ejemplo de uso de partial clone

    • Caso real de velocidad de clonado y espacio en disco al clonar un repo con mucho historial de archivos PNG grandes:
      • con un clone normal tarda casi 4 minutos y ocupa 1.3GB
      • con partial clone y un límite de blobs de 100KB, se clona en 6 segundos y ocupa 49MB
      • frente al original, mejora del 97% en velocidad de clonado y reducción del 96% en tamaño del checkout
  • Límites de partial clone

    • Cuando se necesita un dato filtrado (por ejemplo, git diff, git blame, git checkout), Git solicita el archivo al servidor
    • Esta es la misma característica que tiene Git LFS
    • En la práctica, rara vez hace falta usar blame sobre archivos binarios

Los problemas de Git LFS

  • Alta dependencia del proveedor: la implementación de GitHub solo soporta sus propios servidores, lo que genera cobros y dependencia
  • Problema de costos: almacenar 50GB en GitHub LFS cuesta $40 al año, frente a $13 en Amazon S3
  • Difícil de revertir: una vez que se migra a LFS, no se puede volver atrás sin reescribir el historial
  • Costo continuo de configuración: todos los colaboradores deben instalar LFS; si no lo hacen, ven archivos de metadatos en lugar de los archivos reales, lo que genera confusión

Lo que viene: Large Object Promisor

  • Los archivos grandes también generan problemas de costos para las plataformas de hosting como GitHub y GitLab
  • Git LFS reduce costos del servidor descargando archivos grandes a un CDN
  • ¿Qué es Large Object Promisor?

    • A inicios de este año, Git hizo merge oficialmente de una función llamada large object promisor
    • Esta función reduce la carga de almacenamiento del lado del servidor de forma similar a LFS, pero disminuye mucho la complejidad para el usuario

      Este esfuerzo tiene como objetivo mejorar el trabajo del lado del servidor, especialmente con blobs grandes ya comprimidos en formato binario
      Es una solución alternativa a Git LFS
      Large Object Promisors, git-scm.com

  • Cómo funciona

    • 1. El usuario hace push de archivos grandes al host de Git
    • 2. El host deriva esos archivos grandes a un promisor de backend
    • 3. Durante el clone, el host de Git entrega al cliente la información del promisor
    • 4. Cuando hace falta, el cliente descarga automáticamente los archivos grandes desde ese promisor
  • Estado actual de adopción y retos

    • El promisor para objetos grandes sigue en desarrollo y parte del código fue mergeado en Git en marzo de 2025
    • En GitLab y otros proyectos se sigue discutiendo la implementación adicional y los problemas pendientes
    • Todavía falta tiempo para una adopción masiva
    • Por ahora, sigue siendo inevitable depender de Git LFS para almacenar archivos grandes
    • Cuando el promisor se masifique, también se espera que GitHub permita subir archivos de más de 100MB

Conclusión: el futuro de los archivos grandes en Git es Git

  • El proyecto Git sigue pensando constantemente en el problema de los archivos grandes por ti
  • Por ahora, todavía sigue siendo necesario usar Git LFS
  • Pero a medida que evolucionen partial clone y large object promisors, Git LFS se volverá cada vez menos necesario, y pronto llegará una era en la que los archivos grandes podrán gestionarse fácilmente solo con Git
  • En el futuro, el último obstáculo para usar archivos grandes en Git será únicamente la idea de meter una biblioteca de MP3 dentro del repositorio

1 comentarios

 
GN⁺ 2025-08-16
Comentarios de Hacker News
  • Incluso con el viejo svn, un directorio de trabajo de 150 GB con muchos archivos binarios grandes funcionaba bastante bien sin mayores problemas, mientras que con git no pasa así. Me pregunto por qué svn tiene un enfoque distinto al de git para archivos binarios grandes, y si git no podría hacer lo mismo. Además, al manejar datos binarios, una función indispensable es el bloqueo de archivos: solo una persona debería poder trabajar sobre cierto archivo y el resto tenerlo en solo lectura para evitar merges confusos. Tampoco me queda claro si descargar los archivos grandes a un sistema externo realmente mejora los problemas de rendimiento o estabilidad. Al final, solo cambia el repositorio; un repositorio sigue siendo un repositorio. Da la impresión de que moverlos fuera es, en realidad, una forma de que los forges públicos de git eviten el costo de almacenar archivos grandes

    • git y svn tienen diseños completamente distintos. git es totalmente distribuido, así que cada repositorio debe tener el historial completo de todos los archivos, y el concepto de bloqueo pierde sentido. Solo hay que elegir el sistema de control de versiones adecuado para el proyecto; no es que git tenga que servir para todo
  • Me gusta la idea de los large object promisors. Si fuera fácil conectarlo con algo como S3, creo que me cambiaría de LFS de inmediato. S3 tiene mucha sinergia para versionar archivos binarios grandes. También tiene la ventaja de Intelligent-Tiering, que mueve automáticamente los datos a capas de almacenamiento más baratas conforme envejecen. Si restaurar datos de hace 10 años tarda medio día, no importa

    • Pienso igual. No entiendo por qué este no fue el enfoque por defecto desde el principio. Tengo corriendo mi propio servidor pequeño de git LFS, y si git simplemente diera soporte nativo a S3, estaría listo para cambiarme de inmediato

    • En mi trabajo actual estamos cacheando los objetos LFS en un bucket para reducir costos. En cada ejecución de PR obtenemos la lista de archivos con git lfs ls-files, los traemos desde gcp, guardamos los objetos localmente con git lfs checkout, y luego hacemos pull para traer solo lo que falte. Los archivos que no están en caché se vuelven a subir al bucket con gcloud storage rsync. Desde la perspectiva del desarrollador no hace falta configuración adicional; solo se hace pull de los objetos nuevos, y la UI de GitHub tampoco genera confusión sobre el estado del repositorio. Antes pensé en levantar nuestro propio backend de LFS, pero este método resuelve el problema más grande que teníamos por ahora. GitHub cobraba demasiado tráfico cada vez que CI descargaba archivos LFS, y por el límite de caché de 10 GB y la imposibilidad de compartir entre ramas, había que volver a descargarlos cada vez. Incluso quería pagar para ampliar la caché, pero ni siquiera existía esa opción. Para aplicarlo a los desarrolladores, basta con agregar un git hook, así de simple

    • Me pregunto si S3 es un servicio relacionado con Amazon

  • Se mencionan varias cosas malas de Git LFS, pero no estoy de acuerdo con decir que hay vendor lock-in. Como GitHub ofrece un cliente y un servidor abiertos, esa afirmación no me parece justa. Aun así, vale la pena mencionar que LFS no funciona para trabajo offline o tipo sneakernet, aunque no sea un caso muy común. Los large object promisors parecen mover la complejidad del lado cliente de LFS al servidor; al final da la impresión de que solo cambia de lugar la complejidad. Si la estructura es que el servidor git sube los archivos al servidor LFS y al object store, entonces aparecen otros trade-offs. Me da curiosidad qué pasará en servidores git públicos cuando oculten el promisor remote y alguien haga uploads

    • De verdad creo que LFS es bastante malo. La implementación del servidor también es un desastre, y mezcla el contenido de los objetos con la forma de almacenarlos. El mecanismo de opt-in también está muy mal hecho: si lo usas sin pensar mucho, terminas con un archivito de texto en vez del archivo real que querías. No sé si la nueva solución sea mejor, pero sí está claro que LFS no es bueno

    • Otro problema de Git LFS que descubrí hace poco es que la migración contamina incluso los .gitattributes de commits superiores. O sea, si en la secuencia de commits A→B→C solo en C agregaste un archivo grande a LFS, entonces A y B también terminan con un .gitattributes que apunta a archivos LFS que no existen. Eso pasa porque durante la migración .gitattributes se propaga hacia atrás por el historial, sin comprobar si la entidad actual realmente existe en ese commit

    • Antes Git LFS no soportaba SSH, así que era obligatorio conseguir un certificado SSL, y eso elevaba la barrera de entrada para quienes hacían self-hosting en casa. Parece que GitLab añadió recientemente un parche para soporte SSH

  • En una clase de ingeniería de software recomendaban no meter archivos grandes (como medios) en Git, sino ponerlos en un repositorio de artefactos (como Artifactory). Así se pueden distribuir como dependencias snapshot, y el sistema de build puede encargarse de traer automáticamente solo la versión más reciente. Los archivos viejos que se acumulan en local también se limpian enseguida con solo vaciar la caché del sistema de build

    • Esto se siente un poco como una especie de submódulo de git. Si los submódulos realmente resolvieran el problema, la gente ya los estaría usando. Los submódulos de git también soportan shallow clone (link relacionado: https://stackoverflow.com/questions/2144406/how-to-make-shallow-git-submodules). Nunca me ha tocado el problema de archivos grandes, así que me pregunto cuál sería la razón de que este enfoque no funcione. Las desventajas que mencionan en SO no me parecen tan graves

    • Me pregunto si en esa clase también enseñan la arquitectura de sistemas CI/CD. Hoy en día muchos ingenieros junior no están familiarizados con toda la integración entre GitLab, Artifactory, CodeSonar, Anchore, etc.

    • Este enfoque también tiene desventajas. Requiere credenciales adicionales para el sistema CI/CD o para los desarrolladores. Los commits también se vuelven de varios pasos, y primero hay que conocer el ID del artefacto; si intentas automatizar eso con git hooks, al final termina volviéndose tan complejo como git-lfs

  • Este artículo está siendo injusto con LFS. LFS no depende de GitHub y su protocolo también es abierto. Las desventajas de LFS son en buena medida inevitables por ser una extensión de git, y los promisors en realidad son, en esencia, la misma idea que LFS. La diferencia es que al integrarlo dentro de git, la UX mejora un poco

    • Un repositorio que haya usado LFS хотя бы una vez queda bloqueado para siempre. Para reducir el espacio usado, hay que borrar el repositorio completo, y eso ni siquiera se comunica claramente de forma oficial. En mi empresa vivimos esto directamente cuando metimos un archivo grande de base de datos comprimida en LFS mientras analizábamos estadísticas de GitHub
  • Esto no es la solución real. git LFS también es solo una medida temporal, y aunque pongas argumentos de filtro al clonar, eso no resuelve el problema de fondo. git clone es el primer comando que todos aprenden, pero así cada vez habría que recordar el filtro; si te equivocas, solo pierdes tiempo, y aun si sale bien, el repositorio clonado podría no funcionar correctamente. Al final, la única solución de raíz sería cambiar a una estructura que traiga eficientemente primero los archivos más recientes, como rsync. git no suele hacer ese tipo de cambios fundamentales

    • Totalmente de acuerdo. git siempre “resuelve” los problemas agregando otra flag, pero la mayoría de los usuarios ni siquiera conoce esas funciones. Si mejoraran los valores por defecto, podrían resolverlo sin romper compatibilidad

    • el repositorio clonado podría no funcionar correctamente
      En realidad, lo único que falta es el historial de blobs

    • Se dice que rsync resolvió este problema, pero pregunto cómo se vería en la práctica. No hablo del algoritmo, sino de qué aparecería realmente en el sistema de archivos local del usuario cuando hace git clone

    • Si la mayor parte del tamaño del repositorio está en revisiones antiguas, entonces un enfoque tipo rsync que primero traiga solo la versión más reciente es la solución más adecuada para la mayoría de los usuarios

  • Me alegra mucho que se agregue soporte para archivos grandes al core de Git. Aunque fuera una solución externa, la estructura de opt-in iba a ser parecida de todos modos. Como quería reducir al máximo la cantidad de comandos y hacerlo lo más seamless posible, diseñé la API limitándola a los filtros smudge/clean del archivo .gitattributes. Además, colaboré directamente con Atlassian y Microsoft para evitar el vendor lock-in, y Atlassian también ayudó bastante con la API de file locking. LFS se ofrece como open source con soporte compatible en tres hosts

  • Estamos desarrollando oxen para resolver los problemas que tuvimos con git y git-lfs. Mantiene la misma interfaz de git, pero funciona mucho más rápido en entornos con archivos grandes y monorepos con millones de archivos. Ofrecemos CLI y servidor open source, así que si a alguien le interesa, agradeceríamos feedback
    https://github.com/Oxen-AI/Oxen

  • El propio formato de almacenamiento de git también necesita una renovación al estilo de herramientas modernas de backup como restic o borg, con content-defined chunking para archivos y directorios

  • Entre las desventajas de GitLFS faltó mencionar el tema de la autenticación: si no usas SSH-agent, incluso para hacer un push hay que autenticarse varias veces. En mi experiencia, hubo casos en los que tuve que hacerlo más de dos o tres veces