Version Control: infierno de múltiples versiones, synchronization de files

Me gustaría saber cómo lidias normalmente con esta situación:

Tengo un set de funciones de utilidad. Say..5..10 files. Y técnicamente son biblioteca estática, multiplataforma: SConscript / SConstruct plus Proyecto de Visual Studio (no solución).

Esas funciones de utilidad se utilizan en múltiples proyectos pequeños (15+, el número aumenta con el time). Cada proyecto tiene una copy de algunos files o de una biblioteca completa, no un enlace en un lugar central. A veces el proyecto usa un file, dos files, algunos usan todo. Normalmente, las funciones de utilidad se incluyen como una copy de cada file y SConscript / SConstruct o Visual Studio Project (dependiendo de la situación). Cada proyecto tiene un repository de git separado. A veces, un proyecto se deriva de otro, a veces no lo es. Usted trabaja en cada uno de ellos, en order aleatorio. No hay otras personas (para hacer las cosas más simples)

El problema surge cuando, al trabajar en un proyecto, modifica esos files de function de utilidad.
Debido a que cada proyecto tiene una copy de file, presenta una nueva versión, que lleva al desastre cuando intenta más tarde (una semana después, por ejemplo) adivinar qué versión tiene la funcionalidad más completa (es decir, usted agregó una function a a.cpp en un proyecto, y agregó otra function a a.cpp en otro proyecto, que creó un fork de versión)

¿Cómo manejarías esta situación para evitar el "infierno de la versión"? Una forma en que puedo pensar es usar enlaces simbólicos / enlaces duros, pero no es perfecto: si borras un almacenamiento central, se irá al infierno. Y los enlaces duros no funcionarán en el sistema de arranque dual (aunque sí lo harán los enlaces simbólicos). Parece que lo que necesito es algo así como el repository de git avanzado, donde el código para el proyecto se almacena en un repository local, pero se sincroniza con múltiples repositorys externos. Pero no estoy seguro de cómo hacerlo o si es posible hacer esto con git.

¿Entonces, qué piensas?

No es completamente claro para mí lo que quieres, pero tal vez los submodules de Git puedan ser útiles: http://git-scm.com/docs/git-submodule

La manera simple normal sería tener la biblioteca como un proyecto en el control de su versión, y si hay una modificación, editar solo este proyecto.

Luego, otros proyectos que necesitan la biblioteca pueden get los files necesarios del proyecto de la biblioteca.

En Subversion puede usar externos (no es GIT lo sé, pero estos consejos aún pueden ayudar). Así es como funciona:

  • Divida el código específico de la aplicación (\ MYAPP) del código común (\ COMMON)
  • Eliminar todos los duplicates de las aplicaciones; solo deberían usar el código común
  • Ingrese el código común en las aplicaciones agregando \ COMMON como externo en \ MYAPP

Probablemente también tengas versiones de tu aplicación. También presente versiones en el código común. Entonces, su aplicación tendrá las siguientes carpetas en el repository:

  • \ MYAPP \ TRUNK
  • \ MYAPP \ V1
  • \ MYAPP \ V2

Del mismo modo, agregue versiones al código común, ya sea usando numbers de versión, como este:

  • \ COMMON \ TRUNK
  • \ COMMON \ V1
  • \ COMMON \ V2

O usando dates, como esta:

  • \ COMMON \ TRUNK
  • \ COMMON \ 2010JAN01
  • \ COMMON \ 2010MAR28

Los elementos externos de \ MYAPP \ TRUNK deben apuntar a \ COMMON \ TRUNK, eso es obvio.

Intente sincronizar las versiones del código común con las versiones de las aplicaciones, de modo que cada vez que se repare una versión de la aplicación, también se corrija el código común, y la versión de la aplicación apuntará al código externo relevante.

Por ejemplo, los externos de \ MYAPP \ V1 pueden señalar a \ COMMON \ 2010JAN01.

La ventaja de este enfoque es que cada desarrollador puede ampliar, mejorar y depurar el código común. La desventaja es que el time de compilation de las aplicaciones boostá a medida que aumente el código común.

La alternativa (poner bibliotecas en su sistema de versión) tiene la desventaja de que la gestión (ampliación, mejora, debugging) del código común siempre se realiza de forma separada de la gestión de las aplicaciones, lo que puede evitar que los desarrolladores escriban un código común genérico ( y todos comienzan a escribir sus propias versiones de classs "genéricas"). Por otro lado, si tiene un equipo claro y flexible que es el único responsable del código común, el código común estará mucho mejor controlado en la última alternativa.

En términos de Configuración (general), una solución es tener múltiples troncales (twigs):

  • Lanzamiento
  • Integración
  • Desarrollo

Lanzamiento
Esta línea externa / sucursal contiene un software que ha superado la garantía de calidad y puede ser entregado a un cliente. Después del lanzamiento, todos los files están marcados como "solo lectura". Se les da una label para identificar los files con el número de versión.

Periódicamente o bajo demanda, el gurú de la testing tomará la última versión (punta) del tronco de Integración y someterá a testings de calidad extenuantes. Así es como se promueve una versión de integración a una versión de lanzamiento.

Integración
Este tronco contiene el último código de trabajo. Contiene correcciones de errores y nuevas funciones. Los files deben labelrse después de cada corrección de error o característica nueva.

El código se mueve a la twig de integración después de que el error ha pasado la testing de calidad o la nueva característica está completamente desarrollada (y probada). Una buena idea es labelr la versión de integración con una label temporal antes de integrar el código del desarrollador.

Desarrollo Estas son las twigs creadas por los desarrolladores para corregir errores o desarrollar nuevas funciones. Puede ser una copy de todos los files movidos a su máquina local o solo los files que necesitan ser modificados (con enlaces a la troncal de Integración para todos los demás files).

Cuando se mueve entre troncos, el código debe pasar la testing de calificación, y debe haber permiso para moverse al troncal. Por ejemplo, las nuevas características injustificadas no se deben poner en la twig de integración sin autorización.


En su caso, los files deben volverse a verificar en la troncal de Integración después de que se hayan modificado O en una nueva twig o troncal si el código es muy diferente de la versión anterior (como agregar nuevas características).

Estuve estudiando GIT y SourceSafe tratando de descubrir cómo implementar este esquema. El esquema es fácil de implementar en las aplicaciones más grandes de Configuration Management como PVCS y ClearCase. Parece que para GIT, se necesitan repositorys duplicates (un repository para cada tronco). SourceSafe indica claramente que solo permite una label por versión, por lo que los files que no han cambiado perderán la información de la label.