Soy otro usuario de Subversion que lucha por reeducarme en el Tao del control de versiones distribuido.
Cuando usaba Subversion, era un gran admirador del enfoque de proyecto menor y, con la mayoría de mis antiguos empleadores, estructuraríamos nuestras sucursales de repositorio; Etiquetas y tronco de la siguiente manera:
branches-+
+-personal-+
| +-alice-+
| | +-shinyNewFeature
| | +-AUTOMATED-+
| | +-shinyNewFeature
| +-bob-+
| +-AUTOMATED-+
| +-bespokeCustomerProject
+-project-+
+-shinyNewFeature
+-fixStinkyBug
tags-+
+-m20110401_releaseCandidate_0_1
+-m20110505_release_0_1
+-m20110602_milestone
trunk
Dentro del propio árbol fuente, usaríamos (algo así) la siguiente estructura:
(src)-+
+-developmentAutomation-+
| +-testAutomation
| +-deploymentAutomation
| +-docGeneration
| +-staticAnalysis
| +-systemTest
| +-performanceMeasurement
| +-configurationManagement
| +-utilities
+-libraries-+
| +-log-+
| | +-build
| | +-doc
| | +-test
| +-statistics-+
| | +-build
| | +-doc
| | +-test
| +-charting-+
| | +-build
| | +-doc
| | +-test
| +-distributedComputing-+
| | +-build
| | +-doc
| | +-test
| +-widgets-+
| +-build
| +-doc
| +-test
+-productLines-+
| +-flagshipProduct-+
| | +-coolFeature
| | +-anotherCoolFeature
| | +-build
| | +-doc
| | +-test
| +-coolNewProduct
+-project-+
+-bigImportantCustomer-+
| +-bespokeProjectOne
| +-bespokeProjectTwo
+-anotherImportantCustomer-+
+-anotherBespokeProject
La idea era (y sigue siendo) usar la estructura del repositorio para ayudar a estructurar la comunicación entre el equipo de ingeniería; la parte del negocio orientada al cliente y otras partes interesadas y expertos en dominios.
A saber: los documentos de origen que se encuentran en uno de los directorios de "proyectos" se usan (y ganan dinero) solo una vez. Los documentos que se encuentran en uno de los directorios "productLines" ganan dinero tantas veces como se vende un producto de esa línea en particular. Los documentos que se encuentran en uno de los directorios de "bibliotecas" ganan dinero tantas veces como cualquiera de los productos que los usan se venden.
Hace explícita la noción de amortización de costos y ayuda a crear soporte para la reutilización de documentos fuente en toda la empresa.
También significa que existe una estructura común sobre la cual pueden operar nuestras herramientas de automatización de compilación. (Nuestros scripts de compilación recorren el árbol de origen en busca de carpetas de "compilación" dentro de las cuales encuentran archivos de configuración que especifican cómo se debe compilar cada componente; ocurre un proceso similar para la generación y prueba de documentación).
Significativamente, los productos en los que trabajo suelen tardar MUCHO tiempo en ejecutar pruebas de medición y caracterización del rendimiento; de 20 a 200 horas; generar en algún lugar entre varios GB y varios TB de resultados de prueba procesados / datos intermedios (que deben almacenarse y vincularse a una configuración de sistema particular para que se pueda medir la mejora del rendimiento a lo largo del tiempo). Este problema hace que la administración de la configuración sea una consideración importante, y también impone algunos requisitos para la centralización, ya que típicamente los recursos computacionales necesarios para ejecutar la medición del desempeño y las pruebas de caracterización son limitados; (un pequeño grupo de 64-128 núcleos).
Como una nota final; el sistema de integración continua sabe que necesita activar una compilación; análisis estático; la prueba de humo y la prueba de la unidad se ejecutan cada vez que se modifica la troncal, cada vez que se modifica cualquier rama "etiqueta", y cada vez que se modifica cualquier rama "AUTOMATIZADA". De esta manera, los desarrolladores individuales pueden usar el sistema CI con sus ramas personales, una capacidad importante, en mi humilde opinión.
Ahora, aquí está mi pregunta: ¿Cómo puedo replicar todo lo anterior (y mejorarlo, si es posible), con Mercurial.
--editar:
Mi línea de pensamiento actual es utilizar un repositorio central de Subversion, para definir la estructura general, pero permitir el uso de hg como cliente para que los desarrolladores puedan tener repositorios disponibles localmente.
fuente
Respuestas:
La respuesta de Spoike es excelente, pero hay algunas cosas que creo que valdría la pena agregar que son demasiado grandes para comentarios.
Organización de la sucursal
Con Mercurial puedes ignorar felizmente la totalidad de tu primer organigrama. Como dice Spoke, cada repositorio tiene su propio conjunto de etiquetas, ramas (con nombre y anónimo) y puede organizarse de acuerdo con las necesidades del negocio.
Si
bespokeProjectTwo
necesita una versión especial de lacharting
biblioteca, entonces se ramificaríacharting
, agregaría las nuevas instalaciones y la usaríabespokeProjectTwo
. Las nuevas instalaciones (y sus errores) no serían utilizadas por otros proyectos que harían referencia a lacharting
biblioteca estándar . Si lacharting
biblioteca principal tuviera errores corregidos, podría fusionar esos cambios en la rama. Si otros proyectos también necesitaran estas instalaciones, puede hacer que esos proyectos usen la rama especial o fusionar la rama en la línea principal y cerrar la rama.Además, no hay nada que le impida tener una política para estructurar los nombres de las sucursales para proporcionar servicios específicos como sus sucursales de AUTOMATION.
Organización del directorio
No hay ninguna razón por la que no pueda mantener su directorio de origen exactamente como está con Mercurial. La única diferencia es que, mientras que con Subversion tiene un único
(src)
repositorio monolítico , con Mercurial es mejor dividirse en repositorios que están agrupados lógicamente. De su estructura de árbol de origen, probablemente extraería cada uno de los siguientes como repositorios individuales:Esto permite que cualquier producto o proyecto a medida use cualquier combinación de bibliotecas, en cualquier revisión. Eche un vistazo a los repositorios mercuriales para una manera fácil de administrar qué bibliotecas se utilizan para cualquier versión dada de un producto o proyecto.
Flujo de trabajo
Una alternativa al flujo de trabajo sugerido por Spoike (el desarrollador extrae del bendito repositorio, trabaja localmente, emite una solicitud de extracción y finalmente el integrador extrae esos cambios y los fusiona) sería utilizar el sistema de integración continua como intermediario.
Como antes, el desarrollador se retira del repositorio bendecido y trabaja localmente, pero cuando lo hace, se retira del repositorio bendecido nuevamente y se fusiona antes de pasar a un repositorio sin bendiciones. Cualquier cambio en el repositorio no bendecido se revisa (de forma manual o automática) y se traslada al repositorio bendecido solo si se aprueba.
Esto significa que el integrador solo tiene que aceptar o rechazar un cambio, no hacer la fusión. En mi experiencia, casi siempre es mejor para el desarrollador que escribió el código realizar la fusión que para que otra persona lo haga.
Como se sugiere en el libro de mercurial, se pueden usar ganchos para automatizar este procedimiento:
Otros asuntos
El problema de los grandes conjuntos de datos de prueba también se puede resolver colocando esos datos de prueba en un sub-repositorio mercurial . Esto evitará que el repositorio de código se hinche con datos de prueba, mientras mantiene los datos de prueba bajo control de revisión.
fuente
productLines
obigImportantCustomer
como repositorios superiores.Bien, tratando de responder esto simplemente.
Lo que necesitas saber
Lo primero que debe saber: Mercurial es un control de versión distribuido y tiene algunas propiedades que debe conocer enumeradas a continuación.
El modelo habitual con el que las personas trabajan en DVCS (que se emplea en github y bitbucket) es hacerlo semi-centralizado.
Cada usuario tiene un repositorio público (en algunos recursos compartidos o en un servidor seguro) y un repositorio privado (en sus propias estaciones de trabajo). Ambos son clones del repositorio "bendecido" de un integrador. Cada vez que sienten que están listos para publicar su código, pueden enviar los cambios a su repositorio público. Un integrador puede elegir qué usuarios extraer código en el repositorio "bendito".
Si el integrador no puede fusionar fácilmente el código de algún usuario, entonces los cambios se rechazan y corresponde a ese usuario en particular actualizar su repositorio y arreglar la fusión ellos mismos. Por lo general, no es tan difícil si se fusiona con frecuencia (ya que es menos el código que debe fusionarse) y, por lo general, ese usuario debe saber qué salió mal con la fusión.
Configuración de repositorios por proyecto
Entonces, la configuración habitual es que para cada proyecto hay lo siguiente:
Un repositorio público de solo lectura del que es responsable el integrador. Es "bendecido".
Es decir, todos los usuarios pueden extraer / recuperar contenido, pero no tienen acceso para enviarlo.
Cada usuario puede tener su propio clon público del repositorio.
La configuración más sencilla se coloca en una unidad compartida (aunque podría considerar hospedar como bitbucket). El integrador recibe solicitudes de extracción de los usuarios e intenta extraer el nuevo código de estos repositorios. Cuando las fusiones se realizan sin problemas, se coloca en el repositorio de solo lectura. De lo contrario, se les pide a los usuarios que solucionen los conflictos de fusión que surgen actualizándolos y fusionándolos localmente.
Cada usuario puede tener sus propios clones privados del repositorio.
Una buena práctica es sacar de su clon público, pero no importa si sacan de su público o del integrador. Todos los commits son identificables de manera única, por lo que fusionar los commits que olvidó buscar en el público es relativamente fácil de arreglar (al impulsar los cambios de lo privado a lo público, también obtiene automáticamente los cambios del integrador).
Organización del código fuente
En cuanto a cómo organizar la fuente del proyecto en sí, es algo en lo que debe pensar. Si un artefacto necesita ser controlado por la fuente, entonces póngalo en control de la fuente. Personalmente, no me gusta la idea de registrar artefactos creados por la compilación o el tiempo de ejecución (debido al alto riesgo de conflictos de fusión en este tipo de artefactos), como archivos binarios o archivos de registro.
También puede verificar la configuración, siempre que facilite la puesta en marcha de los desarrolladores y no altere la configuración de las versiones o el entorno de producción / en vivo (como la configuración de la aplicación / servidor web). Esto lleva a la noción de que si la configuración que tiene obstaculiza seriamente a los desarrolladores para comenzar dentro de los cinco minutos posteriores a la verificación del código, entonces debe ser refactorizado. Otro requisito es que debería ser muy difícil para los desarrolladores estropear el lanzamiento o el entorno de producción / en vivo.
Usted menciona que tiene datos de prueba que deben estar vinculados a alguna versión del código. Ahora, esto es un poco más complicado porque los sistemas DVCS como Mercurial y Git tienden a ser más lentos cuando ingresas datos que son ENORMES. En mi experiencia, se vuelve realmente insoportable después de 5 GB de archivos binarios (su kilometraje puede variar, por lo que debe probar cómo funciona para usted). Sin embargo, recomendaría que coloque los datos generados en su propio repositorio y que su sistema de prueba los etiquete adecuadamente cuando los registre (y / o cree archivos de texto para los mismos fines de metadatos).
Espero que todo esto tenga sentido. Comenta a continuación si me perdí algunos detalles o si algo necesita más explicaciones e intentaré editarlo.
fuente