Ramificación flexible vs estática (Git vs Clearcase/Accurev)


Mi pregunta es sobre la forma en que Git maneja las ramas: cada vez que se ramifica desde un commit, esta rama nunca recibirá cambios de la rama padre a menos que fuerce con una fusión.

Pero en otros sistemas como Clearcase o Accurev, puede especificar cómo se llenan las ramas con algún tipo de mecanismo de herencia: Quiero decir, con Clearcase, usando un config_spec, puede decir " obtener todos los archivos modificados en branch / main / issue001 y luego continuar con los que están en / main o con esta línea de base específica".

En Accurev también tiene un mecanismo similar que permite que los flujos reciban cambios de las ramas superiores (flujos como los llaman) sin fusionar o crear una nueva confirmación en la rama.

¿No extrañas esto mientras usas Git? ¿Puede enumerar escenarios donde esta herencia es una necesidad?

Gracias

Update Por favor, lea la respuesta de VonC a continuación para enfocar mi pregunta. Una vez que estamos de acuerdo "lineal almacenamiento " y los SCM basados en DAG tienen diferentes capacidades, mi pregunta es: ¿cuáles son los escenarios de la vida real (especialmente para las empresas más que OSS) donde lineal puede hacer cosas que no son posibles para DAG? Valen?

Author: phi, 2009-04-18

9 answers

Para entender por qué Git no ofrece algún tipo de lo que se refiere como un "mecanismo de herencia" (que no implica un commit), primero debe comprender uno de los conceptos básicos de esos SCM (Git vs. ClearCase por ejemplo)

  • ClearCase utiliza un almacenamiento de versión lineal : cada versión de un elemento (archivo o directorio) está vinculada en una relación directa lineal con la versión anterior del mismo elemento.

  • Git utiliza un Grafo Acíclico Dirigido DAG - : cada "versión" de un archivo es en realidad parte de un conjunto global de cambios en un árbol que es a su vez parte de un commit. La versión anterior de eso debe encontrarse en un commit anterior, accesible a través de una única ruta de grafo acíclico dirigida.

En un sistema lineal, una especificación de configuración puede especificar varias reglas para lograr la "herencia" que ve (para un archivo dado, primero seleccione un cierto versión, y si no está presente, a continuación, seleccione otra versión, y si no está presente, a continuación, seleccione una tercera, y así sucesivamente).

La rama es una bifurcación en un historial lineal una versión dada para una regla select dada (todas las demás reglas select anteriores a esa todavía se aplican, de ahí el efecto "herencia")

En un DAG, un commit representa toda la "herencia" que obtendrá; no hay una selección "acumulativa" de versiones. Solo hay una ruta en este gráfico para seleccionar todo los archivos que verá en este punto exacto (commit).
Una rama es solo un nuevo camino en este gráfico.

Para aplicar, en Git, algunas otras versiones, debes:

Pero dado que Git es un SCM basado en DAG, siempre resultará en una nueva confirmación.

Lo que estás "perdiendo" con Git es algún tipo de" composición "(cuando estás seleccionando diferentes versiones con diferentes reglas de selección sucesivas), pero eso no sería práctico en un DVCS (como en" Distributed"): cuando estás haciendo una rama con Git, necesitas hacerlo con un punto de partida y un contenido claramente definido y fácilmente replicado a otros repositorios.

En un VCS puramente central, puede definir su espacio de trabajo (en ClearCase, su "vista", ya sea instantánea o dinámica) con cualquier regla tú quieres.


Desconocido-google añade en el comentario (y en su pregunta anterior):

Entonces, una vez que vemos que los dos modelos pueden lograr cosas diferentes (lineal vs DAG), mi pregunta es: ¿cuáles son los escenarios de la vida real (especialmente para las empresas más que OSS) donde lineal puede hacer cosas que no son posibles para DAG? ¿Valen la pena?

