En conflictos de rebase, ¿cómo decir "usar file de la twig A, eliminar el file del maestro"?

Estoy sacando una twig de github, my-new-branch , para revisarla. Ha modificado los files de compilation en (lo sé, lo sé). Como era de esperar, recibí un conflicto en el file minificado cuando lo extraje / rebase.

No quiero revisar manualmente cada cambio en el file modificado. Solo quiero decir "use el file de my-new-branch , elimine el file del máster, continúe el rebase".

¿Cómo puedo hacer esto?

Primero déjame poner las notas usuales:

  • git pull es esencialmente git fetch seguido de git merge o git rebase . Hace la rebase en lugar de la combinación cuando se lo dice, a través de --rebase o una input de configuration. En general, prefiero usar los dos commands separados, aunque para casos específicos en los que estoy seguro de que deseo una fusión regular o una rebase, usaré git pull .

    Esto es muy importante porque en merge vs rebase los roles de nuestro / ellos se intercambian, porque …

  • git rebase es esencialmente una secuencia de repetidas operaciones de git cherry-pick , realizada en una nueva, temporal y anónima sucursal. Una vez que todas las confirmaciones que se networkingefinirán se han seleccionado con éxito en la nueva sucursal anónima, Git quita la label de sucursal de la antigua cadena de compromisos, pegándola en la nueva cadena.

    Esto significa que cuando estás rebase, tu sucursal actual es una sucursal anónima, y ​​la sucursal de la cual viene cada compromiso, que Git llama "suya", como en --theirs -X theirs o -X theirs --theirs es en realidad tu propia sucursal. La twig que Git llama "nuestra", como en --ours o -X ours , será su sucursal, ¡pero todavía no! Para el primer paso en particular, la twig anónima apunta a la confirmación a la que se está refinanciando, que es la (s) nueva (s) confirmación (es) que trajo cuando usted (o su git pull ) ejecutó git fetch . En otras palabras, es su compromiso, no el tuyo, a pesar de que Git se refiere a él con --ours .

  • Por el contrario, cuando te estás fusionando ( git merge ), Git se queda en tu propia sucursal, y --ours y -X ours refiere a tu sucursal mientras que --theirs y -X theirs refieren a su sucursal.

La mayoría de las personas considera que este nuestro intercambio de roles al less es un poco confuso, por lo que si está confundido, no está solo. Creo que ayuda si practicas con git cherry-pick , pero incluso así puede ser complicado.

Ahora, a los pasos prácticos de realmente hacer la rebase.

Digamos que comienzas con un ram de bra :

 $ git checkout bra 

Luego, haces algo como:

 $ git rebase origin/master 

para copyr cualquier compromiso que tengas en tu bra , que tampoco esté ya en origin/master , para que aparezca después de la sugerencia de origin/master en una nueva twig que, al final, se labelrá como bra .

Inicialmente, tienes esto:

  E--F--G <-- bra / ...--A--B--C--D <-- origin/master 

Al final, tendrás esto:

  E--F--G [abandoned - original bra] / ...--A--B--C--D <-- origin/master \ E'-F'-G' <-- bra 

El primer paso en la rebase es descubrir cuál se compromete a elegir. Normalmente, eso es solo "todas las confirmaciones en la twig original que no están en el destino", es decir, E , F y G en este caso.

A continuación, Git comtesting la confirmación de sugerencia de la twig de destino: confirma D , aquí, como un "HEAD separado" (twig anónima), y ejecuta un bucle de commands de git cherry-pick (o algo equivalente: exactamente qué command se usa depende en qué banderas le das a git rebase ). El primero elige con precisión E compromete a hacer la copy E' . Tenga en count que la confirmación actual ahora confirma D

Aquí es donde entran las banderas de nosotros y las suyas. Echemos un vistazo a lo que hace git cherry-pick con más detalle, ya que es aquí donde quiere resolver sus conflictos.

Una selección de cereza comienza comparando un compromiso con su padre. En este caso, estamos seleccionando E , por lo que comparamos E con el compromiso primario de E , que es B compromiso. Esto nos da una list de cambios línea por línea: eliminar estas líneas, agregar algunas otras líneas como reemploops. Git ahora intenta aplicar esta diferencia (como una fusión) contra la confirmación actual, que es D Tenga en count que también hay cambios de B a D , por lo que Git realmente puede hacer una fusión, con los conflictos de fusión habituales y la resolución de conflictos.

Digamos que uno de los cambios de B a E tiene este aspecto, en el file README :

 @@ ... @@ this is some context -we ditched this +and added this better line and kept this the same 

Si no aparece un cambio similar en B -to- D , Git toma una copy de este cambio. Pero si, en B -to- D , tenemos esto en su lugar:

 @@ ... @@ this is some context -we ditched this +to put in a superior line and kept this the same 

Git declara un conflicto: no es seguro si la línea "superior" es mejor que la línea "mejor", o viceversa.

Usar -X ours o -X theirs dice a git qué línea prefiere en caso de conflicto. Digamos que usas -X theirs : esto significa que prefieres el cambio B -a- E . Esto se debe a que "nuestro" cambio es el de B a D : esa es la twig (anónima) en la que estamos; "su" cambio es el de B a E

Esto no significa "tomar su file completo" . Solo significa "tomar su cambio ". Digamos que en otro lugar en B -to- D , también cambiamos algo de ortografía, pero nunca tocamos esas líneas en B -to- E Usar -X theirs toma los cambios BE pero deja los cambios B to- D solos .

Podemos, en cambio, dejar que Git detenga la rebase en este punto y ejecutar manualmente:

 $ git checkout --theirs -- README 

o:

 $ git checkout <id of commit E> -- README 

Esto significa "tomar todo el file de la confirmación E exactamente como aparece en la confirmación E ", es decir, descartar cualquier cambio B to- D .

Una vez que hemos resuelto los conflictos, al tomar automáticamente "sus" (es decir, los nuestros) cambian con -X theirs , o al tomar manualmente "su (s) file (s) con git checkout --theirs , y continuar manualmente el process de rebase de recolección de cerezas:

 $ git rebase --continue 

-Git hace un nuevo commit E' usando el README resuelto, y continúa para seleccionar el commit F , haciendo un E to- F diff y aplicando eso para cometer E' .

Dependiendo de lo que pongamos en comprometer E' , esto puede aplicarse limpiamente, o puede get más conflictos de fusión. Si esto genera más conflictos de fusión, Git los maneja de acuerdo con nuestras instrucciones, de la misma manera que antes.

Por último, Git elige a G haciendo una diferencia de F a G y aplicando eso a F' .

Para finalizar la rebase, Git simplemente quita el bra label de la twig de G y lo hace apuntar a G' . Los compromisos E--F--G ahora están abandonados (aunque todavía están en sus reflogs, y por lo tanto permanecerán en su repository durante al less más de 30 días por defecto).