Git Merging: lo que sucede con 2 sucursales fusionadas al mismo time

Tengo una comprensión poco clara sobre la fusión en git, que me gustaría entender correctamente.

Digamos que tengo un file F en la twig principal, que ya tiene 100 LOC. Creo una twig A desde master, y escribo 50 LOC, comienza desde la línea 101 a la línea 150. Creo una request de fusión para fusionar la twig A con la maestra. Entonces, si la twig A se fusionará, entonces el file F en el maestro tendrá 150 LOC

Supongamos que la twig A aún no se fusionó para dominar, aún esperando. Y creo una nueva twig B desde el maestro. También escribo 50 LOC, también comienza desde la línea 101 a la 150 (porque la twig A aún no está fusionada). Y también creo un MR para la twig B

¿Qué pasará si 2 personas revisan 2 MR y:

  1. Se fusionan 2 MR al mismo time? ¿El maestro tendrá un conflicto, porque ambas twigs quieren fusionarse en la línea 101 a la 150?

  2. Si la twig A se fusiona primero, significa que el maestro ya tiene 150 LOC, pero la twig B todavía comienza desde la línea 101 a la 150, porque se creó desde el maestro cuando todavía tenía 100 LOC. ¿Habrá también un conflicto cuando B se fusione? ¿O cómo lo maneja Git?

Gracias de antemano (no soy un troll, solo quiero descubrir cosas, en caso de que algunas personas vayan a marcar esta pregunta)

Algo para aclarar, creo: los conflictos y las estrategias de fusión son un concepto de git en sí mismo. "Solicitud de combinación", OTOH, es un concepto de gitlab (y otros hosts de repos tienen conceptos similares) pero no significa nada en absoluto. Su pregunta se responde mejor hablando de git; así que solo necesitamos saber que una request de fusión es un flujo de trabajo mediante el cual se puede iniciar una operación de fusión en git. Así que tomemos su pregunta en dos partes:

Fusiones secuenciales

Respuesta corta: probablemente habrá un conflicto.

Si habrá un conflicto dependerá de la estrategia de fusión. Mis testings sugieren que normalmente habría un conflicto, ya que git ve cambios alternativos en las líneas 101 – 150. Dado que ambos sets de cambios son agregados, creo que podría concebir que ambos sets de líneas se agreguen sin conflicto, aunque no está claro en qué order entraría. Puedes hacer que git intente hacer eso usando el controller de fusión de union ; ver http://kernel.org/pub/software/scm/git/docs/gitattributes.html

Puedes decirle a git que resuelva las fusiones de diferentes maneras a través de los arguments de la command-line, pero dado que esas instrucciones se aplicarían a la confirmación completa, no solo el file en el que se configura esta condición, normalmente no querrás hacerlo. Podría usar .gitattributes para influir en cómo git fusiona solo un file, si puede saber de antemano cuándo será el correcto para el file (completo).

Por lo tanto, hay muchas opciones sobre cómo cambiar el comportamiento de merge : demasiadas para detallar aquí sin conocer un resultado específico deseado. Pero por lo general, funciona bien usar las configuraciones de fusión pnetworkingeterminadas y resolver conflictos cuando ocurren, en mi experiencia de todos modos.

Fusiones concurrentes

En realidad, no es posible que se produzcan dos fusiones "al mismo time" dentro de un solo repository. Si un host proporciona alguna forma de iniciar una fusión en el repository alojado ( origin ) directamente, lo que en realidad no sé que lo haga nadie, sino por el argumento, entonces una fusión tendría que completarse primero, y la otra lo haría ver el resultado de esa combinación como punto de partida; así que mira la parte anterior de la respuesta para eso.

Lo que puede suceder es que una persona puede realizar una fusión en un repository y otra puede realizar otra fusión en un segundo repository, y luego puede haber conflictos cuando ambos intentan sincronizarse con el control remoto. Y así es como se verá eso:

(Tenga en count que a lo largo de este ejemplo estoy asumiendo fusiones verdaderas , es decir, qué pasaría si utiliza la opción no-ff . Los charts de fusión podrían ser más simples, pero los resultados serían los mismos en lo que respecta a los conflictos, si es rápido- se permitieron fusiones hacia adelante)

Entonces el repository comienza con

  B <--(branch_B) / x -- x -- O <--(master) \ A <--(branch_A) 

Todos los commits contienen un solo file. En O ese file tiene 100 líneas. A y B agregan cada uno 50 líneas nuevas al final del file.

Ahora Alice fusiona branch_A , y Bob fusiona branch_B , cada uno en su repository local. Entonces Alice tiene

  B <--(branch_B) / x -- x -- O -- MA <--(master) \ / A ^-(branch_A) 

y Bob tiene

  v-(branch_B) B / \ x -- x -- O -- MB <--(master) \ A <--(branch_A) 

Para compartir su trabajo, cada uno tratará de push hacia el origin ; y al igual que con merge s, uno completará primero antes de que el otro comience, incluso si intentan comenzar a empujar exactamente en el mismo momento.

Entonces Alice recibe su impulso, y el origin se actualiza para parecerse a su local. Cuando Bob intenta presionar, obtiene un error porque su master está detrás del master en el origin (o, podríamos decir, detrás del origin/master una vez que se ha actualizado, asumiendo asignaciones típicas).

Entonces Bob tiene que pull (o fetch y merge ) antes de poder push . Para ilustrarlo más claramente, supongamos que él fetch es. Ahora él tiene

  v-(branch_B) B / \ x -- x -- O -- MB <--(master) |\ | MA <--(origin/master) |/ A <--(branch_A) 

y para completar el efecto de un pull , necesita fusionar el origin/master en el master , por lo que incluso este caso se networkinguce a la situación de "fusión secuencial" cubierta primero. De hecho, si traza el mismo escenario usando fusiones de avance rápido, quedará claro que la "2da fusión" necesaria aquí es exactamente igual a la "2da fusión" si todo fue hecho por un usuario en un repository.