Git fusiona rama de revisión en rama de características
Digamos que tenemos la siguiente situación en Git:
Un repositorio creado:
mkdir GitTest2 cd GitTest2 git init
Se realizan y confirman algunas modificaciones en el master:
echo "On Master" > file git commit -a -m "Initial commit"
Feature1 se bifurcó en master y se realizó algo de trabajo:
git branch feature1 git checkout feature1 echo "Feature1" > featureFile git commit -a -m "Commit for feature1"
Mientras tanto, se descubre un error en el código maestro y se establece una rama de revisión:
git checkout master git branch hotfix1 git checkout hotfix1
El error se corrigió en la rama de revisión y se fusionó nuevamente con la rama maestra (quizás después de una solicitud de extracción/revisión de código):
echo "Bugfix" > bugfixFile git commit -a -m "Bugfix Commit" git checkout master git merge --no-ff hotfix1
El desarrollo de la característica 1 continúa:
git checkout feature1
Digamos que necesito la revisión en mi rama de funciones, tal vez porque el error también ocurre allí. ¿Cómo puedo lograr esto sin duplicar las confirmaciones en mi rama de funciones?
Quiero evitar obtener dos nuevas confirmaciones en mi rama de funciones que no tienen relación con la implementación de la función. Esto me parece especialmente importante si uso solicitudes de extracción: todas estas confirmaciones también se incluirán en la solicitud de extracción y deberán revisarse aunque esto ya se haya hecho (ya que la revisión ya está en el archivo maestro).
No puedo hacer un git merge master --ff-only
: "fatal: No es posible avanzar rápido, abortando", pero no estoy seguro de si esto me ayudó.
¿Cómo fusionamos la rama maestra con la rama característica? Fácil:
git checkout feature1
git merge master
No tiene sentido forzar una fusión rápida aquí, ya que no se puede hacer. Se comprometió tanto en la rama característica como en la rama maestra. Ahora es imposible avanzar rápido.
Eche un vistazo a GitFlow . Es un modelo de ramificación para git que se puede seguir, e inconscientemente ya lo hiciste. También es una extensión de Git que agrega algunos comandos para los nuevos pasos del flujo de trabajo que hacen cosas automáticamente que de otro modo tendrías que hacer manualmente.
Entonces, ¿qué hiciste bien en tu flujo de trabajo? Tiene dos ramas con las que trabajar, su rama feature1 es básicamente la rama "desarrollar" en el modelo GitFlow.
Creó una rama de revisión desde master y la volvió a fusionar. Y ahora estás estancado.
El modelo de GitFlow le pide que combine la revisión también con la rama de desarrollo, que en su caso es "feature1".
Entonces la verdadera respuesta sería:
git checkout feature1
git merge --no-ff hotfix1
Esto agrega todos los cambios que se realizaron dentro de la revisión a la rama de funciones, pero solo esos cambios. Es posible que entren en conflicto con otros cambios de desarrollo en la rama, pero no entrarán en conflicto con la rama maestra si eventualmente fusiona la rama de características con la rama maestra.
Tenga mucho cuidado con el rebase. Sólo rebase si los cambios que hizo permanecieron locales en su repositorio, por ejemplo, no envió ninguna rama a ningún otro repositorio. Rebasar es una gran herramienta para organizar tus confirmaciones locales en un orden útil antes de lanzarlas al mundo, pero rebasar después arruinará las cosas para los principiantes de git como tú.
Deberías poder cambiar la base de tu rama en master:
git checkout feature1
git rebase master
Gestionar todos los conflictos que surjan. Cuando llegue a las confirmaciones con las correcciones de errores (ya en master), Git dirá que no hubo cambios y que tal vez ya se aplicaron. Luego continúas la rebase (mientras te saltas las confirmaciones que ya están en master) con
git rebase --skip
Si realiza una git log
en su rama de funciones, verá que la confirmación de corrección de errores aparece solo una vez y en la parte maestra.
Para obtener una discusión más detallada, consulte la documentación del libro de Git en git rebase
( https://git-scm.com/docs/git-rebase ) que cubre este caso de uso exacto.
================ Editar para contexto adicional =====================
Esta respuesta se proporcionó específicamente para la pregunta de @theomega, teniendo en cuenta su situación particular. Tenga en cuenta esta parte:
Quiero evitar [...] confirmaciones en mi rama de funciones que no tienen relación con la implementación de la función.
Rebasar su rama privada en master es exactamente lo que producirá ese resultado. Por el contrario, fusionar master en su rama haría precisamente lo que él específicamente no quiere que suceda : agregar una confirmación que no esté relacionada con la implementación de la característica en la que está trabajando a través de su rama.
Para dirigirme a los usuarios que leen el título de la pregunta, omiten el contenido y el contexto reales de la pregunta, y luego solo leen la respuesta principal a ciegas, suponiendo que siempre se aplicará a su (diferente) caso de uso, permítanme explicarles:
- solo rebase las sucursales privadas (es decir, que solo existen en su repositorio local y no han sido compartidas con otros). Cambiar la base de las ramas compartidas "rompería" las copias que otras personas puedan tener.
- si desea integrar cambios de una rama (ya sea maestra u otra rama) en una rama que es pública (por ejemplo, ha presionado la rama para abrir una solicitud de extracción, pero ahora hay conflictos con la rama maestra y necesita actualizar su rama para resolver esos conflictos) deberá fusionarlos (por ejemplo,
git merge master
como en la respuesta de @Sven). - También puede fusionar sucursales en sus sucursales privadas locales si así lo prefiere, pero tenga en cuenta que esto resultará en confirmaciones "extranjeras" en su sucursal.
Finalmente, si no está satisfecho con el hecho de que esta respuesta no es la mejor opción para su situación, aunque fuera para @theomega, agregar un comentario a continuación no será particularmente útil: No controlo qué respuesta se selecciona, solo @theomega lo hace.
git merge
puedes seguir los pasos a continuación
1. fusionar origin/master
rama con feature
rama
# step1: change branch to master, and pull to update all commits
$ git checkout master
$ git pull
# step2: change branch to target, and pull to update commits
$ git checkout feature
$ git pull
# step3: merge master to feature(⚠️ current is feature branch)
$ git merge master
2. fusionar feature
rama con origin/master
rama
origin/master
es la rama maestra remota, mientras quemaster
es la rama maestra local
$ git checkout master
$ git pull origin/master
$ git merge feature
$ git push origin/master
Según este artículo , deberías:
crear una nueva rama que se base en la nueva versión de master
git branch -b newmaster
fusiona tu antigua rama de funciones en una nueva
git checkout newmaster
resolver conflicto en la nueva rama de funciones
Los dos primeros comandos se pueden combinar para git checkout -b newmaster
.
De esta manera, su historial permanece claro porque no necesita fusiones posteriores. Y no es necesario que seas tan cauteloso ya que no es necesario realizar una rebase de Git.