Git merge informa que "ya está actualizado" aunque hay una diferencia

286

Tengo un repositorio git con 2 ramas: master y test.

Existen diferencias entre las ramas maestra y de prueba.

Ambas sucursales tienen todos los cambios comprometidos.

Si lo hago:

git checkout master
prueba de diferencia de git

Aparece una pantalla llena de cambios que muestra las diferencias. Quiero fusionar los cambios en la rama de prueba y también lo hago:

prueba de fusión git

Pero reciba el mensaje "Ya actualizado"

Sin embargo, examinar archivos debajo de cada rama diferente muestra claramente las diferencias.

¿Cuál es el problema aquí y cómo lo resuelvo?

Charles Darke
fuente
¿Tiene código modificado sin compromiso?
ozma

Respuestas:

146

El mensaje "Ya actualizado" significa que todos los cambios de la sucursal que está intentando fusionar ya se han fusionado con la sucursal en la que se encuentra actualmente. Más específicamente, significa que la rama que está intentando fusionar es una matriz de su rama actual . Felicitaciones, esa es la fusión más fácil que jamás harás. :)

Use gitkpara echar un vistazo a su repositorio. La etiqueta para la rama "prueba" debe estar en algún lugar debajo de la etiqueta de la rama "maestra".

Su sucursal está actualizada con respecto a su matriz. Según la fusión, no hay nuevos cambios en el padre desde la última fusión. Eso no significa que las ramas sean iguales, porque puede tener muchos cambios en su rama de trabajo y parece que sí.

Editar 10/12/2019:

Según Charles Drake en el comentario a esta respuesta, una solución para remediar el problema es:

git checkout master
git reset --hard test

Esto lo lleva de vuelta al nivel de 'prueba'.

Entonces hazlo:

git push --force origin master

para forzar cambios de nuevo al repositorio central.

Bombe
fuente
2
Holy cr * p! ¡Tienes razón! Creo que lo que sucedió fue que otra rama (desarrollo inestable) se fusionó incorrectamente con master y la rama de prueba era un subconjunto de inestable. La fusión que estaba tratando de hacer era devolver al maestro al nivel de "prueba".
Charles Darke
2
Correcto. Esa operación no tendría ningún sentido, por lo que Git se niega a hacer nada. :)
Bombe
24
Lo que he hecho ahora es: git checkout master; git reset - prueba dura; Esto lo lleva de vuelta al nivel de 'prueba'. Luego hice un "git push - force origin master" para forzar los cambios de regreso al repositorio central.
Charles Darke
22
Hubiera sido bueno si git tuviera una advertencia para decir "tratando de fusionarse con el padre".
Charles Darke
1
Empujar una rama que no es descendiente de la rama que ya existe en el lado remoto se considera algo malo: vea las discusiones en las páginas de manual para git-push y git-pull.
Bombe
131

Esto a menudo me sucede cuando sé que hay cambios en el maestro remoto, por lo que trato de fusionarlos usando git merge master. Sin embargo, esto no se fusiona con el maestro remoto, sino con su maestro local.

Entonces, antes de hacer la fusión, finalice la compra y luego git pullallí. Entonces podrá fusionar los nuevos cambios en su rama.

ACarter
fuente
77
¿Hay alguna forma de evitar el cambio de ramas, algo así como hacer un tirón de la rama que se fusionará mientras aún está en la rama en la que se fusionará y luego fusionar?
Japheth Ongeri - inkalimeva
Ahh, linda. Pensé git fetchque actualizaría la rama maestra incluso si actualmente estoy en una diferente. Resulta que no. ¡Gracias! Estoy bastante seguro de que hay una opción fetchque le permite especificar qué rama obtener.
Raik
1
@Raik Puedes hacerlo git fetch --all, pero esto solo busca las ramas, no las tira.
Ingo Bürk
66
@ JaphethOngeri-inkalimeva Puedes hacerlo git fetch --all && git merge origin/master. No es necesario actualizar su local masterpara fusionar cambios remotos.
Ingo Bürk
@ IngoBürk Tenía 2 sucursales, actualicé 1 con git merge mastery 1 con git merge origin/master. También me fui mastery git pullantes de actualizar 2 sucursales. a pesar de que compartían el mismo contenido, la creación de un PR entre las 2 ramas mostró algunos archivos diff. Lo arreglé por git pullla bifurcación de destino en la bifurcación de características, que mostró: Already up to date! Merge made by the 'recursive' strategy.esto dio como resultado la confirmación de fusión sin cambios, pero eliminó los archivos diff inesperados de PR. ¿Alguna idea de por qué existe una diferencia entre fusionar sucursales locales y remotas "equivalentes"?
wrapperapps
45

