Estoy buscando opiniones sobre cómo manejar archivos binarios grandes de los que depende mi código fuente (aplicación web). Actualmente estamos discutiendo varias alternativas:
- Copie los archivos binarios a mano.
- Pro: no estoy seguro.
- Contra: Estoy totalmente en contra de esto, ya que aumenta la probabilidad de errores al configurar un nuevo sitio / migrar el antiguo. Construye otro obstáculo para tomar.
- Adminístralos a todos con Git .
- Pro: elimina la posibilidad de "olvidar" copiar un archivo importante
- Contra: Bloquea el repositorio y disminuye la flexibilidad para administrar la base de código y las comprobaciones, clones, etc. tardarán bastante.
- Repositorios separados.
- Pro: retirar / clonar el código fuente es más rápido que nunca, y las imágenes se archivan correctamente en su propio repositorio.
- Contra: elimina la sencillez de tener el único repositorio de Git en el proyecto. Seguramente presenta algunas otras cosas en las que no he pensado.
¿Cuáles son sus experiencias / pensamientos con respecto a esto?
Además: ¿Alguien tiene experiencia con múltiples repositorios Git y los administra en un solo proyecto?
Los archivos son imágenes de un programa que genera archivos PDF con esos archivos. Los archivos no cambiarán muy a menudo (como en años), pero son muy relevantes para un programa. El programa no funcionará sin los archivos.
Respuestas:
Si el programa no funciona sin los archivos, parece que dividirlos en un repositorio separado es una mala idea. Tenemos grandes conjuntos de pruebas que dividimos en un repositorio separado, pero esos son realmente archivos "auxiliares".
Sin embargo, es posible que pueda administrar los archivos en un repositorio separado y luego usarlos
git-submodule
para incorporarlos a su proyecto de una manera sensata. Entonces, todavía tendría el historial completo de toda su fuente, pero, según tengo entendido, solo tendría la única revisión relevante de su submódulo de imágenes. Lagit-submodule
instalación debería ayudarlo a mantener la versión correcta del código en línea con la versión correcta de las imágenes.Aquí hay una buena introducción a los submódulos de Git Book.
fuente
Descubrí git-annex recientemente que me parece increíble. Fue diseñado para administrar archivos grandes de manera eficiente. Lo uso para mis colecciones de fotos / música (etc.). El desarrollo de git-annex es muy activo. El contenido de los archivos se puede eliminar del repositorio de Git, solo Git realiza un seguimiento de la jerarquía del árbol (a través de enlaces simbólicos). Sin embargo, para obtener el contenido del archivo, es necesario un segundo paso después de tirar / empujar, p.
Hay muchos comandos disponibles, y hay una gran documentación en el sitio web. Un paquete está disponible en Debian .
fuente
git annex
está disponible en Windows . Si alguien lo ha probado en Windows, ¡me gustaría saber sobre su experiencia!Otra solución, desde abril de 2015, es Git Large File Storage (LFS) (por GitHub).
Utiliza git-lfs (consulte git-lfs.github.com ) y se prueba con un servidor que lo admite: lfs-test-server :
puede almacenar metadatos solo en el repositorio de git y el archivo grande en otro lugar.
fuente
lfs-test-server
se declara que no es para uso en producción. En realidad, estoy trabajando en el servidor de producción LFS ( github.com/artemkin/git-lfs-server ). Está en progreso, pero ya es útil, y lo estamos probando internamente.Eche un vistazo a git bup, que es una extensión de Git para almacenar de forma inteligente binarios grandes en un repositorio de Git.
Desea tenerlo como un submódulo, pero no tendrá que preocuparse de que el repositorio sea difícil de manejar. Uno de sus casos de uso de muestra es almacenar imágenes de VM en Git.
En realidad, no he visto mejores tasas de compresión, pero mis repositorios no tienen binarios realmente grandes.
Su experiencia puede ser diferente.
fuente
También puedes usar git-fat . Me gusta que solo depende del stock de Python y
rsync
. También es compatible con el flujo de trabajo Git habitual, con los siguientes comandos autoexplicativos:Además, debe registrar un archivo .gitfat en su repositorio y modificar sus atributos .gitat para especificar las extensiones de archivo que desea
git fat
administrar.Agregue un binario usando el normal
git add
, que a su vez invoca engit fat
función de sus reglas de atributos.Finalmente, tiene la ventaja de que la ubicación donde se almacenan realmente sus archivos binarios se puede compartir entre repositorios y usuarios y admite todo lo que
rsync
haga.ACTUALIZACIÓN: No use git-fat si está usando un puente Git-SVN. Terminará eliminando los archivos binarios de su repositorio de Subversion. Sin embargo, si está utilizando un repositorio Git puro, funciona de maravilla.
fuente
Usaría submódulos (como Pat Notz) o dos repositorios distintos. Si modifica sus archivos binarios con demasiada frecuencia, trataría de minimizar el impacto del enorme repositorio que limpia el historial:
Tuve un problema muy similar hace varios meses: ~ 21 GB de archivos MP3, sin clasificar (nombres incorrectos, ID3 incorrectos, no sé si me gusta ese archivo MP3 o no ...), y replicado en tres computadoras.
Utilicé un disco duro externo con el repositorio principal de Git, y lo cloné en cada computadora. Luego, comencé a clasificarlos de la manera habitual (empujar, tirar, fusionar ... eliminar y renombrar muchas veces).
Al final, solo tenía ~ 6 GB de archivos MP3 y ~ 83 GB en el directorio .git. Solía
git-write-tree
ygit-commit-tree
para crear una nueva confirmación, sin antepasados de confirmación, y comencé una nueva rama que apuntaba a esa confirmación. El "registro de git" para esa rama solo mostró una confirmación.Luego, eliminé la rama anterior, mantuve solo la nueva rama, eliminé los registros de referencia y ejecuté "git prune": después de eso, mis carpetas .git pesaron solo ~ 6 GB ...
Podrías "purgar" el enorme repositorio de vez en cuando de la misma manera: tu "git clone" será más rápido.
fuente
La solución que me gustaría proponer se basa en ramas huérfanas y un ligero abuso del mecanismo de etiqueta, en lo sucesivo denominado * almacenamiento binario de etiquetas huérfanas (OTABS)
TL; DR 12-01-2017 Si puede usar el LFS de github o algún otro tercero, debería hacerlo. Si no puedes, sigue leyendo. Tenga en cuenta que esta solución es un truco y debe tratarse como tal.
Propiedades deseables de OTABS
git pull
egit fetch
, incluso,git fetch --all
siguen siendo eficientes en ancho de banda , es decir, no todos los binarios grandes se extraen del control remoto de forma predeterminada.Propiedades indeseables de OTABS
git clone
potencialmente ineficiente (pero no necesariamente, dependiendo de su uso). Si implementa esta solución, es posible que tenga que aconsejar a sus colegas que la usen engit clone -b master --single-branch <url>
lugar de hacerlogit clone
. Esto se debe a que, por defecto, git clone literalmente clona todo el repositorio, incluidas las cosas en las que normalmente no querría desperdiciar su ancho de banda, como las confirmaciones sin referencia. Tomado de SO 4811434 .git fetch <remote> --tags
ancho de banda sea ineficiente, pero no necesariamente el almacenamiento sea ineficiente. Siempre puede aconsejar a sus colegas que no lo usen.git gc
truco para limpiar su repositorio de cualquier archivo que ya no desee.Agregar los archivos binarios
Antes de comenzar, asegúrese de haber confirmado todos los cambios, su árbol de trabajo está actualizado y su índice no contiene ningún cambio no confirmado. Puede ser una buena idea empujar todas sus sucursales locales a su control remoto (github, etc.) en caso de que ocurra un desastre.
git checkout --orphan binaryStuff
Hará el truco. Esto produce una rama que está completamente desconectada de cualquier otra rama, y la primera confirmación que realizará en esta rama no tendrá padre, lo que la convertirá en una confirmación raíz.git rm --cached * .gitignore
.rm -fr * .gitignore
. El.git
directorio interno permanecerá intacto porque el*
comodín no coincide.git fetch
obstruyendo su conexión. Puede evitar esto presionando una etiqueta en lugar de una rama. Esto aún puede afectar el ancho de banda y el almacenamiento del sistema de archivos de su colega si tiene la costumbre de escribirgit fetch <remote> --tags
, pero siga leyendo para obtener una solución alternativa. Siga adelante ygit tag 1.0.0bin
git push <remote> 1.0.0bin
.git branch -D binaryStuff
. Su confirmación no se marcará para la recolección de basura, porque una etiqueta huérfana apuntando sobre ella1.0.0bin
es suficiente para mantenerla viva.Retirar el archivo binario
git checkout 1.0.0bin -- VeryBigBinary.exe
.1.0.0bin
descargada, en cuyo caso deberá hacerlo degit fetch <remote> 1.0.0bin
antemano.VeryBigBinary.exe
en su maestro.gitignore
, para que nadie en su equipo contamine la historia principal del proyecto con el binario por accidente.Eliminar completamente el archivo binario
Si decide purgar por completo VeryBigBinary.exe de su repositorio local, su repositorio remoto y los repositorios de su colega, simplemente puede:
git push <remote> :refs/tags/1.0.0bin
git tag -l | xargs git tag -d && git fetch --tags
. Tomado de SO 1841341 con ligera modificación.git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"
. También eliminará todos los otros commits sin referencia. Tomado de SO 1904860git clone -b master --single-branch <url>
lugar de hacerlogit clone
.2.0.0bin
. Si le preocupa que sus colegas escribangit fetch <remote> --tags
, puede nombrarlo nuevamente1.0.0bin
. Esto asegurará que la próxima vez que busquen todas las etiquetas, las antiguas1.0.0bin
no tengan referencia y se marquen para la recolección de basura posterior (utilizando el paso 3). Cuando intenta sobrescribir una etiqueta en el control remoto, debe usarla-f
así:git push -f <remote> <tagname>
Epílogo
OTABS no toca su maestro ni ninguna otra rama de desarrollo / código fuente. Los hashes de commit, toda la historia y el pequeño tamaño de estas ramas no se ven afectados. Si ya ha hinchado su historial de código fuente con archivos binarios, tendrá que limpiarlo como un trabajo separado. Este script puede ser útil.
Confirmado para trabajar en Windows con git-bash.
Es una buena idea aplicar un conjunto de trucos estándar para hacer que el almacenamiento de archivos binarios sea más eficiente. La ejecución frecuente de
git gc
(sin ningún argumento adicional) hace que git optimice el almacenamiento subyacente de sus archivos mediante el uso de deltas binarios. Sin embargo, si es improbable que sus archivos sigan siendo similares de commit a commit, puede desactivar por completo los deltas binarios. Además, dado que no tiene sentido comprimir archivos ya comprimidos o cifrados, como .zip, .jpg o .crypt, git le permite desactivar la compresión del almacenamiento subyacente. Desafortunadamente, es una configuración de todo o nada que también afecta su código fuente.Es posible que desee realizar un script de partes de OTABS para permitir un uso más rápido. En particular, los pasos de guión 2-3 de Eliminar completamente archivos binarios en un
update
gancho git podrían dar una semántica convincente pero quizás peligrosa para git fetch ("buscar y eliminar todo lo que está desactualizado").Es posible que desee omitir el paso 4 de Eliminar completamente los archivos binarios para mantener un historial completo de todos los cambios binarios en el control remoto a costa de la hinchazón del repositorio central. Los repositorios locales permanecerán esbeltos con el tiempo.
En el mundo Java, es posible combinar esta solución
maven --offline
para crear una compilación fuera de línea reproducible almacenada completamente en su control de versiones (es más fácil con Maven que con Gradle). En el mundo de Golang, es posible desarrollar esta solución para administrar su GOPATH en lugar de hacerlogo get
. En el mundo de Python, es posible combinar esto con virtualenv para producir un entorno de desarrollo autónomo sin depender de servidores PyPi para cada compilación desde cero.Si los archivos binarios cambian muy a menudo, al igual que los artefactos de construcción, que podría ser una buena idea para la escritura de una solución que almacena 5 versiones más recientes de los artefactos en las etiquetas huérfanas
monday_bin
,tuesday_bin
, ...,friday_bin
y también una etiqueta huérfano para cada versión1.7.8bin
2.0.0bin
, etc. Puede rotarweekday_bin
y eliminar binarios antiguos a diario. De esta manera obtienes lo mejor de dos mundos: mantienes el historial completo de tu código fuente pero solo el historial relevante de tus dependencias binarias. También es muy fácil obtener los archivos binarios para una etiqueta determinada sin obtener el código fuente completo con todo su historial:git init && git remote add <name> <url> && git fetch <name> <tag>
debería hacerlo por usted.fuente
git gc
" - dejó de leer allí mismo. ¿Por qué alguien renunciaría a su último cinturón de seguridad en favor de algún truco?git gc
no es inseguro de ejecutar. Todas sus confirmaciones pendientes se mantendrán de forma segura en el disco duro durante al menos 30 días de forma predeterminada: git-scm.com/docs/git-gcgit push <remote> 1.0.0bin
-remote: error: GH001: Large files detected. You may want to try Git Large File Storage
. Parece que tal vez GitHub ya no es compatible con esto? El binario en cuestión tenía un tamaño de 100 MB.En mi opinión, si es probable que modifique a menudo esos archivos grandes, o si tiene la intención de hacer mucho
git clone
ogit checkout
, entonces debería considerar seriamente usar otro repositorio de Git (o tal vez otra forma de acceder a esos archivos).Pero si trabaja como nosotros, y si sus archivos binarios no se modifican a menudo, entonces el primer clon / pago será largo, pero después de eso debería ser tan rápido como desee (teniendo en cuenta que sus usuarios siguen usando el primer repositorio clonado) tenía).
fuente
SVN parece manejar deltas binarios de manera más eficiente que Git.
Tuve que decidir sobre un sistema de versiones para la documentación (archivos JPEG, archivos PDF y archivos .odt). Acabo de probar agregar un archivo JPEG y rotarlo 90 grados cuatro veces (para verificar la efectividad de los deltas binarios). El repositorio de Git creció un 400%. El repositorio de SVN creció solo un 11%.
Parece que SVN es mucho más eficiente con archivos binarios.
Entonces, mi elección es Git para el código fuente y SVN para archivos binarios como documentación.
fuente
git gc
el tamaño total del repositorio git se redujo a 184 KB. Luego cambié un solo píxel de blanco a negro y comprometí este cambio, el tamaño total del repositorio git aumentó a 388 KB, y después de quegit gc
el tamaño del repositorio git total se redujo a 184 KB. Esto muestra que git es bastante bueno para comprimir y encontrar deltas de archivos binarios.git clone --filter
de Git 2.19 + clones poco profundosEsta nueva opción podría eventualmente convertirse en la solución final al problema del archivo binario, si los desarrolladores de Git y GitHub lo hacen lo suficientemente fácil de usar (lo que posiblemente todavía no hayan logrado para submódulos, por ejemplo).
En realidad, permite recuperar solo los archivos y directorios que desea para el servidor, y se introdujo junto con una extensión de protocolo remoto.
Con esto, primero podríamos hacer un clon superficial y luego automatizar qué blobs para buscar con el sistema de compilación para cada tipo de compilación.
Incluso ya existe una
--filter=blob:limit<size>
que permite limitar el tamaño máximo de blob para obtener.He proporcionado un ejemplo mínimo detallado de cómo se ve la función: ¿Cómo clono un subdirectorio solo de un repositorio Git?
fuente
Personalmente, me he encontrado con fallas de sincronización con Git con algunos de mis hosts en la nube una vez que los datos binarios de mis aplicaciones web se ubicaron por encima de la marca de 3 GB . En ese momento, consideré BFT Repo Cleaner , pero me pareció un truco. Desde entonces, comencé a mantener los archivos fuera del ámbito de aplicación de Git, en su lugar, aproveché herramientas especialmente diseñadas como Amazon S3 para administrar archivos, versiones y copias de seguridad.
Si. Los temas de Hugo se manejan principalmente de esta manera. Es un poco kudgy, pero hace el trabajo.
Mi sugerencia es elegir la herramienta adecuada para el trabajo . Si es para una empresa y está administrando su línea de código en GitHub, pague el dinero y use Git-LFS. De lo contrario, podría explorar opciones más creativas, como el almacenamiento descentralizado y cifrado de archivos usando blockchain .
Las opciones adicionales a considerar incluyen Minio y s3cmd .
fuente
Echa un vistazo a camlistore . No está realmente basado en Git, pero me parece más apropiado para lo que tienes que hacer.
fuente