Cuando se trata de "escenario de la vida real" en términos de reglas de selección, lo que puede hacer en un modelo lineal es tener varias reglas de selección para el mismo conjunto de archivos.

Considere esta " especificación de configuración "(es decir," especificación de configuración " para reglas de selección con ClearCase):

element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... aLabel2 -mkbranch myNewBranch

Selecciona todos los archivos etiquetados 'aLabel2' (y se ramifican desde allí), excepto los etiquetados 'aLabel3' - y se ramifican desde allí - (porque esa regla precede a la que menciona 'aLabel2').

¿vale la pena?

No.

En realidad, el sabor UCM de ClearCase (el "Gestión Unificada de la Configuración" la metodología incluida con el producto ClearCase, y que representa todas las "mejores prácticas" deducidas del uso básico de ClearCase) no lo permite, por razones de simplificación. Un conjunto de archivos se llama un "componente", y si desea ramificar para una etiqueta dada (conocida como una "línea de base"), que se traduciría como esta siguiente especificación de configuración:

element /aPath/... .../myNewBranch
element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... /main/0 -mkbranch myNewBranch

Tienes que elegir un punto de partida (aquí, 'aLabel3') y ve desde ahí. Si desea también los archivos de ' aLabel2', hará una fusión de todos los archivos 'aLabel2' a los de 'myNewBranch'.

Esa es una "simplificación" que no tiene que hacer con un DAG, donde cada nodo del gráfico representa un "punto de partida" definido de forma única para una rama, cualquiera que sea el conjunto de archivos involucrados.

Merge y rebase son suficientes para combinar ese punto de partida con otras versiones de un conjunto dado de archivos, con el fin de lograr el deseado "composición", manteniendo esa historia particular en aislamiento en una rama.

El objetivo general es razonar en "operaciones de control de versiones coherentes aplicadas a un componente coherente". Un conjunto" coherente " de archivos es uno en un estado coherente bien definido:

  • si está etiquetado, todos {[12] } sus archivos están etiquetados
  • si se ramifican, todos sus archivos se ramificarán desde el mismo único comenzando punto

Eso se hace fácilmente en un sistema DAG; puede ser más difícil en un sistema lineal (especialmente con "Base ClearCase" donde la "especificación de configuración" puede ser complicada), pero se aplica con la metodología UCM de esa misma herramienta basada en lineal.

En lugar de lograr esa "composición" a través de un " truco de regla de selección privada "(con ClearCase, algún orden de regla selecta), lo logra solo con operaciones de VCS (rebase o merge), que dejan un rastro claro para que todos lo sigan (a diferencia de una especificación de configuración privada para un desarrollador, o compartida entre algunos pero no todos los desarrolladores). Una vez más, impone un sentido de coherencia, a diferencia de una "flexibilidad dinámica", que puede tener dificultades para reproducirse más adelante.

Que le permite salir del reino de VCS (Version Control System) y entrar en el reino de SCM (Software Configuration Management), que se refiere principalmente a " reproducibilidad". Y que (Características de SCM) se puede lograr con un VCS basado en lineal o un VCS basado en DAG.

 30
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:25:02

Parece que lo que estás buscando podría ser git rebase. Reorganizar una rama conceptualmente la separa de su punto de rama original y la vuelve a unir en algún otro punto. (En realidad, la rebase se implementa aplicando cada parche de la rama en secuencia al nuevo punto de rama, creando un nuevo conjunto de parches.) En su ejemplo, puede rebase una rama a la punta actual de una rama superior, que esencialmente "heredará" todos los cambios realizados en la otra rama.

 3
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-18 08:06:42

No estoy totalmente claro en lo que está pidiendo, pero suena como git el seguimiento de la semántica es lo que quieres. Cuando se ramifica desde el origen am puedes hacer algo como:

Git-t-b my_branch origin / master