Digamos que tiene una rama mastercon el siguiente historial de confirmación:

A -- B -- C -- D

Ahora, crea una prueba de bifurcación, trabaja en ella y realiza 4 confirmaciones:


                 E -- F -- G -- H
                /
A -- B -- C -- D

masterla cabeza apunta a D, y test la cabeza apunta a H.

El mensaje "Ya actualizado" aparece cuando el HEAD de la rama en la que se está fusionando es un padre de la cadena de commits de la rama que desea fusionar. Ese es el caso, aquí: Des padre de E.

No hay nada que fusionado desde testque master, puesto que nada ha cambiado en masterdesde entonces. Lo que quieres hacer aquí es, literalmente, decirle a Git que tenga masterla cabeza apuntando a H, para que la rama del maestro tenga el siguiente historial de confirmaciones:

A -- B -- C -- D -- E -- F -- G -- H

Este es un trabajo para el comando Git reset. También desea que el directorio de trabajo para reflejar este cambio, por lo que va a hacer un disco de restablecimiento:

git reset --hard H
Marek Stanley
fuente
3
Me han dicho en el pasado que usar git reset --hardes algo bastante drástico, ¿puede perder confirmaciones? ¿Existe una forma más segura de hacer estos cambios, o son los peligros de git reset --hardexagerar?
Graham R. Armstrong
1
Este comando es cuerdo, no te preocupes. Diría que lo único a lo que debe prestar atención con la --hardopción es el hecho de que realmente modifica su directorio de trabajo y, como consecuencia, pierde cambios no confirmados. Personalmente, hago un git statusantes y después de cada comando git ejecutado manualmente para asegurarme de que mi repositorio esté limpio o en el estado esperado.
Marek Stanley
esto generará el mensaje de estado "Su sucursal y 'origen / maestro' han divergido", ¿cómo puedo resolverlo?
Eido95
1
Desearía poder darte más de un voto a favor. ¡Gracias!
KMC
¿Hay alguna necesidad de la --hardopción? He estado en esta situación un par de veces y siempre reinicio sin --hard. Funcionó bien sin el riesgo de perder cambios no comprometidos.
Casimir
16

Lo que funciona para mí, digamos que tienes branch1 y quieres fusionarlo en branch2.

Abre la línea de comando git, vaya a la carpeta raíz de branch2 y escriba:

git checkout branch1
git pull branch1
git checkout branch2
git merge branch1
git push

Si tiene conflictos, no necesita hacer git push, primero resuelva los conflictos y luego presione.

Stefan Pintilie
fuente
6

Una fusión siempre se realiza entre el HEAD actual y uno o más commits (generalmente, encabezado o etiqueta de rama),
y el archivo de índice debe coincidir con el árbol del commit HEAD (es decir, el contenido del último commit) cuando comienza.
En otras palabras, no git diff --cached HEADdebe informar cambios.

El commit combinado ya está contenido en HEAD. Este es el caso más simple, llamado "Ya actualizado".

Eso debería significar que los commits en la prueba ya están fusionados en master, pero dado que otros commits se realizan en master, git diff testaún darían algunas diferencias.

VonC
fuente
6

Esto sucede porque su copia local de la sucursal que desea fusionar está desactualizada. Tengo mi sucursal, llamé MyBranchy quiero fusionarla ProjectMaster.

_>git status
On branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

