Actualizar ramas de Git desde master
Tengo cuatro ramas (master, b1, b2 y b3). Después de trabajar en b1-b3, me di cuenta de que tenía algo que cambiar en la rama maestra que debería estar en todas las demás ramas. Cambié lo que necesitaba enmaster
y... aquí está mi problema:
¿ Cómo actualizo todas las demás sucursales con master
el código de sucursal?
Tienes dos opciones:
La primera es una fusión, pero esto crea una confirmación adicional para la fusión.
Consulta cada sucursal:
git checkout b1
Luego fusiona:
git merge origin/master
Luego presione:
git push origin b1
Alternativamente, puedes hacer una rebase:
git fetch
git rebase origin/master
Tienes básicamente dos opciones:
Te fusionas. En realidad, esto es bastante simple y una operación perfectamente local:
git checkout b1 git merge master # repeat for b2 and b3
Esto deja el historial exactamente como sucedió: se bifurcó desde master, realizó cambios en todas las ramas y finalmente incorporó los cambios desde master en las tres ramas.
git
puede manejar esta situación muy bien, está diseñado para fusiones que ocurren en todas direcciones, al mismo tiempo. Puede confiar en que podrá unir todos los hilos correctamente. Simplemente no le importa si la ramab1
se fusionamaster
omaster
se fusionab1
, la confirmación de fusión se ve igual para git. La única diferencia es qué rama termina apuntando a esta confirmación de fusión.Tu rebase. Las personas con un SVN o experiencia similar lo encuentran más intuitivo. Los comandos son análogos al caso de fusión:
git checkout b1 git rebase master # repeat for b2 and b3
A la gente le gusta este enfoque porque conserva una historia lineal en todas las ramas. Sin embargo, esta historia lineal es mentira, y debes ser consciente de que lo es. Considere este gráfico de confirmación:
A --- B --- C --- D <-- master \ \-- E --- F --- G <-- b1
La fusión da como resultado la historia real:
A --- B --- C --- D <-- master \ \ \-- E --- F --- G +-- H <-- b1
La rebase, sin embargo, te da esta historia:
A --- B --- C --- D <-- master \ \-- E' --- F' --- G' <-- b1
El punto es que las confirmaciones
E'
,F'
yG'
nunca existieron realmente y probablemente nunca han sido probadas. Puede que ni siquiera compilen. En realidad, es bastante fácil crear confirmaciones sin sentido mediante una rebase, especialmente cuando los cambiosmaster
son importantes para el desarrollo deb1
.La consecuencia de esto puede ser que no se pueda distinguir cuál de los tres comete
E
,F
yG
en realidad introdujo una regresión, disminuyendo el valor degit bisect
.No estoy diciendo que no debas usar
git rebase
. Tiene sus usos. Pero siempre que lo utilices, debes ser consciente del hecho de que estás mintiendo sobre la historia. Y al menos deberías compilar y probar las nuevas confirmaciones.
git rebase master
es la forma correcta de hacer esto. La fusión significaría que se crearía una confirmación para la fusión, mientras que el cambio de base no.
Si ha estado trabajando en una rama de forma intermitente, o si han sucedido muchas cosas en otras ramas mientras trabajaba en algo, es mejor cambiar la base de su rama a master. Esto mantiene el historial ordenado y hace que todo sea mucho más fácil de seguir.
git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed
Notas:
- No cambies la base de las ramas en las que has colaborado con otros.
- Debe volver a basarse en la rama con la que se fusionará, que puede no siempre ser maestra.
Hay un capítulo sobre rebase en http://git-scm.com/book/ch3-6.html y muchos otros recursos disponibles en la web.