Y luego los futuros "git pull" fusionarán automáticamente origin / master en su rama de trabajo. A continuación, puede utilizar "git cherry-v origin / master" para ver cuál es la diferencia. Puedes usar "git rebase" antes de publicar tu cambios para limpiar el historial, pero no debe usar rebase una vez tu historia es pública (es decir, otras personas están siguiendo esa rama).

 3
Author: stsquad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-18 10:31:49

En cuanto al esquema de herencia utilizado por accurev: los usuarios de GIT probablemente "obtendrán" todo cuando miren git-flow (vea también: http://github.com/nvie/gitflow y http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/)

Este modelo de ramificación de GIT hace más o menos (manualmente / con la ayuda de la herramienta git-flow) lo que accurev hace de forma automática y con excelente soporte gráfico.

Así que aparece GIT puede haz lo que accurev hace. Dado que nunca usé git / git-flow día a día, realmente no puedo decir cómo funciona, pero se ve prometedor. (Menos soporte GUI adecuado: -)

 2
Author: Martin Ba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-10 13:58:42

Voy a tratar de responder a su pregunta. (Tengo que decir aquí que no he utilizado GIT solo leer sobre él, así que si algo que menciono a continuación está mal, por favor corríjame)

"¿Puede enumerar escenarios donde esta herencia es una necesidad?"

No diré que sea una necesidad, porque puede resolver un problema con la herramienta que tiene, y podría ser una solución válida para su entorno. Supongo que es más una cuestión de procesos que de la propia herramienta. Asegurarse de que su proceso es coherente y también le permite retroceder en el tiempo para reproducir cualquier paso intermedio / estado es el objetivo, y la ventaja es que la herramienta le permite ejecutar su proceso y SCMP lo más indoloro posible

El único escenario que puedo ver es útil tener este comportamiento 'herencia' y usar la potencia de la especificación de configuración, es cuando desea que su conjunto de cambios "aislado" asignado a una tarea (devtask, CR, SR, o lo que defina el propósito/alcance de su conjunto de cambios)

Usando esta composición le permite tener su rama de desarrollo limpia y aún así usar una combinación diferente (usando composición) del resto del código, y todavía tener solo lo que es relevante para la tarea aislado en una rama durante el todo ciclo de vida de la tarea, solo hasta la fase de integración.

Siendo purista tener que commit / merge / rebase solo para tener un "punto de partida definido", supongo que ' contaminaría' tu rama y terminarás con tu cambios + otros cambios en su rama/conjunto de cambios.

¿Cuándo/Dónde es útil este aislamiento? Los puntos a continuación solo podrían tener sentido en el contexto de las empresas que buscan CMM y algunas certificaciones ISO, y podrían no ser de interés para otro tipo de empresas o OSS

  • Siendo muy exigente, es posible que desee contar con precisión las líneas de código (añadido / modificado / eliminado) del conjunto de cambios correspondiente a un solo desarrollador, más tarde utilizado como una entrada para el código y el esfuerzo estimación.

  • Puede ser más fácil revisar el código en diferentes etapas, teniendo solo su código en una sola rama (no pegado con otros cambios)

En proyectos grandes con varios equipos y + 500 desarrolladores trabajando activamente en el mismo código base, (donde los árboles de versiones de elementos individuales gráficos parecen una red enredada desordenada con varias líneas de carga, una para cada gran cliente o una para cada tecnología ) varios grados de profundidad hicieron que esta cantidad de personas trabajaran sin problemas para adaptar el mismo producto / sistema (código base) a diferentes propósitos. Usando esta especificación de configuración, dinámicamente le dio a cada equipo o sub equipo, una vista diferente de lo que necesitan y desde donde necesitan ramificar, (en cascada en varios casos) sin la necesidad de crear ramas de integración intermedia, o constantemente fusionando y rebasando todos los bits con los que necesita comenzar. Código de la misma tarea / propósito era ramificación de diferentes etiquetas, pero tenía sentido. (Aquí se puede argumentar que la "línea de base conocida" es un principio del Acuerdo SMC, pero las etiquetas simples contempladas en un Plan escrito SMC hicieron el trabajo) Debe ser posible resolver esto con GIT (supongo que de una manera no dinámica), pero me resulta muy difícil imaginarlo sin este comportamiento de 'herencia'. Supongo que el punto mencionado por VonC "si se ramifica, todos sus archivos se ramifican desde el mismo punto de partida único" se rompió aquí, pero además estaba bien documentado en el SCMP, I recuerde que había razones de negocios fuertes para hacerlo de esa manera.

Sí construir estas especificaciones de configuración que mencioné anteriormente no fue gratis, al principio había 4-5 personas bien pagadas detrás del SCM, pero más tarde se redujeron por scripts automatizados que le preguntaron qué quería en términos de etiquetas/ramas/características y escribirán el CS por usted.

La reproducibilidad aquí se logró simplemente guardando la especificación de configuración junto con la tarea en el sistema devTask, por lo que cada tarea mapeado a requisitos, y mapeado a una especificación de configuración, un conjunto de cambios (archivos de código, documentos de diseño, documentos de prueba, etc.)

Así que hasta aquí una conclusión aquí podría ser, solo si su proyecto es lo suficientemente grande / complicado (y puede permitirse gerentes de SC a lo largo de la vida del proyecto:)) entonces solo comenzará a pensar si necesita el comportamiento de 'herencia' o una herramienta realmente versátil, de lo contrario irá directamente a una herramienta que es gratuita y ya se de ti SCM ... pero podría haber otros factores en la herramienta SCM que podrían hacer que se adhiera a uno u otro ...sigue leyendo..

