@Mark Longair lo logró en su respuesta aquí , pero me gustaría agregar una idea adicional.
Relacionado y respondiendo a la pregunta de cómo dividir una solicitud de extracción (PR) grande, especialmente cuando aplastar sus confirmaciones no es práctico debido a una o más fusiones de master en su feature_branch
Mi situación:
hice una gran apuesta feature_branch
con 30 confirmaciones y abrí una solicitud de extracción (PR) en GitHub para fusionarla master
. Branch master
cambió una tonelada debajo de mí y recibió 200 confirmaciones feature_branch
que no tenía. Para resolver conflictos que hice git checkout feature_branch
y git merge master
para fusionar master
los cambios en mi feature_branch
. Elegí en merge
lugar del rebase
último maestro, por lo que tendría que resolver los conflictos solo una vez en lugar de potencialmente 30 veces (una vez para cada una de mis confirmaciones). No quería aplastar mis 30 commits en 1 primero y luego rebase en el últimomaster
porque eso podría borrar el historial de comentarios de revisión de GitHub en el PR. Entonces, fusioné master en mi rama de características y resolví conflictos 1 sola vez. Todo estuvo bien. Sin embargo, mi RP era demasiado grande para que mis colegas la revisaran. Necesitaba dividirlo. Fui a aplastar mis 30 commits y ¡OH NO! ¿DÓNDE ESTÁN? ¡TODOS ESTÁN INTERMITADOS CON master
las 200 confirmaciones recientes ahora porque me fusioné con master
mi feature_branch
! ¿QUÉ DEBO HACER?
git cherry
uso en caso de que quiera intentar git cherry-pick
confirmaciones individuales:
git cherry
al rescate (más o menos)!
Para ver todos los commits que están dentro feature_branch
pero NO dentro master
, puedo hacer:
git checkout feature_branch
git cherry master
O bien, puedo verificar las confirmaciones de CUALQUIER rama sin asegurarme de que estoy en feature_branch
primer lugar haciendo git cherry [upstream_branch] [feature_branch]
esto. Nuevamente, esto verifica qué confirmaciones ESTÁN en feature_branch
pero NO en upstream_branch
( master
en este caso):
git cherry master feature_branch
Agregar -v
también muestra las líneas de asunto del mensaje de confirmación:
git cherry -v master
La canalización a "recuento de palabras", "líneas" ( wc -l
) cuenta cuántas confirmaciones hay:
git cherry master | wc -l
Puede comparar este recuento con el número de confirmación que se muestra en su GithHub PR para sentirse mejor al saber que git cherry
realmente está funcionando. También puede comparar los hash de git uno por uno y ver si coinciden con git cherry
GitHub. Tenga en cuenta que git cherry
no contará ningún commit de combinación en la que fueron fusionados master
en feature_branch
, pero GitHub VOLUNTAD. Entonces, si ve una pequeña discrepancia en el recuento, busque en la página de confirmación de relaciones públicas de GitHub la palabra "fusionar" y probablemente verá que ese es el culpable que no aparece git cherry
. Por ejemplo: una confirmación titulada "Combinar rama 'maestro' en feature_branch" aparecerá en el PR de GitHub, pero no cuando se ejecute git cherry master feature_branch
. Esto está bien y se espera.
Entonces, ahora tengo un medio para descubrir qué diferencias me gustaría elegir en una nueva rama de características para dividir esta diferencia: puedo usar git cherry master feature_branch
localmente o mirar los commits en el PR de GitHub.
Cómo podría ayudar el aplastamiento, si tan solo pudiéramos aplastarlo:
Sin embargo, una alternativa para dividir mi gran diferencia es aplastar mis 30 confirmaciones en una sola, aplicar un parche en una nueva rama de características, restablecer de forma parcial la confirmación de la revisión, luego usar git gui
para agregar piezas archivo por archivo, fragmento por fragmento o linea por linea. Una vez que obtengo una subfunción, puedo confirmar lo que he agregado y luego revisar una nueva rama, agregar un poco más, confirmar, revisar una nueva rama, etc., hasta que tenga mi gran característica dividida en varias subfunciones . El problema es que mis 30 commits se entremezclan con los otros 200 commits de otras personas debido a mi git merge master
en mi feature_branch
, por lo que rebase no es práctico, ya que tendría que seleccionar 230 commits para reordenar y aplastar mis 30 commits.
Cómo usar un archivo de parche como un reemplazo mucho más fácil para aplastar:
Una solución alternativa es simplemente obtener un archivo de parche que contenga un "equivalente de squash" de mis 30 confirmaciones, parchearlo en una nueva bifurcación de master
(una nueva rama de subfunción) y trabajar desde allí, de la siguiente manera:
git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch
Ahora tengo mi parche de 30 confirmaciones todo aplicado localmente, pero sin etapas y sin compromiso.
Ahora use git gui
para agregar archivos, fragmentos y / o líneas y dividir su gran PR o "diff":
Tenga en cuenta que si no tiene git gui
, puede instalarlo fácilmente en Ubuntu con sudo apt install git-gui
.
Ahora puedo ejecutar git gui
y comenzar a agregar archivos, fragmentos y / o líneas (haciendo clic con el botón derecho en el programa git GUI), y dividir la rama de la función de confirmación 30 en sub ramas como se describe arriba, agregando, confirmando y bifurcando repetidamente una nueva rama de funciones y repetir este ciclo hasta que todos los cambios se hayan agregado a una rama secundaria y mi función de confirmación 30 se divida con éxito en 3 o 4 subcaracterísticas. Ahora puedo abrir un RP por separado para cada una de estas subfunciones, y será más fácil para mi equipo revisarlas.
Referencias
- Cree un parche o un archivo diff desde el repositorio git y aplíquelo a otro repositorio git diferente