nothing to commit, working tree clean

_>git merge ProjectMaster
Already up-to-date.

¡Pero que hay cambios que deben fusionarse!

Aquí está la cosa, cuando escribo git merge ProjectMaster escribo, git mira mi copia local de esta rama, que podría no estar actualizada . Para ver si este es el caso, lo primero que digo Git para comprobar y ver si mis ramas no están actualizados a buscar cualquier cambio si lo que usar, eh, fetch. Luego me subo a la rama que quiero fusionar para ver qué sucede allí ...

_>git fetch origin

_>git checkout ProjectMaster
Switched to branch ProjectMaster
**Your branch is behind 'origin/ProjectMaster' by 85 commits, and can be fast-forwarded.**
  (use "git pull" to update your local branch)

Ah-ha! Mi copia local está obsoleta por 85 confirmaciones, ¡eso lo explica todo! Ahora, Pullelimino los cambios que me faltan, luego salto MyBranche intento fusionar nuevamente.

_>git pull
Updating 669f825..5b49912
Fast-forward

_>git checkout MyBranch-Issue2
Switched to branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

_>git merge ProjectMaster
Auto-merging Runbooks/File1.ps1
CONFLICT (content): Merge conflict in Runbooks/Runbooks/File1.ps1

Automatic merge failed; fix conflicts and then commit the result.

Y ahora tengo otro problema que solucionar ...

FoxDeploy
fuente
5

Esto me sucedió porque extrañamente GIT pensó que la sucursal local era diferente de la sucursal remota. Esto era visible en el gráfico de rama: mostraba dos ramas diferentes: remotos / origin / branch_name y branch_name.

La solución fue simplemente eliminar el repositorio local y volver a clonarlo desde el control remoto. De esta manera, GIT comprendería que los controles remotos / origin / branch_name> y branch_name son realmente lo mismo, y podría emitir el git merge branch_name.

rm <my_repo>
git clone <my_repo>
cd <my_repo>
git checkout <branch_name>
git pull
git checkout master
git merge <branch_name>
cdupont
fuente
¿No es exactamente la misma respuesta que la de Acarter?
Andrew C
Creo que Acarter realmente perdió el punto, no hubo cambios en el control remoto, ese no fue el problema en absoluto. Necesitaba "git checkout master" y luego "git merge <branch_name>" para forzar la fusión de avance rápido. Al revés no hizo nada ya que la rama estaba por delante del maestro. La respuesta de Bombe es una buena explicación, pero nunca respondió la parte de la pregunta "¿cómo lo resuelvo?".
MrMas
5

git merge origin/masteren cambio git merge masterfuncionó para mí. Entonces, para fusionar master en la rama de características, puede usar:

git checkout feature_branch
git merge origin/master
Tal como
fuente
5

Asegúrese de verificar primero la rama que desea fusionar y luego tire de ella (para que su versión local coincida con la versión remota).

Luego, vuelva a pagar en su sucursal en la que desea realizar la fusión y su fusión git debería funcionar.

John Murphy
fuente
1
Esto fue todo para mí: hice un tirón mientras estaba en el maestro; llegó a saber que obtuve nuevos commits en "branch". Intenté fusionar "branch" en master - "Ya actualizado". Hizo git checkout "rama" - obtuve "Tu rama está detrás ... y se puede reenviar rápidamente", lo que significa que necesitaba actualizar "rama" ejecutando git pullmientras estaba en la "rama"
sdbbs
3

sucedió a mí y me enviaron a esta página, no estoy seguro si tenía el mismo escenario, pero el mío era yo tratando de "volver a fusionar" esa rama de "prueba".

Así que anteriormente lo fusioné, pero excluyo intencionalmente algunos cambios específicos durante esa fusión, por lo que claramente tiene algunas diferencias entre las ramas. Entonces estaba tratando de volver a fusionarlo porque me doy cuenta / olvido que debería haberlo hecho y quería agregar un cambio / archivo en particular que anteriormente había excluido y esperaba que si volviera a hacer una fusión mostrara todos los cambios que excluí antes , pero estaba equivocado y en su lugar recibo el mensaje "Ya actualizado".

