¿Dolores de cabeza con control de versiones distribuido para equipos tradicionales?

20

Aunque uso y me gusta DVCS para mis proyectos personales, y puedo ver totalmente cómo facilita la administración de las contribuciones a su proyecto de otros (por ejemplo, su escenario típico de Github), parece que para un equipo "tradicional" podría haber algunos problemas sobre el enfoque centralizado empleado por soluciones como TFS, Perforce, etc. (Por "tradicional" me refiero a un equipo de desarrolladores en una oficina que trabaja en un proyecto que nadie "posee", y potencialmente todos tocan el mismo código).

He previsto un par de estos problemas por mi cuenta, pero por favor interviene con otras consideraciones.

En un sistema tradicional, cuando intenta registrar su cambio en el servidor, si alguien más ha registrado previamente un cambio conflictivo, entonces se ve obligado a fusionarse antes de poder registrar el suyo. En el modelo DVCS, cada desarrollador registra su cambia localmente y en algún momento empuja a otro repositorio. Ese repositorio luego tiene una rama de ese archivo que 2 personas cambiaron. Parece que ahora hay que poner a alguien a cargo de lidiar con esa situación. Una persona designada en el equipo podría no tener suficiente conocimiento de toda la base de código para poder manejar la fusión de todos los conflictos. Por lo tanto, ahora se ha agregado un paso adicional en el que alguien tiene que acercarse a uno de esos desarrolladores, decirle que tire y haga la fusión y luego empuje nuevamente (o debe construir una infraestructura que automatice esa tarea).

Además, dado que DVCS tiende a hacer que trabajar localmente sea tan conveniente, es probable que los desarrolladores puedan acumular algunos cambios en sus repositorios locales antes de presionar, haciendo que tales conflictos sean más comunes y más complicados.

Obviamente, si todos en el equipo solo trabajan en diferentes áreas del código, esto no es un problema. Pero tengo curiosidad sobre el caso en el que todos están trabajando en el mismo código. Parece que el modelo centralizado obliga a resolver los conflictos de manera rápida y frecuente, minimizando la necesidad de realizar grandes y dolorosas fusiones o de que alguien "vigile" el repositorio principal.

Entonces, para aquellos de ustedes que usan un DVCS con su equipo en su oficina, ¿cómo manejan estos casos? ¿Le afecta negativamente su flujo de trabajo diario (o más probable, semanal)? ¿Hay otras consideraciones que debo tener en cuenta antes de recomendar un DVCS en mi lugar de trabajo?

J Cooper
fuente
Esa es una excelente pregunta. La forma en que describió el problema es más o menos la razón principal (entre otras) por la que no considero usar DVCS con mi equipo (afortunadamente, o no, estoy en condiciones de hacer esa llamada).
Alex
Mis experiencias y sentimientos son muy similares a los tuyos.
William Payne

Respuestas:

26

Hemos estado usando Mercurial durante aproximadamente un año. Si bien existe el dolor de cabeza que menciona, el desafío más grande para la adopción total para nosotros fue entrar en la mentalidad DVCS de los repositorios locales (= comprometerse a menudo). La antigua mentalidad de "Comprometerse una vez que haya pulido el código" puede ser difícil de dejar Vamos.

Tu dijiste:

En el modelo DVCS, cada desarrollador registra sus cambios localmente y en algún momento empuja a otro repositorio. Ese repositorio luego tiene una rama de ese archivo que 2 personas cambiaron. Parece que ahora hay que poner a alguien a cargo de lidiar con esa situación.

Una instalación predeterminada de Mercurial bloquea este comportamiento. No permitirá un empuje si se creará más de una cabeza en el repositorio remoto, sin confirmación adicional. Para las actividades diarias, lo evitamos. (Git ha nombrado cabezas y cada una solo puede actualizarse si combina completamente la versión anterior, sin confirmación adicional, por lo que nuevamente la situación no puede surgir. El otro DVCS también tiene una protección similar).

Entonces, al final de cada día de trabajo, se debe reservar un tiempo para el compromiso, que en realidad son estas actividades:

  1. Cometer cambios locales.
  2. Tire del repositorio central.
  3. Fusionar (y confirmar fusión)
  4. Empuje al repositorio central.

Esto mantiene la actividad de fusión en una persona que estuvo trabajando recientemente en este código y debería poder integrar sus cambios tan rápido como cualquier otra persona.

Como se señaló en la pregunta, esto realmente solo agrega esfuerzo cuando dos personas están trabajando en la misma área de código. Si ese es el caso, hay más beneficios al usar DVCS de todos modos, por lo que la recompensa ya es evidente para esos desarrolladores. (Los beneficios adicionales incluyen que cada desarrollador pueda confirmar código por separado y jugar con su propio repositorio sin que otro desarrollador se interponga en el camino).

