version-control - usados - version control software
MetodologĂa de control de versiones preferidas (11)
Soy un novato en el mundo del control de fuente / versión y he estado leyendo todo lo posible físicamente para entender las diferentes técnicas que las personas usan para su propio control de fuente / versión.
Una cosa que he notado es una ruptura bastante clara en los métodos de los desarrolladores en dos (¿posiblemente más?) Grupos: un grupo prefiere mantener su troncal en un estado siempre estable y realiza todo el mantenimiento y desarrollo futuro en las ramas, mientras otros prefieren hacer todo su desarrollo en el tronco y mantenerlo en un estado no tan estable.
Tengo curiosidad sobre lo que la comunidad aquí en StackOverflow prefiere o si tiene sus propios métodos.
Nota: Si ayudara a adaptar las respuestas, debería tener en cuenta que soy un desarrollador único (como mucho habrá dos o tres más en el mismo proyecto) que trabaja principalmente en ASP.NET y SQL Server 2005.
Como estoy seguro de que ha notado al buscar en la web respuestas sobre este tema, esta es una de esas cosas en las que la mejor respuesta es "depende", y como la mayoría de las respuestas indicaron, es una compensación entre lo fácil que le gustaría poder comprometer / fusionar un nuevo código y administrar un extenso historial de versiones que puede revertir fácilmente para fines de soporte o depuración.
Trabajo para una empresa pequeña, lo que significa que, en cualquier momento, podríamos tener 3 o 4 versiones diferentes de código en máquinas de desarrollo que aún no se hayan comprometido con el repositorio. Usamos TortoiseSVN para nuestro sistema de control de versiones, lo que nos da la capacidad de ramificar / fusionar sin demasiada dificultad, así como de poder ver el registro de actualizaciones o revertir nuestras copias locales a una revisión anterior con bastante facilidad.
En función de su pregunta, supongo que estaríamos dentro del grupo de desarrolladores que intentan mantener, en todo momento, un Troncal estable, y bifurcamos un nuevo código y lo probamos antes de volver a fusionarlo en el Troncal. También hacemos un esfuerzo para mantener "instantáneas" de cada lanzamiento de versión, de modo que, si es necesario, podemos verificar fácilmente una versión anterior y volver a compilarla, sin incorporar nuevas funciones destinadas a una versión futura (esto también es un gran mecanismo para rastrear errores, ya que puede usar versiones anteriores de código para ayudar a determinar cuándo se introdujo por primera vez un error en particular en su código. Sin embargo, una cosa a tener en cuenta es si su aplicación hace referencia a un código común que se mantiene por separado de su versión -ed código, necesitarás hacer un seguimiento de eso también!).
En el repositorio, termina pareciéndose a algo así:
El maletero
- Versión v1.0.1.x
Versión v1.0.2.x
- v1.0.2.x Bug-Fix A <- (Estos se fusionan de nuevo en Trunk, pero permanecen en el repositorio)
- v1.0.2.x Corrección de errores B
Versión v1.1.1.x
v1.2.1.x Desarrollo <- (Esto se fusionará nuevamente a Trunk y se reemplazará por una carpeta de Release)
- v1.2.1.x Nueva función A <- (Estas vuelven a fusionarse en la rama Desarrollo)
- v1.2.1.x Nueva característica B
Cuando comencé en la compañía, nuestra estructura de versión no era tan sofisticada, y en mi experiencia, diría que si usted tiene alguna necesidad de realizar un seguimiento de las versiones anteriores, valdrá la pena el esfuerzo de poner algo como esto juntos (como dije antes, no tiene que verse exactamente así, siempre que se ajuste a sus necesidades individuales), manténgalo bien documentado para que todos los contribuyentes puedan mantenerlo (la alternativa es que el creador termine "cuidando niños") "el repositorio, que rápidamente se convierte en una increíble pérdida de tiempo", y aliente a todos sus desarrolladores a seguirlo. Al principio puede parecer un gran esfuerzo, pero lo apreciará la primera vez que necesite aprovecharlo.
¡Buena suerte!
En tu caso, recomiendo evitar muchas ramificaciones. Es realmente un proceso bastante avanzado y no es necesario para proyectos pequeños y pequeños equipos.
Esta es la metodología que seguimos: cualquier liberación estable debería tomarse del tronco. Cualquier otro trabajo o modificación debe ir dentro de la rama de trabajo y se debe combinar con el tronco cuando esté listo para ser lanzado.
Si tiene múltiples desarrollos independientes, cada grupo debería tener allí en la rama, que deberían sincronizar con trunc periódicamente y fusionarlo nuevamente al tronco cuando esté listo.
Estoy listo para el tronco siempre estable. Necesita poder reconstruir la última versión estable en cualquier momento ...
Hago todo mi desarrollo en el maletero. Soy un desarrollador único y no quiero lidiar con la molestia de la bifurcación. Cuando mi código es estable, solo etiqueto esa versión actual. Por ejemplo, etiquetaría la versión 1.0, 2.0 beta, la versión 2.0 candidata 1, la versión 2.0, etc. La ramificación probablemente sería una mejor alternativa si está manteniendo versiones antiguas para corregir errores y soporte, pero como yo no hago esto, no no te preocupes por eso
Siempre estable. Incluso si soy un desarrollador único, casi especialmente si soy un desarrollador solitario.
Tener un árbol roto para mí significa una manera menos de saber lo que debería estar haciendo.
Se producen grandes cambios en las sucursales, así como en las versiones estables, y se realiza la unidad de cambios más pequeña posible en cualquier punto dado para seguir avanzando a un buen ritmo.
Siempre he usado el tronco principal como jefe de código. En general, el nuevo código de desarrollo va allí.
Nos ramificamos para las liberaciones y podemos ramificarnos para un "gran" experimento desestabilizador.
Cuando hacemos correcciones de errores, entran primero en main y luego se fusionan (back-ported) en la rama de versión apropiada si es necesario.
Si el gran experimento funciona, se fusiona nuevamente en main.
Usamos etiquetas para números de compilación en las ramas de versión y la principal. De esa forma podemos volver a una versión específica y compilarla si es necesario.
Trate de mantenerlo simple para empezar, siempre trato de tener una compilación de trabajo conocida que pueda reproducirse para pruebas e implementaciones, etc. Dependiendo de su repositorio, podría usar el número de revisión (SVN) o simplemente etiquetar las versiones de trabajo conocidas tal como están. necesario.
Si encuentra que hay varias personas que tocan los mismos archivos, tendrá que considerar una estrategia de bifurcación, aparte de eso para un equipo de desarrollo tan pequeño, será simplemente una tarea innecesaria ... (IMO)
Un aspecto es cuánto tiempo estarán los cambios en un estado inestable.
Cuando un cambio que hago puede afectar a otras personas, o a la construcción nocturna, entonces hago mi trabajo en una rama y me fusiono cuando es estable.
Cuando los cambios que realizo no afectarán a otras personas (porque es mi código privado en mi casa, en lugar de código en el trabajo), entonces estoy de acuerdo con verificar los estados intermedios que no funcionan, si eso es lo que quiero. A veces, haré algunos checkins seguidos que no son estables; eso está bien para mí cuando solo soy yo quien se ve afectado y el flujo de trabajo será continuo. Es que si vuelvo dentro de unos años (en lugar de solo unos pocos días) y las cosas no funcionan, se vuelve problemático (una desventaja de haber estado allí todo el tiempo que tengo, tengo algunos proyectos que todavía están pendientes). en desarrollo y mantenimiento que tienen la edad suficiente para votar).
Utilizo una variante de etiquetado para lograr compilaciones repetibles, por lo que si necesito volver a una versión estable para corregir un error, puedo usar la información de la etiqueta para hacerlo. Es crucial poder obtener una versión estable a pedido.
Las diferencias pueden tener que ver con cuán dolorosa es o no la fusión en un sistema de control de versiones dado.
Con git, la bifurcación y la fusión es prácticamente sin esfuerzo, por lo que es un flujo de trabajo común para mí mantener limpio mi maestro y hacer todo mi trabajo en las sucursales. Bifurcar y fusionar en svn, particularmente en versiones anteriores, no es tan barato y fácil, así que cuando estaba usando svn tendía a trabajar directamente en el tronco.
Una distinción clave es qué tan grandes suelen ser los archivos en promedio. Los archivos grandes (1000 líneas +) tienden a tener muchos cambios independientes que se combinan trivial y automáticamente. Por lo tanto, el hecho de que alguien más está cambiando activamente un archivo en el que está a punto de empezar a trabajar probablemente no sea interesante, por lo que está bien si el sistema lo hace difícil de descubrir.
Entonces tiende a terminar con una estrategia de CV que tiene muchas ramas y fusiones fáciles. La nueva funcionalidad está escrita en nuevas ramas.
Si está trabajando con los archivos más pequeños y altamente cohesivos típicos de un diseño OO, en un lenguaje como Java, tales conflictos accidentales son mucho más raros. Incluso como ejemplo artificial, es bastante difícil crear dos conjuntos de cambios que se pueden realizar en una clase (y en los correspondientes casos de prueba de JUnit) que se pueden hacer de forma aislada y luego volver a unir automáticamente mediante una herramienta de fusión de texto. .
Si realiza una gran cantidad de refactorización (cambio de nombre y división de archivos), eso hace que la herramienta de fusión se destaque aún más.
Por lo tanto, tiende a ser mejor con una estrategia de VC que tiene un tronco estable identificable y utilizable y ramas mínimas.
En el primer enfoque, la nueva funcionalidad se escribe en nuevas ramas y se fusiona cuando se completa. En el segundo, está escrito en archivos nuevos y habilitado cuando se completa.
Por supuesto, si haces el segundo, definitivamente necesitas una protección sólida contra la línea de base que no se puede usar por un período de tiempo prolongado (es decir, integración continua y un sólido conjunto de pruebas de ejecución automática).