git - traer - divergir sinonimo
bifurcación maestra y ''origen/maestro'' han divergido, ¿cómo ''desviar'' bifurcaciones ''? (10)
De alguna manera mi maestro y mi origen / rama maestra han divergido. En realidad no quiero que se diviertan. ¿Cómo puedo ver estas diferencias y ''fusionarlas''?
En mi caso, aquí está lo que hice para provocar el mensaje git commit --amend
: hice git push
pero luego git commit --amend
para agregar algo al mensaje de confirmación. Entonces también hice otro commit.
Así que en mi caso eso simplemente significaba que el origen / maestro estaba desactualizado. Como sabía que nadie más estaba tocando origen / maestro, la solución fue trivial: git push -f
(donde -f
significa fuerza)
En mi caso, esto fue causado por no cometer mi resolución de conflictos.
El problema fue causado al ejecutar el comando git pull
. Los cambios en el origen llevaron a conflictos con mi repositorio local, que resolví. Sin embargo, no los cometí. La solución en este punto es confirmar los cambios ( git commit
el archivo resuelto)
Si también ha modificado algunos archivos desde que resolvió el conflicto, el comando git status
mostrará las modificaciones locales como modificaciones locales sin etapas y la resolución de combinaciones como modificaciones locales por etapas. Esto se puede resolver de forma adecuada al enviar los cambios desde la fusión primero con git commit
, luego agregar y git commit
los cambios no programados como de costumbre (por ejemplo, por git commit -a
).
En mi caso, puse los cambios en origin/master
y luego me di cuenta de que no debería haberlo hecho :-( Esto se complicó por el hecho de que los cambios locales estaban en un subárbol. Así que volví a la última confirmación correcta antes de " mal "cambios locales (utilizando SourceTree) y luego me salió el" mensaje de divergencia ".
Después de arreglar mi desorden localmente (los detalles no son importantes aquí) quería "mover hacia atrás en el tiempo" la rama de origin/master
remoto para que estuviera sincronizada con el master
local nuevamente. La solución en mi caso fue:
git push origin master -f
Tenga en cuenta el interruptor -f
(fuerza). Esto eliminó los "cambios erróneos" que habían sido empujados al origin/master
por error y ahora las sucursales locales y remotas están sincronizadas.
Tenga en cuenta que esta es una operación potencialmente destructiva, así que hágala solo si está 100% seguro de que "retroceder" el maestro remoto a tiempo es correcto.
Me encontré en esta situación cuando traté de cambiar de base una rama que estaba rastreando una rama remota, y estaba tratando de volver a clasificarla en maestro. En este escenario, si intenta realizar una rebase, lo más probable es que encuentre su rama divergida y puede crear un desastre que no es para git nubees.
Digamos que estás en la rama my_remote_tracking_branch, que fue bifurcada del maestro
$ git status
# En la rama my_remote_tracking_branch
nada que cometer (directorio de trabajo limpio)
Y ahora estás tratando de rebase de maestro como:
git rebase master
¡PARE AHORA y ahórrese algunos problemas! En su lugar, utiliza fusionar como:
git merge master
Sí, terminarás con compromisos adicionales en tu sucursal. Pero a menos que esté preparado para las ramas "no divergentes", este será un flujo de trabajo mucho más suave que el rebasado. Vea este blog para una explicación mucho más detallada.
Por otro lado, si su sucursal es solo una sucursal local (es decir, aún no está conectada a ningún control remoto), definitivamente debería hacer una rebase (y su sucursal no divergirá en este caso).
Ahora, si está leyendo esto porque ya se encuentra en un escenario "desviado" debido a tal rebase, puede volver a la última confirmación desde el origen (es decir, en un estado sin desvío) usando:
git reset - hard origin / my_remote_tracking_branch
Para ver las diferencias:
git difftool --dir-diff master origin/master
Esto mostrará los cambios o diferencias entre las dos ramas. En araxis (Mi favorito) lo muestra en una carpeta de estilo diferente. Mostrando cada uno de los archivos modificados. Luego puedo hacer clic en un archivo para ver los detalles de los cambios en el archivo.
Puedes revisar las diferencias con un:
git log HEAD..origin/master
antes de tirar (buscar + fusionar) (ver también "¿Cómo hacer que git siempre tire de una rama específica?" )
Cuando tengas un mensaje como:
"Su rama y ''origen / maestro'' se han desviado, # y tienen 1 y 1 confirmación (s) diferentes cada uno, respectivamente."
, compruebe si necesita actualizar el origin
. Si el origin
está actualizado, entonces algunas confirmaciones se han enviado a origin
desde otro repositorio mientras realizas tus propias confirmaciones a nivel local.
... o ---- o ---- A ---- B origin/master (upstream work)
/
C master (your work)
Basó el commit C en el commit A porque ese era el último trabajo que había recuperado en ese momento.
Sin embargo, antes de que intentara regresar al origen, otra persona presionó el commit B.
La historia del desarrollo ha divergido en caminos separados.
A continuación, puede fusionar o rebase. Consulte Pro Git: Git Branching - Rebasing para más detalles.
Unir
Usa el comando git merge:
$ git merge origin/master
Esto le dice a Git que integre los cambios de origin/master
en su trabajo y cree un compromiso de fusión.
La gráfica de la historia ahora se ve así:
... o ---- o ---- A ---- B origin/master (upstream work)
/ /
C ---- M master (your work)
La nueva combinación, commit M, tiene dos padres, cada uno de los cuales representa una ruta de desarrollo que condujo al contenido almacenado en ese commit.
Tenga en cuenta que la historia detrás de M ahora no es lineal.
Rebase
Utilice el comando git rebase:
$ git rebase origin/master
Esto le indica a Git que reproduzca commit C (su trabajo) como si lo hubiera basado en commit B en lugar de A.
Los usuarios de CVS y Subversion rutinariamente cambian sus cambios locales sobre el trabajo ascendente cuando se actualizan antes de confirmar.
Git solo agrega una separación explícita entre los pasos de confirmación y rebase.
La gráfica de la historia ahora se ve así:
... o ---- o ---- A ---- B origin/master (upstream work)
/
C'' master (your work)
Commit C ''es un nuevo commit creado por el comando git rebase.
Es diferente de C en dos formas:
- Tiene una historia diferente: B en lugar de A.
- Su contenido explica los cambios tanto en B como en C; es lo mismo que M del ejemplo de combinación.
Tenga en cuenta que la historia detrás de C ''sigue siendo lineal.
Hemos elegido (por ahora) permitir solo el historial lineal en cmake.org/cmake.git
.
Este enfoque preserva el flujo de trabajo basado en CVS utilizado anteriormente y puede facilitar la transición.
Un intento de insertar C ''en nuestro repositorio funcionará (suponiendo que usted tenga permisos y nadie haya presionado mientras estaba rebasando).
El comando git pull proporciona una forma abreviada de buscar desde el origen y reajustar el trabajo local en él:
$ git pull --rebase
Esto combina los pasos anteriores de búsqueda y rebase en un solo comando.
Sé que hay muchas respuestas aquí, pero creo que git reset --soft HEAD~1
merece algo de atención, porque le permite mantener los cambios en la última confirmación local (no presionada) mientras se resuelve el estado divergente. Creo que esta es una solución más versátil que tirar con rebase
, porque el compromiso local se puede revisar e incluso mover a otra rama.
La clave es usar --soft
, en lugar de los duros - --hard
. Si hay más de 1 confirmación, debería funcionar una variación de HEAD~x
. Así que aquí están todos los pasos que resolvieron mi situación (tuve 1 confirmación local y 8 confirmaciones en el control remoto):
1) git reset --soft HEAD~1
para deshacer la confirmación local. Para los siguientes pasos, he usado la interfaz en SourceTree, pero creo que los siguientes comandos también deberían funcionar:
2) git stash
para esconder los cambios de 1). Ahora todos los cambios son seguros y ya no hay divergencias.
3) git pull
para obtener los cambios remotos.
4) git stash pop
o git stash apply
para aplicar los últimos cambios ocultos, seguidos de un nuevo commit, si se desea. Este paso es opcional, junto con 2) , cuando se quieren deshacer los cambios en la confirmación local. Además, cuando desee comprometerse con otra rama, este paso se debe realizar después de cambiar a la deseada.
Tenía el mismo mensaje cuando intentaba editar el último mensaje de confirmación, de git commit --amend -m "New message"
, usando: git commit --amend -m "New message"
Cuando git commit --amend -m "New message"
los cambios usando git push --force-with-lease repo_name branch_name
no hubo problemas
Tuve esto y estoy desconcertado en cuanto a lo que lo causó, incluso después de leer las respuestas anteriores. Mi solucion fue hacer
git reset --hard origin/master
Luego, eso simplemente restablece mi copia (local) del maestro (que supongo que se ha jodido) en el punto correcto, como lo representa el origen / maestro (remoto).
ADVERTENCIA : perderá todos los cambios que aún no se hayan enviado a
origin/master
.
git pull --rebase origin/master
Es un comando único que puede ayudarlo la mayor parte del tiempo.
Editar: extrae las confirmaciones del origen / maestro y aplica sus cambios en el nuevo historial de derivaciones.