tipos tag remove practices etiquetas crear best git git-submodules git-subtree

remove - git tag best practices



Administración de fuentes de terceros y binarios utilizados por el código bajo el control de fuente (3)

Tengo una base de código grande bajo control de código fuente (era subversión, ahora git). Para compilar el código y ejecutar las pruebas, uso un conjunto de bibliotecas de terceros. Estas bibliotecas se pueden dividir en pocas categorías.

  • Solo binarios
  • Fuentes de terceros
  • Fuentes de terceros + modificaciones locales.

Cada biblioteca tiene sus configuraciones {Windows, Linux} X {depurar, lanzar} X {32 bits, 64 bits}. Además, estas bibliotecas evolucionan con el tiempo y las diferentes versiones de mi proyecto utilizan diferentes versiones / compilaciones de estas bibliotecas.

Mi pregunta es ¿cuál es la mejor manera de almacenar estos terceros?

Aquí está mi conjunto de preferencias:

  1. Mantener el tamaño del repositorio de origen del proyecto pequeño
  2. Mantenga la fuente del proyecto sincronizada con los terceros para que siempre pueda compilar y ejecutar una versión antigua.
  3. Fácil de manejar
  4. Plataforma cruzada

Probé y pensé en varias soluciones, pero ninguna fue satisfactoria:

  1. Use un script versionado para obtener los archivos binarios de un servidor ftp administrado manualmente que contiene todas las versiones de las bibliotecas. Esto funciona, pero requiere una administración cuidadosa de la estructura de directorios en el servidor. Es propenso a errores, ya que alguien podría sobrescribir uno de los binarios con una nueva compilación.
  2. Externos de SVN: en el momento, los externos de SVN no podían referirse a una etiqueta específica. Hoy estoy usando git.
  3. Submódulos de Git: extrae todo el repositorio externo, que puede ser enorme. Alternativamente, se requiere administrar un repositorio separado para cada biblioteca. El submódulo apunta a una etiqueta específica, lo que significa que obtengo todos los elementos externos, cuando necesito solo algunos, o que imito algún sistema de archivos extraño en el árbol git.

Para mí es claro que las fuentes de terceros deben almacenarse en git en una sucursal del proveedor, pero los archivos binarios y los encabezados son una historia diferente.


Hemos optado por una variante de su opción 3. La opción 1 me parece que es equivalente a la opción 3, pero con más esfuerzos de implementación / prueba de su parte y, por lo tanto, más posibilidades de salir mal.

En última instancia, si desea poder recrear exactamente una compilación, necesitará que sus versiones externas (incluidos los binarios) se versionen junto con el código y se alojen localmente. Y los submódulos de git harán un buen trabajo al hacer esto por ti.


Para las fuentes de terceros, creo que los submódulos son exactamente lo que estás buscando. Si no desea requerir todo el historial de subida en cada clon, realice una interfaz del repositorio de subida con el suyo propio, que contiene una rama artesanal con el historial necesario. Mira git commit-tree para ver cómo hacer eso, es fácil. Los ID de confirmación no coincidirán con el autoritario en sentido ascendente, pero la ID del árbol lo hará.

Para los binarios, git annex parece ser la forma más recomendada para almacenar contenido que no encaja bien con el enfoque de fuente diferente de git. No lo he usado, pero el diseño parece estar listo para el uso en producción, también admite múltiples repositorios independientes y parece tan conveniente como podría serlo.

Esto no es llave en mano, por lo que realmente no cumple con su tercera parte, pero elimina el resto y lo que necesita es el uso sencillo de herramientas básicas.


Una solución justa para mi problema es git-subtree que recientemente se fusionó con git de línea principal. Proporciona un equilibrio justo entre mis requisitos y las limitaciones de la plataforma. Ahora tengo múltiples repositorios para los externos (cada uno tiene una rama de proveedor así como una rama de cambios locales) y cada repositorio de proyecto toma partes de estos externos en subcarpetas. Para mantener las cosas organizadas, mantengo las carpetas ''bin'' y ''lib'' que contienen enlaces blandos a los archivos / carpetas apropiados en la subcarpeta externa.

git-subtree permite fusionar un subárbol de un repositorio externo en una subcarpeta. La subcarpeta se puede combinar de un lado a otro con el repositorio externo.

Pros contras:

  1. Repositorio pequeño: el repositorio no es tan pequeño como me gustaría que fuera, pero contiene solo las partes necesarias de los repositorios externos. Para ahorrar espacio trato de mantener pequeños los árboles externos. Considero que es un buen precio para pagar cuando, a cambio, obtengo simplicidad y robustez; como cargar y actualizar un proyecto es un simple git pull y todos los datos relacionados con el proyecto están contenidos en un solo repositorio

  2. Sincronización de proyectos / externos: dado que el proyecto y los aspectos externos se versionan en el mismo repositorio, puedo verificar cualquier rama / etiqueta que desee y espero que funcione.

  3. Simplicidad: el trabajo del día a día es sencillo. Actualizar el repositorio externo, crear uno nuevo o cambiar a una versión diferente del externo puede ser complicado y requiere una sintaxis especial. Sin embargo esto sucede demasiado. Lo mejor es que uno puede agregar un nuevo externo a este proyecto primero y solo después dividirlo (usando git-subárbol) en su propio repositorio.

  4. Multiplataforma - bueno es git

  5. Binarios: decidí evitar tener binarios y proporcionar Makefiles en su lugar. Llegué a esta decisión ya que algunos de mis elementos externos dependen de otros aspectos externos, lo que hace que sea muy difícil crear un binario que no cambie muy a menudo. Para algunos externos, almaceno los binarios debido a tiempos de construcción muy largos.

Estructura:

/root /External /External1 (git-subtree from [email protected]:External1 v1.0) /External2 (git-subtree from [email protected]:External2 v0.7) /lib /libExternal1.a -> ../External/External1/libExternal1.a /libExternal2.a -> ../External/External1/libExternal2.a /include /External1 -> ../External/External1/include /External2 -> ../External/External2/include