Algunas notas laterales, que podrían estar fuera de tema, pero supongo que en algunos casos como el mío deben ser consideradas.

Tengo que añadir aquí que usamos el "buen-ol CC" no UCM. Totalmente de acuerdo con VonC en el una buena metodología permite "guiar" la flexibilidad hacia una configuración más coherente. Lo bueno es que CC es bastante flexible y puede encontrar (no sin un poco de esfuerzo) una buena manera de tener algo coherente, mientras que en otro SCM que podría tener de forma gratuita. Pero por ejemplo aquí (y otros lugares en los que he trabajado con CC) para proyectos de C/C++ no podemos permitirnos el precio de no tener la característica winkin (reutilizando los objetos Derive), que reducen varias veces el tiempo de compilación. Se puede argumentar que tener un mejor diseño, un código más desacoplado y optimizar los Makefiles puede reducir la necesidad de compilar todo, pero hay los casos que necesita para compilar toda la bestia muchas veces al día, y compartir el DO ahorra un montón de tiempo/dinero. Donde estoy ahora tratamos de usar tanta herramienta gratuita como podamos, y creo que nos desharemos de CC si podemos encontrar una herramienta más barata o gratuita que implemente la función winkin.

Voy a terminar con algo que Pablo menciona, diferentes herramientas son mejores que otras para diferentes propósitos pero voy a añadir que usted puede alejarse de alguna limitación de la herramienta por tener un proceso coherente y sin escarificar la reproducibilidad, puntos clave del SCM Al final supongo que la respuesta a vale la pena? depende de su "problema", el SDLC que está ejecutando, sus procesos SCM y si hay alguna característica adicional (como winkin) que pueda ser útil en su entorno.

Mis 2 centavos

 2
Author: FedeN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-18 23:18:52

Aparte de la teoría, aquí hay una especie de toma práctica obvia sobre esto, desde mi perspectiva usando AccuRev en un entorno de producción comercial durante varios años: El modelo de herencia funciona muy bien siempre y cuando las corrientes hijas no se hayan divergido demasiado de los antepasados que todavía están en desarrollo. Se descompone cuando los flujos hereditarios son demasiado diferentes.

