Editar: a diferencia de algunas preguntas similares, como Mover un repositorio SVN de varios GB a Git o /programming/540535/managing-large-binary-files-with-git Mi escenario no involucra varios subproyectos que se puede convertir fácilmente en submuelles de git, ni en algunos archivos binarios muy grandes que sean adecuados para git-annex. Es un repositorio único donde los archivos binarios son el conjunto de pruebas que se acoplan estrechamente al código fuente principal de la misma revisión, al igual que si fueran activos de tiempo de compilación como gráficos.
Estoy investigando el cambio de un antiguo repositorio de código de tamaño medio / grande (50 usuarios, 60k revisiones, 80Gb de historial, 2Gb de copia de trabajo) de svn. A medida que el número de usuarios ha crecido, hay una gran rotación en el tronco, y las características a menudo se extienden en múltiples confirmaciones, lo que dificulta la revisión del código. Además, sin ramificación no hay forma de "bloquear" el código incorrecto, las revisiones solo se pueden hacer después de que se haya comprometido con el enlace troncal. Estoy investigando alternativas. Esperaba que pudiéramos pasar a git, pero tengo algunos problemas.
El problema con el repositorio actual en cuanto a git es el tamaño. Hay una gran cantidad de residuos viejos allí, y limpiarlos con una rama de filtro cuando se convierte en git puede reducir su tamaño en un orden de magnitud, alrededor de 5-10 GB. Esto todavía es demasiado grande. La razón principal del gran tamaño del repositorio es que hay muchos documentos binarios que son entradas para las pruebas. Estos archivos varían entre .5mb y 30mb, y hay cientos. También tienen bastantes cambios. He visto submódulos, git-annex, etc., pero tener las pruebas en un submódulo se siente mal, al igual que tener un anexo para muchos archivos para los que desea un historial completo.
Entonces, la naturaleza distribuida de git es realmente lo que me impide adoptarlo. Realmente no me importa la distribución, solo quiero la ramificación barata y las potentes funciones de fusión. Como supongo que el 99.9% de los usuarios de git lo hacen, utilizaremos un repositorio central bendecido y desnudo.
No estoy seguro de entender por qué cada usuario debe tener un historial local completo al usar git. Si el flujo de trabajo no está descentralizado, ¿qué están haciendo esos datos en los discos de los usuarios? Sé que en versiones recientes de git puedes usar un clon superficial con solo historial reciente. Mi pregunta es: ¿es viable hacer esto como el modo de operación estándar para todo un equipo? ¿Se puede configurar git para que sea siempre superficial para que pueda tener un historial completo solo centralmente, pero los usuarios por defecto solo tienen 1000 revoluciones de historial? La opción para eso, por supuesto, sería convertir 1000 revoluciones a git y mantener el repositorio svn para arqueología. En ese escenario, sin embargo, nos encontraríamos con el mismo problema nuevamente después de los próximos miles de revisiones a los documentos de prueba.
- ¿Qué es un buen mejores prácticas para el uso de git con grandes repositorios que contienen muchos archivos binarios que no quieren que la historia de? La mayoría de las mejores prácticas y tutoriales parecen evitar este caso. Resuelven el problema de unos pocos binarios enormes, o proponen descartarlos por completo.
- ¿Se puede usar la clonación superficial como un modo normal de operación o es un "hack"?
- ¿Podrían usarse los submódulos para el código donde tiene una dependencia estrecha entre la revisión de la fuente principal y la revisión del submódulo (como en dependencias binarias en tiempo de compilación o un conjunto de pruebas unitarias)?
- ¿Qué tan grande es "demasiado grande" para un repositorio git (local)? ¿Deberíamos evitar el cambio si podemos reducirlo a 4GB? 2GB?
Respuestas:
Wow, esa es una pregunta larga (y un problema complejo). Intentaré intentarlo.
Esta es una decisión de diseño central con git. Por las razones exactas que necesitaría preguntarle al autor (Linus Torvalds), pero hasta donde yo sé, la razón principal es la velocidad: tener todo local (en un disco rápido o incluso en caché en RAM) hace que las operaciones en el historial sean mucho más rápidas evitando el acceso a la red.
Ese es el punto en el que pensaría primero. Tener tantos archivos binarios que cambian constantemente en el control de código fuente me parece problemático (incluso con SVN). ¿No puedes usar un enfoque diferente? Ideas:
A diferencia del código fuente, un archivo binario de 3 MB probablemente no esté escrito a mano. Si alguna herramienta / proceso lo genera, considere integrar eso en su compilación, en lugar de almacenar los datos.
Si eso no es práctico, los archivos binarios suelen estar mejor en un repositorio de artefactos (como Artifactory for Maven & co.). Quizás esa sea una opción para ti.
En realidad, esto parece que git-annex encajaría perfectamente. git-annex básicamente le permite almacenar el contenido del archivo fuera de un repositorio de git (el repositorio contiene un marcador de posición). Puede almacenar el contenido del archivo de varias maneras (repositorio central de git, unidad compartida, almacenamiento en la nube ...), y puede controlar qué contenido desea tener localmente.
¿Quizás malinterpretaste cómo funciona git-annex? git-annex almacena el historial completo de todos los archivos que administra, solo le permite elegir qué contenido de archivo desea tener localmente.
Finalmente, sobre sus preguntas:
En mi experiencia, las opciones generalmente son:
Eso podría ser factible; Sin embargo, no creo que esto resuelva su problema:
Eso depende de la estructura del repositorio (pocos / muchos archivos, etc.), de lo que desea hacer, de qué tan robustas son sus computadoras y de su paciencia :-).
Para darle una idea rápida: en mi computadora portátil (nueva pero de baja especificación), la confirmación de un archivo de 500 MB demora entre 30 y 60 segundos. Solo el historial de la lista (git log, etc.) no se ve afectado por los archivos grandes; cosas como "git log -S", que debe escanear el contenido del archivo, son muy lentas; sin embargo, la velocidad está dominada principalmente por E / S, por lo que no es realmente culpa de git.
En un repositorio de 3 GB con un puñado de revisiones, "git log -S" tarda aproximadamente un minuto.
Entonces diría que un par de GB está bien, aunque no es ideal. Probablemente, más de 10-20 GB lo están impulsando, pero podría ser factible, tendría que probarlo.
fuente
Pasar a git no resolverá estos problemas, son problemas en la forma en que usa la herramienta y si usa git de la misma manera, los problemas permanecerán.
Puede ramificarse en svn con la misma facilidad en git, y la fusión generalmente es igual de fácil y tiene las mismas dificultades. Git fue diseñado para trabajar con el código fuente del núcleo, por lo que hizo algunas suposiciones que pueden no aplicarse en todos los casos, como la suya con grandes binarios e historias masivas. La intención detrás de un DVCS es que cada usuario trabaje efectivamente solo y solo colabore después, es decir, que tengan su propio repositorio (una copia), trabajen como quieran y luego envíen los cambios a cualquier otra persona que lo desee. Un sistema federado utilizado en el desarrollo del kernel de Linux es perfecto para esto: empuja sus cambios al siguiente tipo de la cadena que lo fusiona con su base de código y luego lo empuja al siguiente tipo hasta que llegue a Linus que lo publica en el lanzamiento. La mayoría de los equipos usan git de manera similar, pero con solo un tipo de upstream que a menudo es un repositorio 'gold' del lado del servidor,
Así que primero buscaría cambiar su flujo de trabajo, solo migrar a git una vez que tenga una mejor manera de trabajar. Implemente la ramificación y la fusión en SVN, si no cambia el nombre de los archivos o directorios, la fusión va bastante bien.
fuente
Mire en la lista de correo de GCC. Migrando el CCG árbol fuente del compilador de de SVN a GIT se analiza en este momento (agosto y septiembre de 2015), mientras se mantiene la historia de GCC. Consulte, por ejemplo, el repositorio de la maquinaria de conversión y los criterios de aceptación para los hilos de correo de conversión git ; encontrará referencias a herramientas y procedimientos relacionados con la conversión (que no es tan sencillo como parece; la conversión de un historial de código tan grande necesita 36 horas y aproximadamente 64 Gbytes de RAM, IIRC)
fuente
Si la conversión de todo el repositorio SVN en Git da como resultado un gran repositorio que no es factible clonar, puede intentar usar SubGit para crear espejos Git más pequeños para ciertas partes de su repositorio Subversion.
Por ejemplo, puede importar y sincronizar algún subdirectorio de su repositorio SVN
http://domain/repos/trunk/project/src
:Para más detalles sobre el uso de SubGit, consulte su documentación .
Tan pronto como tenga Git mirror de ese directorio, puede usar el repositorio Git para enviar nuevos cambios que se reflejen inmediatamente en el repositorio SVN. Dado que solo sincroniza cierta parte del repositorio SVN que reduce significativamente el tamaño del repositorio Git convertido y aún puede crear ramas, fusionarlas, emplear cualquier flujo de trabajo desde el lado de Git.
Alternativamente, puede importar todo el repositorio SVN pero excluir archivos grandes de la sincronización:
El repositorio Git resultante debería tener un tamaño razonable y los desarrolladores aún pueden usar Git para enviar sus cambios al repositorio Subversion.
Tenga en cuenta que esta solución debería funcionar bien para usted si está listo para mantener el servidor Subversion en funcionamiento y usar Git junto con su repositorio SVN.
Descargo de responsabilidad: soy uno de los desarrolladores de SubGit; SubGit es un software comercial con varias opciones gratuitas disponibles.
fuente
Me acercaré a su situación de la siguiente manera:
1) Inicialice un repositorio git en el mismo directorio que su repositorio SVN. Hacer
git init
ygit remote add origin
para comenzar ese repositorio de git. De esa manera, puede continuar comprometiéndose en SVN y git por separado sin tener que lidiar con una conversión completa de uno a otro hasta que esté listo.2) Use activamente las herramientas bfg y filter-branch para intentar reducir su repositorio git, como se explica aquí: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html
3) Use git-annex, o Git LFS, o simplemente un servidor de almacenamiento externo para sus binarios grandes (transporte de archivos usando scripts de shell en tiempo de compilación).
4) Una vez que se sienta cómodo con la estrategia de fusión / ramificación en su repositorio git, y se sienta cómodo con el tamaño de su repositorio git, podrá realizar una migración completa de su svn a git.
Espero que esto ayude.
fuente