Al leer el comentario / respuesta de @Bombe, tiene razón, y creo que se comporta de esa manera, así que lo que hice fue hacer una copia de seguridad de los archivos en la rama de prueba, luego verificar la rama maestra y pegar manualmente los archivos en ella y confirmar como si se tratara de nuevos cambios.

No estoy seguro de si esta es la forma correcta o podría ayudar a otros que tienen este mismo problema, pero sí proporcionó una solución a mi caso particular.

bubjavier
fuente
La misma situación aquí. El escenario es que quiero dividir una rama de "integración" en varias ramas de "características".
Yadli
2
En lugar de pasta manual, puede obtenerlos archivos directamente desde una rama en rama actual: git checkout srcBranch -- path/to/file. Puede usar archivos glob también.
Todd
Gracias, utilicé su método de pago, pero puse checkout srcBranch -- *y luego miré mis diferencias
portforwardpodcast
2

Si la fusión de la rama A en la rama B informa "Ya actualizado", lo inverso no siempre es cierto. Es cierto solo si la rama B es descendiente de la rama A, de lo contrario, la rama B simplemente puede tener cambios que no están en A.

Ejemplo:

  1. Crea ramas A y B fuera del maestro
  2. Realiza algunos cambios en master y combina estos cambios solo en la rama B (sin actualizar u olvidarse de actualizar la rama A).
  3. Realiza algunos cambios en la rama A y combina A con B.

En este punto, la fusión de A a B informa "Ya actualizado" pero las ramas son diferentes porque la rama B tiene actualizaciones del maestro mientras que la rama A no.

Stan Bashtavenko
fuente
2

Enfrenté este escenario usando Git Bash.

Nuestro repositorio tiene múltiples ramas y cada rama tiene un ciclo de confirmación diferente y la fusión ocurre de vez en cuando. Old_Branch se usó como padre para New_Branch

Old_Branch se actualizó con algunos cambios que debían fusionarse con New_Branch

Estaba usando el siguiente comando de extracción sin ninguna rama para obtener todas las fuentes de todas las ramas.

origen de extracción de git

Curiosamente, esto no extrae todos los commits de todas las ramas. Lo había pensado así, ya que lo indicado muestra casi todas las ramas y etiquetas.

Así que para solucionar esto había comprobado que Old_Branch sacó lo último usando

git checkout Old_Branch

git pull origin Old_Branch

Ahora revisado New_Branch

git checkout New_Branch

Lo saqué para estar seguro

git pull origin New_Branch

git merge Old_Branch

Y viola consiguió solucionar los conflictos de Old_Branch a New_Branch :), lo que se esperaba

satlead
fuente
0

Me ha pasado lo mismo. Pero el escenario era un poco diferente, tenía una rama maestra y eliminé release_1 (digamos) de ella. Realizó algunos cambios en la rama release_1 y la fusionó en origen. luego hice ssh y en el servidor remoto volví a pagar release_1 usando el comando git checkout -b release_1, ¡que realmente crea una nueva rama release_! desde el maestro en lugar de verificar la rama existente ya existente release_1 desde el origen. Resolvió el problema eliminando el interruptor "-b"

Deepika Anand
fuente
0

Yo tuve el mismo problema. Tuve cambios en el control remoto y todavía mostraba "Ya actualizado". Reclinar el repositorio solucionó el problema para mí.

Mohammad Rayan
fuente
0

Tonto, pero podría suceder. Suponga que el nombre de su sucursal tiene el prefijo de una referencia de problema (por ejemplo #91-fix-html-markup), si hace esta fusión:

$ git merge #91-fix-html-markup

no funcionará según lo previsto porque todo después de que #se ignora, porque #comienza un comentario en línea.

En este caso se puede cambiar el nombre de la rama omitiendo #o utilizar comillas simples para el nombre de la sucursal: git merge '#91-fix-html-markup'.

Paolo
fuente