La herencia (versiones posteriores como hijos de las anteriores) permite que los cambios en los flujos ancestros estén activos en los flujos secundarios sin que nadie haga nada (a menos que se requiera una fusión, en cuyo caso se muestra como superposición profunda, lo que es bueno poder ver).

Eso suena genial, y en la práctica lo es, cuando todas las corrientes involucradas son relativamente similares. Usamos ese modelo para flujos de nivel de hotfix y service pack debajo de una versión de producción dada. (En realidad es un poco más complicado que eso para nosotros, pero esa es la idea general.)

Los lanzamientos de producción están en paralelo, sin herencia, con aquellos hotfix y service pack niños debajo de cada uno de ellos. Iniciar una nueva versión significa crear una nueva transmisión a nivel de versión y enviar manualmente todo, desde la transmisión de mantenimiento más reciente para la versión anterior. Después de eso, los cambios a versiones anteriores que se aplican a versiones posteriores tienen que ser empujados manualmente en cada una de ellas, requiriendo más trabajo, pero permitiendo un control mucho mayor.

Originalmente usamos el modelo de herencia en todas las versiones, donde las posteriores eran hijos de los anteriores. Eso funcionó bien por un tiempo, pero se volvió inmanejable con el tiempo. Las grandes diferencias arquitectónicas entre versiones hicieron que inevitablemente heredar cambios fuera una Mala Idea. Sí, puede poner una instantánea en el medio para bloquear la herencia, pero luego todos los cambios tienen que ser empujados manualmente, y la única diferencia real entre los flujos padre-instantánea-hijo y paralelos que no heredan es que toda la vista de flujo gráfico empuja continuamente hacia abajo y hacia la derecha, que es un PITA.

Uno realmente lo bueno de AccuRev es que tienes esta opción, todo el tiempo. No es una restricción inherente de la arquitectura de su programa SCM.

 2
Author: enigment,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-08 13:35:30

¿Has notado que también puedes revisar versiones de archivos específi cos con GIT?

Solo usa esto:

git checkout [< tree-ish >] [--] < paths >

Como por especificación de configuración, cualquier versión existente de un archivo (rutas) se puede cargar en el árbol de trabajo. Cita de git-checkout docs:

La siguiente secuencia comprueba la rama master, revierte el Makefile a dos revisiones, elimina hello.c por error, y lo recupera del índice:

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            
 2
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-07 15:22:26

ClearCase, sin multisitio, es un repositorio único pero Git está distribuido. ClearCase se compromete a nivel de archivo, pero Git se compromete a nivel de repositorio. (Esta última diferencia significa que la pregunta original se basa en un malentendido, como se señaló en los otros mensajes aquí.)

Si estas son las diferencias de las que estamos hablando, entonces creo que 'lineal' versus 'DAG' es una forma confusa de distinguir estos sistemas SCM. En ClearCase todas las versiones de un archivo se denominan la versión del archivo "árbol", pero en realidad es un gráfico acíclico dirigido! La verdadera diferencia con Git es que los DAG de ClearCase existen por archivo. Así que creo que es engañoso referirse a ClearCase como no-DAG y Git como DAG.

(Por cierto ClearCase versiones de sus directorios de una manera similar a sus archivos - pero eso es otra historia.)

 1
Author: Darren Yeats,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-30 14:26:44

No estoy seguro de si estás preguntando algo, pero estás demostrando que los streams de Accurev son herramientas diferentes a las ramas de Git (o SVN). (No conozco a Clearcase.)

Por ejemplo, con Accurev estás obligado, como dices, a usar ciertos flujos de trabajo, lo que te da un historial auditable de cambios que no es compatible con Git. La herencia de Accurev hace que ciertos flujos de trabajo sean más eficientes y otros imposibles.

Con Git puedes tener la codificación exploratoria segregada en repositorios locales o en ramas de características, que Accurev no soportaría muy bien.

Diferentes herramientas son buenas para diferentes propósitos; es útil preguntar para qué sirve cada una .

 0
Author: Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-18 14:33:12