2012-07-03 11 views
28

Tengo una gran base de código bajo control de código fuente (era subversión, ahora git). Para compilar el código y ejecutar las pruebas, utilizo un conjunto de bibliotecas de terceros. Estas bibliotecas se pueden dividir en pocos categoriesLAdministrar fuentes y binarios de terceros usados ​​por código bajo el control de código fuente

  • Binarios sólo
  • fuentes de 3 ª parte
  • fuentes de 3 ª parte + modificaciones locales

Cada biblioteca tiene su {Windows, Linux} X {depuración, release} Configuraciones X {32bit, 64bit}. Además, estas bibliotecas evolucionan con el tiempo y las diferentes versiones de mi proyecto utilizan diferentes versiones/construcciones 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 de la fuente repositorio del proyecto pequeña
  2. mantenga la fuente de proyecto en sincronía con las 3 partes por lo que siempre se puede compilar y ejecutar y la versión antigua
  3. simple para gestionar
  4. Cruz plataforma

probé y el pensamiento de varias soluciones pero ninguna fue satisfactoria:

  1. Utilice un script versionado para buscar los archivos binarios desde un servidor ftp administrado manualmente que contiene todas las versiones de las bibliotecas. Esto funciona, pero requiere una administración cuidadosa de la estructura del directorio en el servidor. Es propenso a errores ya que alguien puede sobreescribir uno de los binarios con una nueva compilación.
  2. SVN Externals - En el momento SVN externos no podía hacer referencia a una etiqueta específica. Hoy estoy usando git.
  3. Submódulos de Git: extrae todo el repositorio externo, que puede ser enorme. Alternativamente, 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 solo necesito algunos, o imito algún sistema de archivos extraño en el árbol git.

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

+1

recomendaría contra la que caben estas dependencias en sus propios repositorios. ¿Has considerado algo así como Maven? No tengo idea qué idioma estás usando, pero creo que existe algo similar para la mayoría de las plataformas principales. – Dan

+0

¿Está incluyendo los binarios en el repositorio fuente ocupando realmente tanto espacio? – StingyJack

+0

Algunos de los binarios son bastante grandes. Sin embargo, el problema real es tener múltiples versiones de los binarios en el repositorio del proyecto y compartir los mismos binarios versionados entre múltiples proyectos. – Xyand

Respuesta

13

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

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

Pros/Contras:

  1. Pequeño repositorio - El repositorio no es tan pequeña como me gustaría que fuera pero contiene sólo las partes necesarias de los repositorios externos. Para ahorrar espacio, trato de mantener pequeños los árboles externos. Considero que es un buen precio a pagar cuando a cambio recibo simplicidad y solidez; como cargar y actualizar un proyecto es un simple git pull y todos los datos relacionados con el proyecto están contenidos en un único repositorio

  2. Proyecto/sincronización externa - Como el proyecto y las versiones externas están versionadas en el mismo repositorio, puedo verificar cualquier rama/etiqueta que quiero y espero que esté funcionando.

  3. Simplicidad: el trabajo 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 pasa demasiado. Lo mejor es que uno puede agregar un nuevo externo a este proyecto primero y luego solo dividirlo (usando git-subárbol) en su propio repositorio.

  4. Cruz plataforma - Bueno, es git

  5. Binarios - decidí evitar la celebración de los binarios y proporcionar Makefile en su lugar. Llegué a esta decisión ya que algunos de mis elementos externos dependen de otros elementos externos, lo que hace que sea muy difícil construir un archivo 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 
0

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

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

+0

¿Usó varios submódulos para los externos? Si no, ¿cómo organizaste el árbol?Estoy pensando en un escenario en el que diferentes proyectos necesitan una combinación diferente de versiones de la biblioteca. – Xyand

+0

Múltiples submódulos para los externos. ¿Tienes una preocupación específica sobre esto? –

+0

Mi preocupación es que tendría que admitir ~ 20 repositorios externos con toda la configuración involucrada, acceso de usuario, etc. De lo contrario, parece que es lo correcto. – Xyand

0

Para las fuentes de terceros, creo que los submódulos son exactamente lo que estás buscando. Si no desea exigir todo el historial de upstream en cada clon, frontend el repositorio de subida con el suyo, que contiene una sucursal hecha a mano con solo el historial necesario. Mira git commit-tree para ver cómo hacer eso, es fácil.Las identificaciones de confirmación no coincidirán con las autoritativas en sentido ascendente, pero la identificación del árbol sí lo hará.

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

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

Cuestiones relacionadas