Para muchos proyectos el manejo de archivos u objetos binarios es algo complicado de gestionar en repositorios Git, pero existe una funcionalidad que puede salvar el día.
Los problemas
Integración
El problema radica en que existen archivos binarios, los cuales Git no puede integrar automáticamente los cambios. Como saben, Git integra cambios basados en las líneas modificadas de los archivos… Pero, en los casos en los que estos archivos tienen estructuras definidas (binarios) Git no puede evaluar ni integrar los cambios de forma automática. Acá, el problema continúa, pues tampoco los humanos podemos hacerlo. La única forma es la coordinación y replicación de cambios de forma manual en los archivos. Esto además de desastroso es una pesadilla a la hora de mantener la integridad de los cambios en las aplicaciones.
El repositorio
En Git, los repositorios locales son copias exactas y completas del repositorio remoto, esto es bastante útil para trabajar en entornos sin conexión o bien no requerir de esta para navegar entre ramas, históricos y tags. Pero como los archivos binarios no puede ser segmentados y trazar únicamente los cambios en las líneas afectadas, Git pretende que, si así lo deseamos, podamos tener una copia de todos los archivos en cualquier momento de la historia del repositorio, pero con los binarios la única forma que tiene Git de lograr esto, es copiar el archivo completo, y no solo los cambios que sufrió desde la última versión guardada.
Esta situación ocasiona que, al clonar un repositorio, Git deba copiar todas y cada una de las copias de ese archivo binario (solo por si en algún momento las requerimos). Acá el problema es que si interactuamos con un repositorio con archivos binarios (push, pull o clon) por red deberán pasar copias de todas las versiones que todos y cada uno de estos archivos han tenido a lo largo de la vida del repositorio. Por lo que nuestro disco duro, nuestra conexión de red y nuestra paciencia sufran al extremo por mover todos estos archivos y sus versiones.
La solución
Estos escenarios con los archivos binarios no son tan comunes, o en ocasiones se aprende a convivir con ellos, pues suelen ser archivos que sufren pocas modificaciones o solo son modificados por un único desarrollador en el equipo.
Sin embargo, otros son los escenarios donde de no existir soluciones a estos problemas Git no sería opción. Y para esto apareció Git Large File Storage (Git LFS).
Git LFS parte del hecho de que existen estos archivos y que en mayor o menor parte son necesarios dentro de los repositorios. Entonces, estos archivos son tratados por Git de una forma levemente diferente para facilitar a los usuarios del repositorio el trabajo (push, pull, clone, etc) y aún así, garantizar que siempre podamos contar con todas las versiones de un archivo en la historia del repositorio.
Git LFS
Integración
El primer problema expuesto es la integración de cambios en archivos binarios, Git LFS lo soluciona mediante bloqueos de archivos en el repositorio, de forma que cuando algún integrante del equipo va a realizar cambios en un archivo binario, debe solicitar el “bloqueo” del archivo para que ningún otro miembro modifique el archivo (al menos en el repositorio) y de esta forma los otros usuarios no pueden modificar los archivos bloqueados o bien consultar los bloqueos para prevenir conflictos casi imposibles de resolver.
Estos bloqueos funcionan a nivel de repositorio, por lo que, tras el cambio, este se puede integrar y replicar fácilmente por las ramas que corresponde sin generar conflictos, una vez integrado el dueño del bloqueo lo retira y permite que los demás miembros continúen sus cambios sobre esta versión.
Repositorio
Con esta funcionalidad, Git identifica los archivos que hemos marcado previamente que tienen este comportamiento de archivos binarios, y a la hora de interactuar con el repositorio (pull, clone) nos trae las últimas versiones de los archivos binarios, con esto no descargamos todas las versiones de un archivo que no necesitamos.
El contr de esto, es que requeriríamos de conexión al repositorio para consultar versiones anteriores del archivo, pero la ventaja es que, de momento, solo se descargan las versiones que necesitamos y podemos trabajar sin esperar mucho por la descarga de repositorios gigantescos (recuerda que multimedia, texturas y animaciones pueden pesar hasta Terabytes en un repositorio).
¿Cómo lo uso?
Ok, es muy probable que no necesites nada adicional y que solo requieras activarlo en tu repositorio.
En caso de que sea un repositorio nuevo, es más simple pues solo lo habilitas y listo, en caso de que ya el repositorio exista deberás correr algunos comandos para migrar estos archivos al modo LFS. Para efectos de este post, hablaremos de repositorios nuevos.
Si eres usuario Windows, ya tu cliente Git tiene LFS instalado, si utilizas GNU/Linux, debes instalar el paquete “git-lfs” mediante el gestor de paquetes de su distribución.
El primer comando por correr es «git lfs install», este comando va a configurar todo para que el repositorio empiece a reconocer los archivos que quieres trabajar como binarios (si, al final tu decides cuales van a tener este trato especial y cuales aun siendo binarios continúan con el mismo trato de siempre), esto va a crear el archivo de atributos (el cual debes agregar (add) y versionar (commit + push)), este archivo va a contener los detalles de los archivos que vas a administrar bajo esta función (LFS).
Bien, ahora lo que debes hacer es marcar los tipos de archivos que tratarás como binarios con LFS, para eso ejecutas el comando «git lfs track “*.extension”». Con esto, Git sabrá que estas marcando todos los archivos de esa extensión como binarios y les dará ese trato diferenciado.
Este comando “Track” también funciona con archivos puntuales o con directorios, el comando es el mismo, en lugar de poner un Wildcard con la extensión, coloca el archivo o directorio.
De aquí en adelante crea, modifica, versiona o interactúa con el repositorio de la forma “normal” como siempre lo haces.
Comandos adicionales
Te dejo una lista de más comandos que puedan serte útiles para trabajar con LFS
Comando | Descripción |
---|---|
git lfs install | Configura el repositorio para trabajar con LFS |
git lfs fsck | Verifica la consistencia de los archivos |
git lfs lock file.ext | Bloquea el archivo indicado para que no sea modificado por otro usuario |
git lfs locks | Muestra la lista de los archivos bloqueados en el repositorio |
git lfs prune | Borra versiones anteriores de los archivos binarios en el repositorio local (limpiando espacio) |
git lfs track “*.ext” | Indica al repositorio el manejo de los archivos.ext como binarios |
git lfs unlock file.ext | Elimina el bloqueo sobre un archivo, permitiendo que otros usuarios los modifiquen |
git lfs untrack “*.ext” | Indica al repositorio que deje de tratar los archivos indicados como binarios |
Consideraciones importantes
Acá te dejo también algunas consideraciones que debes tener presente para usar Git LFS
-
En todos los sabores de Git debe funcionar Git LFS, pues forma parte del estándar Git, sin embargo, la experiencia del usuario con esta función puede variar de Git en Git. Por lo que te aconsejo que revises documentación y hagas muchas pruebas sobre el Git que utilizas (Azure DevOps, GitLab, Github, etc).
-
Los repositorios con binarios tienden a consumir mucho almacenamiento por su naturaleza, revisa si tu servicio de Git te va a cobrar por almacenamiento, o si lo auto hospedas, asegúrate de tener espacio para que tus repositorios crezcan.
-
Usualmente los clientes Git en Linux podrían no tener LFS, por lo que debes instalarlo por aparte con el gestor de paquetes de tu distribución.
-
Siempre asegúrate de hacer las suficientes pruebas y que todos los otros miembros del equipo sepan usar esta funcionalidad antes de empezar a trabajar con LFS.
Conclusión
Git LFS es para los que la necesitan, la funcionalidad vital de esta herramienta, sin ella, no se podría utilizar Git como sistema de control de versiones. Si bien, no es una funcionalidad que se requiera en todos los proyectos, si existen escenarios donde es indispensable.
En este post no se mencionaron aplicaciones de frontend y hay que recordar que estas llevan muchos recursos que perfectamente caben dentro de este modelo, como imágenes, íconos, multimedia, fuentes, etc. Y aunque quizás estos archivos no te den dolores de cabeza, no está de más que los implementes con Git LFS.