Otro tema que mencionas:

Además, dado que DVCS tiende a hacer que trabajar localmente sea tan conveniente, es probable que los desarrolladores puedan acumular algunos cambios en sus repositorios locales antes de presionar, haciendo que tales conflictos sean más comunes y más complicados.

Esto no crea un problema de fusión para nosotros, pero podría crear un problema diferente:

La flexibilidad de DVCS significa que son posibles muchos flujos de trabajo diferentes, pero algunos de ellos son irresponsables. Con DVCS, aumenta la necesidad de procesos o procedimientos claros. La actividad de mantener los cambios locales puede o no ser apropiada, dependiendo de muchas cosas.

Por ejemplo: ¿puede un desarrollador trabajar en una función de mascota en el tiempo libre durante unas pocas semanas? En algunos entornos esto es alentador, en otros esto sería inapropiado y todos los cambios deberían centralizarse pronto. Pero si un desarrollador mantiene los cambios a nivel local, entonces seguramente querrá sacar los cambios relacionados para asegurarse de que su trabajo continuará jugando bien con la última versión común.

Cuando el caucho se encuentra con el camino, los lanzamientos o implementaciones de software generalmente provienen de un repositorio central, por lo que los desarrolladores necesitan obtener sus cambios allí para realizar pruebas e implementaciones.

Esa es mi historia, y me quedo con ella, por al menos un par de minutos ...

Jamie F
fuente
Esto es bastante bueno La ramificación también puede agregar cierta complejidad en la situación.
Paul Nathan
44
Con DVCS, aumenta la necesidad de procesos o procedimientos claros. con gran poder vienen grandes responsabilidades.
Newtopian
5

La premisa de su pregunta parece estar en torno a "Las fusiones son difíciles y deben evitarse". Los sistemas DVCS eliminan esta barrera, de hecho hacen más, adoptan la idea de la fusión: como resultado, no debe tener miedo de las fusiones y los conflictos de fusión, ya que a diferencia de las herramientas centralizadas, las herramientas DVCS lo admiten por diseño.

Como dice la excelente respuesta de Jamie F: el flujo de trabajo de Commit-Pull-Merge-Push realizado regularmente (a diario) significa que si está caminando en algún otro trabajo, lo verá temprano, siempre que sea visible, se puede manejar .

Los problemas que describe son más sobre cómo elige utilizar las herramientas.

Cambiamos de SVN a GIT hace 6 meses, después de usar SVN y GIT localmente durante un par de años. Nadie volverá, y los dolorosos conflictos de fusión son cosa del pasado. El mantra "Cometer pequeños y con frecuencia" es la clave.

Mattnz
fuente
3

Cuando trabajaba en un equipo que usaba git, la regla general era esta: trabajar en una rama privada, luego, cuando esté listo para hacer que su trabajo esté disponible para el resto del equipo, vuelva a armar su rama en master antes de presionar. (Luego valide su sucursal).

Esta estrategia significaba que master era una serie lineal de commits y que todos los problemas de integración se reparaban en las sucursales antes de que fueran públicos.

Sean McMillan
fuente
Rebasar "cambia la historia" y puede ser un poco más peligroso. Si el rebase va mal, ya no tiene un registro de cómo se veían los cambios antes del rebase. Por esta razón, muchos desarrolladores argumentan que debería fusionarse en su lugar. Pierdes las bonitas líneas rectas, pero obtienes la capacidad de reintentar una fusión que salió mal. Además, si no presiona ningún cambio hasta que todo esté hecho, no se protegerá de los bloqueos del disco duro u otros desastres locales. Pero estoy seguro de que este enfoque todavía funciona para muchas personas: probablemente mucho mejor que un VCS centralizado.
StriplingWarrior
3

Una herramienta como SVN fomenta firmemente una forma de trabajo estrechamente integrada.

Es decir, comprometerse con frecuencia a una rama compartida (ya sea troncal o una rama de desarrollo).

Esto es A-OK para la mayoría de los entornos de desarrollo corporativo que he experimentado, y se facilita y fomenta aún más mediante el uso de la Integración Continua respaldada por extensas pruebas de integración, pruebas de regresión y pruebas unitarias (Ayudando a los desarrolladores individuales a ganar la confianza de que no han roto cualquier cosa por sus cambios).

DVCS le brinda la libertad de trabajar de manera más independiente, lo que necesita en algunas situaciones, y el soporte mejorado (muy apreciado) para las fusiones no puede causar ningún daño.

