Rebasar sucursales remotas en Git

135

Estoy usando un repositorio Git intermedio para reflejar un repositorio SVN remoto, desde el cual las personas pueden clonar y trabajar. El repositorio intermedio tiene su rama maestra rebaseada todas las noches desde el SVN ascendente, y estamos trabajando en ramas de características. Por ejemplo:

remote:
  master

local:
  master
  feature

Puedo empujar con éxito mi rama de características al control remoto y terminar con lo que espero:

remote:
  master
  feature

local:
  master
  feature

Luego vuelvo a configurar la rama para rastrear el control remoto:

remote:
  master
  feature

local:
  master
  feature -> origin/feature

Y todo esta bien. Lo que me gustaría hacer desde aquí es cambiar la base de la rama de características a la rama maestra en el control remoto, pero me gustaría hacerlo desde mi máquina local. Me gustaría poder hacer:

git checkout master
git pull
git checkout feature
git rebase master
git push origin feature

Para mantener la rama de funciones remotas actualizada con el maestro remoto. Sin embargo, este método hace que Git se queje:

To <remote>
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to '<remote>'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

git pullhace el truco pero provoca una confirmación de fusión que me gustaría evitar. Me preocupa que el mensaje indique feature -> featuremás que, feature -> origin/featurepero esto puede ser solo una presentación.

¿Me estoy perdiendo algo o hago esto de una manera completamente incorrecta? No es crítico evitar hacer el rebase en el servidor remoto, pero hace que arreglar cualquier conflicto de fusión del rebase sea mucho más difícil.

kfb
fuente
Yo tuve el mismo problema. Quería comenzar un modelo de rebase de sucursal ( como este ). Luego me di cuenta de que cometí un error: si desea volver a modificar (no debe enviar los cambios a la función remota antes de realizar la modificación en el maestro). Así que confirme un código a su función. Y ahora desea llevarlo a su función remota. Tenga en cuenta que debe hacer esto: -Debe buscar y atraer a su maestro si es necesario. -Debe rebase en el maestro si ha habido algunos cambios en el maestro que no tiene en su función. Ahora puede presionar la función y no habrá ningún problema.
Markus

Respuestas:

185

Todo se reduce a si la función es utilizada por una persona o si otros están trabajando fuera de ella.

Puedes forzar el empuje después del rebase si solo eres tú:

git push origin feature -f

Sin embargo, si otros están trabajando en ello, debe fusionarse y no rebase del master.

git merge master
git push origin feature

Esto asegurará que tengas un historial común con las personas con las que estás colaborando.

En un nivel diferente, no deberías hacer back-merges. Lo que está haciendo es contaminar el historial de su rama de características con otras confirmaciones que no pertenecen a la característica, lo que hace que el trabajo posterior con esa rama sea más difícil, rebase o no.

Este es mi artículo sobre el tema llamado rama por característica .

Espero que esto ayude.

Adam Dymitruk
fuente
29
+1 para if others are working on it, you should merge and not rebase off of master, rebase mejor se usará solo en una rama privada.
Hendra Uzia
66
Alternativa a la función de origen de inserción de git -f también podría eliminar su función remota y la función de inserción nuevamente
Markus
2
Fusionar master en su rama creará un commit de fusión y causará conflictos con cualquier otra rama de característica abierta de master después de que se empujan sus cambios.
Steven
+1 para git push origin feature -f. En ciertos contextos, puede ser necesario realizar un rebase incluso con ramas remotas. El quid es saber lo que estás haciendo. Y debemos asumir que puede estar eliminando confirmaciones en el repositorio remoto.
enagra
33

Es bueno que hayas mencionado este tema.

Esta es una cosa / concepto importante en git que una gran cantidad de usuarios de git se beneficiarían de conocer. git rebase es una herramienta muy poderosa y te permite juntar commits, eliminar commits, etc. Pero como con cualquier herramienta poderosa, básicamente necesitas saber lo que estás haciendo o algo podría salir realmente mal.

Cuando trabaje localmente y juegue con sus sucursales locales, puede hacer lo que quiera siempre que no haya enviado los cambios al repositorio central. Esto significa que puede reescribir su propia historia, pero no la historia de otros. Solo jugando con tus cosas locales, nada tendrá ningún impacto en otros repositorios.

Es por eso que es importante recordar que una vez que haya empujado las confirmaciones, no debe volver a crearlas más adelante. La razón por la cual esto es importante, es que otras personas podrían hacer sus compromisos y basar su trabajo en sus contribuciones a la base del código, y si luego decide mover ese contenido de un lugar a otro (volver a redactarlo) y empujarlos cambios, entonces otras personas tendrán problemas y tendrán que cambiar su código. Ahora imagine que tiene 1000 desarrolladores :) Simplemente causa una gran cantidad de modificaciones innecesarias.

ralphtheninja
fuente
Votado a favor del mal lenguaje: meta.stackexchange.com/questions/22232/…
Poderes
1
Actualicé mi idioma.
ralphtheninja
5

Debido a que usted reformuló featuresobre lo nuevo master, su local featureya no es un avance rápido origin/feature. Entonces, creo que está perfectamente bien en este caso anular la verificación de avance rápido haciendo git push origin +feature. También puede especificar esto en su configuración

git config remote.origin.push +refs/heads/feature:refs/heads/feature

Si otras personas trabajan además origin/feature, se verán perturbadas por esta actualización forzada. Puede evitar eso fusionándose en el nuevo masteren featurelugar de rebase. El resultado será un avance rápido.

Tilman Vogel
fuente
1

Puede deshabilitar la verificación (si está realmente seguro de saber lo que está haciendo) utilizando la --forceopción para git push.

Andrew Aylett
fuente
15
El problema es que no estoy seguro de saber realmente lo que estoy haciendo :)
kfb
@r_: Por favor lea mi respuesta. Podría ayudarte a entender lo que estás haciendo :)
ralphtheninja