Aquí hay un flujo de trabajo con el que me ocupo habitualmente en el trabajo.
git checkout -b feature_branch
# Do some development
git add .
git commit
git push origin feature_branch
En este punto, mis colegas deben revisar la rama de funciones, pero quiero seguir desarrollando otras funciones de las que dependen feature_branch
. Entonces, mientras feature_branch
está en revisión ...
git checkout feature_branch
git checkout -b dependent_branch
# Do some more development
git add .
git commit
Ahora hago algunos cambios en respuesta a la revisión del código en feature_branch
git checkout feature_branch
# Do review fixes
git add .
git commit
git checkout dependent_branch
git merge feature_branch
Ahora aquí es donde tenemos problemas. Tenemos una política de aplastamiento en el maestro, lo que significa que las ramas de características que se fusionan en el maestro deben comprimirse en una única confirmación.
git checkout feature_branch
git log # Look for hash at beginning of branch
git rebase -i first_hash_of_branch # Squash feature_branch into a single commit
git merge master
Todo está bien, excepto con dependent_branch
. Cuando trato de cambiar la base de la rama dependiente al maestro o intento fusionar el maestro en él, git se confunde con el historial reescrito / aplastado y básicamente marca cada cambio depedendent_branch
como un conflicto. Es un PITA para pasar y básicamente rehacer o eliminar los conflictos de todos los cambios dependent_branch
. ¿Hay alguna solución para esto? A veces, creo manualmente un parche y lo aplico desde una nueva rama del maestro, pero si hay algún conflicto real con eso, es aún peor arreglarlo.
git checkout dependent_branch
git diff > ~/Desktop/dependent_branch.diff
git checkout master
git checkout -b new_dependent_branch
patch -p1 < ~/Desktop/dependent_branch.diff
# Pray for a clean apply.
¿Algunas ideas? Sé que esto sucede debido al historial reescrito durante el squash, pero ese es un requisito que no puedo cambiar. ¿Cuál es la mejor solución / alternativa? ¿Hay algo de magia que pueda hacer? ¿O hay una forma más rápida de realizar todos los pasos relacionados con la creación manual de la diferencia?
git add .
es completamente malvado y eventualmente te morderá cuando termines cometiendo cosas que no pretendías. Debería usargit add -p
o al menosgit add -u .
Respuestas:
Un poco sobre por qué sucede esto:
Dejaré que
O
sea "maestro original" yFB
"nuevo maestro", después de que una rama de función se haya fusionado en:Decir se
feature_branch
parece a:dependent_feature
tiene algunas confirmaciones adicionales además de eso:Fusiona su rama de características original en master y la aplasta, lo que le brinda:
Ahora, cuando intente cambiar la base de la rama dependiente, git intentará descubrir el ancestro común entre esas ramas. Si bien originalmente lo habría sido
C
, si no hubiera reducido las confirmaciones, git encuentraO
como el ancestro común. Como resultado, git está tratando de reproducirA
,B
yC
los que están ya contenía enFB
, y usted va a obtener un montón de conflictos.Por esta razón, realmente no puede confiar en un comando de rebase típico, y debe ser más explícito al proporcionar el
--onto
parámetro:Modifique el
HEAD~3
parámetro según sea necesario para sus sucursales y no debería tener que lidiar con ninguna resolución de conflicto redundante.Alguna sintaxis alternativa, si no le gusta especificar rangos y aún no ha eliminado su rama de función original:
fuente
En este caso particular, parece que "sabe" que sólo se ha puesto en master el trabajo aplastado de la rama en la que trabajó originalmente.
Para que pueda fusionarse felizmente manteniendo sus cambios cada vez que haya un conflicto. Hay una opción para eso:
git merge -Xours master
Consulte https://git-scm.com/docs/git-rebase para obtener más detalles.
fuente
Estoy totalmente en desacuerdo con la política de "combinar cada desarrollo de funciones en una única confirmación", pero es su decisión ...
Mantendría las ramas tal como están y crearía una confirmación combinada solo para su publicación, en una rama especial. Ser capaz de seguir el desarrollo paso a paso es valioso, incluso si la dirección no cree en él. Marque los lugares de los squashes con etiquetas en las ramas "reales", también puede agregar etiquetas entre squash con mensajes que apunten a las confirmaciones reales.
fuente