La preocupación que siempre permanece en el fondo de mi mente es esta: con una gran libertad viene la tentación de usar esa libertad.

Ciertamente, en mi experiencia (limitada), paso mucho más tiempo trabajando independientemente en mi equipo actual (usando Mercurial) que en roles anteriores (donde usamos SVN, CVS y P4).

Esto es solo parcialmente atribuible a la herramienta, pero creo que es una observación razonable hacer que, a falta de una razón convincente para gastar el esfuerzo en comunicación y coordinación, las personas tenderán a trabajar separadas y aisladas.

Esto no es necesariamente algo malo, pero creo que es algo que debe tenerse en cuenta.

William Payne
fuente
1

Lo que sucede con el control de versiones de tipo git / mercurial es comprometerse con frecuencia y enviar al servidor centralizado cuando el código es bueno. Una gran ventaja de esto es que crea pequeños parches, que son fáciles de aplicar en caso de conflictos. Además, su flujo de trabajo debe ser algo en las líneas de:

  1. Muchos locales se comprometen
  2. Tire del servidor
  3. Empujar al servidor

Esta extracción del servidor puede crear conflictos, pero para resolver esto, todo lo que se necesita muchas veces es una simple modificación, en lugar de una fusión. Creo que esto mantendrá el historial de la línea principal bastante limpio y eliminará muchos conflictos.

Este también es el caso cuando se retira del repositorio local de un compañero de trabajo, ya que pueden suceder dos cosas. O empuja primero al servidor, lo cual está bien ya que ya tiene sus parches, y no deben ocurrir conflictos, o empuja primero, lo que significa que solo recibirá sus parches cuando tire.

Por supuesto, a veces una fusión es una mejor solución, como un ejemplo si está trabajando en una rama de características que debería fusionarse en maestra.

En su flujo de trabajo, está hablando de personas que tienen que ir explícitamente a otro desarrollador y decirle que arregle el conflicto, pero eso no debería ser necesario. El servidor central es el "jefe", y contra lo que debería trabajar principalmente. Si sus cambios se aplican al repositorio central, entonces está bien. Si no, es TU trabajo arreglar el conflicto, lo que puede requerir que el desarrollador con el que estás en conflicto te ayude a comprender sus cambios. Esto es algo que ve cuando intenta extraer / rebase del servidor. Así que sea feliz al comprometerse y lidie con los conflictos cuando deba retirarse del servidor.

martiert
fuente
0

El principio de trabajar con repositorio centralizado es el mismo cuando se trabaja con un sistema centralizado o distribuido sin bloqueo:

  • En el sistema centralizado usted:
    1. Obtenga la última versión de mainline ("trunk" en subversion, "master" en git, ...)
    2. Modificar los archivos
    3. Combine las modificaciones con la última versión de la línea principal utilizando el comando "actualizar"
    4. Comprometerse con la línea principal
  • En sistema distribuido usted:
    1. Obtenga la última versión de mainline
    2. Modificar los archivos
    3. Comprometerse localmente
    4. Combine las modificaciones con la última versión de la línea principal y confirme el resultado localmente
    5. Empuje a la línea principal.

Ninguna versión distribuida le permitirá impulsar la revisión que no combina completamente la revisión de cabecera anterior (sin anulación especial; a veces es útil), por lo que no pasará sin realizar el paso de combinación (por lo que no habrá dos versiones para alguien Tendría que consolidar lo que le preocupa).

Ahora tenga en cuenta que cuatro de los pasos son los mismos, excepto por la terminología, pero los sistemas distribuidos agregan un paso adicional "3. Comprometerse localmente". La gran ventaja de este paso es que cuando la actualización / extracción crea conflictos y no está seguro de cómo resolverlos o cometer un error al resolverlos, puede regresar, revisar lo que hizo y rehacer la fusión. Subversion no recordará ninguno de esos, así que si comete un error al resolver la actualización, está jodido.

En cuanto a la acumulación de cambios, las personas también tienden a hacerlo con un sistema centralizado. Especialmente si tiene que cambiar entre funciones a menudo (como interrumpir un trabajo más largo para corregir un error o hacer algunos ajustes que el cliente necesita con urgencia), las personas a menudo necesitarán mantener los cambios localmente simplemente porque no están terminados. Por lo tanto, es mejor si el sistema al menos admite darle sentido.

En cualquier caso, estos problemas deben abordarse mediante pautas y comunicación adecuadas en el equipo y no mediante las herramientas. Con herramientas más flexibles, las pautas son más importantes, pero las herramientas más flexibles permiten abordar mejor varios casos de esquina.

Jan Hudec
fuente