Error de Git y "La rama 'x' no está completamente fusionada"

294

Aquí están los comandos que usé de la rama maestra

git branch experiment
git checkout experiment

Luego realicé algunos cambios en mis archivos, los comprometí y empujé la nueva rama a GitHub.

git commit . -m 'changed files'
git push -u origin experiment

Más tarde, decidí fusionar mi rama experimental en la rama maestra.

git checkout master
git merge experiment

Finalmente empujé los cambios a GitHub.

git push -u origin master

Todo salió bien hasta que intenté eliminar mi rama de experimento usando

git branch -d experiment

Recibí el mensaje de error error: The branch 'experiment' is not fully merged.que soy un poco nuevo en git, y no sé cuánto más podría fusionar las dos ramas. ¿Que me estoy perdiendo aqui?

suave
fuente
2
¿Te ayuda esta publicación? stackoverflow.com/questions/1710894/…
Chrisdigital
2
Esto aparece a veces cuando he hecho ungit commit --amend
Arcolye
12
Además, tenga en cuenta que este mensaje aparecerá después de squash: stackoverflow.com/q/41946475/109941
Jim G.
Creo que el escenario más común es que solo necesita extraer los cambios recién fusionados antes de eliminar la rama localmente.
RaisinBranCrunch

Respuestas:

313

Nota La redacción cambió en respuesta a los comentarios. Gracias @slekse
Eso no es un error, es una advertencia. Significa que la rama que está a punto de eliminar contiene confirmaciones a las que no se puede acceder desde: su rama ascendente o HEAD (revisión actualmente desprotegida). En otras palabras, cuándo podrías perder commits¹.

En la práctica, significa que probablemente modificó, modificó o confirmó las confirmaciones y no parecen idénticas.

Por lo tanto, puede evitar la advertencia al verificar una rama que contiene las confirmaciones de las que está sin referencia eliminando esa otra rama.²

Deberá verificar que, de hecho, no le faltan confirmaciones vitales:

git log --graph --left-right --cherry-pick --oneline master...experiment

Esto le dará una lista de cualquier no compartido entre las ramas. En caso de que tenga curiosidad, puede haber una diferencia sin --cherry-picky esta diferencia podría ser la razón de la advertencia que recibe:

--cherry-pick

Omita cualquier confirmación que introduzca el mismo cambio que otra confirmación en el "otro lado" cuando el conjunto de confirmaciones está limitado por la diferencia simétrica. Por ejemplo, si tiene dos ramas, A y B, una forma habitual de enumerar todas las confirmaciones en un solo lado es con --izquierda-derecha, como el ejemplo anterior en la descripción de esa opción. Sin embargo, muestra los commits que fueron seleccionados de la otra rama (por ejemplo, "3rd on b" puede ser seleccionado de la rama A). Con esta opción, dichos pares de confirmaciones se excluyen de la salida.


Really en realidad son solo basura recolectada después de un tiempo, por defecto. Además, el git-branchcomando no verifica el árbol de revisión de todas las ramas . La advertencia está ahí para evitar errores obvios.

² (Mi preferencia aquí es forzar la eliminación en su lugar, pero es posible que desee tener la tranquilidad adicional).

sehe
fuente
24
Gracias. La frase clave era "contiene confirmaciones a las que no se puede acceder desde ningún otro encabezado de referencia". Aunque ya no necesitaba la rama del experimento, y ya la había fusionado con la maestra, y planeaba eliminarla del origen, git no iba a ser feliz hasta que empujara los cambios para experimentar al origen. Supongo que esta advertencia fue una especie de control de cordura.
mellowsoon
35
-1 "Significa que la rama que está a punto de eliminar contiene confirmaciones a las que no se puede acceder desde ningún otro encabezado de referencia". Esto no es correcto. La advertencia significa que no se puede acceder a la rama desde su flujo ascendente (si tiene una) o desde la CABEZA actual. Vea la página de manual de git-branch.
sleske
3
@TachyonVortex Buen enlace. El comando git branch -vv realmente aclaró lo que estaba pasando por mí.
Jason Massey
11
@sleske Gracias por el comentario: esta respuesta realmente debería editarse. Es una pena que haya sido muy votado porque la oración explicativa principal es incorrecta. Acabo de tener este problema y pasé un tiempo molesto tratando de descubrir cuál era el problema, y ​​era solo que la rama de seguimiento remoto se había eliminado como parte de la solicitud de extracción, y en el tiempo transcurrido desde que extraje los cambios del maestro en la sucursal local. El único 'problema' no fue encontrar la rama de seguimiento remoto, que se eliminó (y estaba tratando de eliminar la rama local por el mismo motivo).
ely
3
Sí, esto puede suceder simplemente cuando intentas eliminar una rama local si estás en una rama diferente de la que estabas cuando la creaste. "¡Los commits a los que no se puede acceder desde ninguna otra referencia" son incorrectos y sin miedo!
Amalgovinus
80

Como señaló Drew Taylor, la eliminación de la rama con -d solo considera el HEAD actual para determinar si la rama está "completamente fusionada". Se quejará incluso si la rama se fusiona con alguna otra rama. El mensaje de error definitivamente podría ser más claro a este respecto ... Puede retirar la rama combinada antes de eliminarla o simplemente usar git branch -D. La capital -D anulará el cheque por completo.

drwowe
fuente
2
La parte sobre HEAD actual me lo arregló. Mi maestro era diferente de la rama de características de la cual creé la rama en conflicto: D
viki.omega9
1
Para alguien que está aprendiendo git, la palabra "actual" parece redundante con "HEAD"? No existe una HEAD no actual: la HEAD, por definición, es la rama actual . ¿Me estoy perdiendo de algo? Supongo que podría decir "rama actual" o "CABEZA" pero no "CABEZA actual".
Mark Lakata
¿Hay alguna forma de cambiar / configurar esto (p. Ej., ¿Siempre tiene que verificar origin/master?) Supongo que verificar origin/masterprimero no es demasiado oneroso, pero se siente como una especie de flujo extraño: ¿por qué necesito verificar origin/masterlocalmente? ¿solo para que verifiques que mis cambios se fusionan allí?
Alec
15

Intenté la respuesta de Sehe y no funcionó.

Para encontrar las confirmaciones que no se han fusionado, simplemente use:

git log feature-branch ^master --no-merges
qwertzguy
fuente
14

Hoy me sucedió esto, ya que estaba fusionando mi primera rama de características nuevamente en master. Como algunos dijeron en un hilo en otra parte de SO, el truco fue cambiar de nuevo a maestro antes de intentar eliminar la rama. Una vez de vuelta en master, git se alegró de eliminar la rama sin ninguna advertencia.

Drew Taylor
fuente
77
No parece que ese sea el problema específico aquí, pero me encontré con el problema que usted describe ahora, ¡así que gracias!
Daniel Buckmaster
4

Git advierte que puede perder el historial al eliminar esta rama. Aunque en realidad no eliminaría ninguna confirmación de inmediato, algunas o todas las confirmaciones de la rama quedarían inalcanzables si no son parte de otra rama también.

Para que la rama experimentse “fusione completamente” en otra rama, su confirmación de punta debe ser un antecesor de la punta de la otra rama, haciendo que las confirmaciones estén en experimentun subconjunto de la otra rama. Esto hace que sea seguro eliminarlo experiment, ya que todas sus confirmaciones seguirán siendo parte del historial del repositorio a través de la otra rama. Debe fusionarse "completamente", porque puede que ya se haya fusionado varias veces, pero ahora se han agregado confirmaciones desde la última fusión que no están contenidas en la otra rama.

Sin embargo, Git no verifica todas las demás ramas en el repositorio; sólo dos:

  1. La rama actual (HEAD)
  2. La rama aguas arriba, si hay una

La "rama ascendente" para experiment, como en su caso, es probablemente origin/experiment. Si experimentestá completamente fusionado en la rama actual, Git lo elimina sin ninguna queja. Si no es así, pero está completamente fusionado en su rama aguas arriba, entonces Git procede con una advertencia que parece:

warning: deleting branch 'experiment' that has been merged
to 'refs/remotes/origin/experiment', but not yet merged to
HEAD.
Deleted branch experiment (was xxxxxxxx).

Donde xxxxxxxxindica un id de confirmación. Estar completamente fusionado en su flujo ascendente indica que los commits experimentse han enviado al repositorio de origen, por lo que incluso si los pierde aquí, al menos se pueden guardar en otro lugar.

Dado que Git no verifica otras ramas, puede ser seguro eliminar una rama porque sabe que está completamente fusionada con otra; puede hacer esto con la -Dopción como se indica, o cambiar a esa rama primero y dejar que Git confirme el estado completamente fusionado por usted.

troore
fuente
1
La clave está "completamente fusionada en la rama actual ". Tenía una rama X 'de X completamente fusionada con X y ya había eliminado origin / X'. Pero con Y verificado, recibí esta advertencia. Cuando salí de XI pude eliminar X '. Es bastante estúpido, creo.
Lawrence Dol
2
Esta respuesta está plagiada desde aquí sin atribución chimera.labs.oreilly.com/books/1230000000561/…
Mark Lakata
3

para ver los cambios que no se fusionan, hice esto:

git checkout experiment
git merge --no-commit master

git diff --cached

Nota: Esto muestra cambios masterque no están en experiment.

No te olvides de:

git merge --abort

Cuando termines de mirar.

ThorSummoner
fuente
@IgorGanapolsky Dunno exactamente, aunque generalmente man git-resety los comandos git reset son suficientes para recuperarse de problemas de estado.
ThorSummoner
3

Solución más fácil con explicación (solución doblemente verificada) (enfrentó el problema antes)

El problema es:

1- No puedo borrar una rama

2- El terminal sigue mostrando un mensaje de advertencia de que hay algunas confirmaciones que aún no están aprobadas

3- sabiendo que revisé el master y la rama y que son idénticos (actualizados)

solución:

git checkout master
git merge branch_name
git checkout branch_name
git push
git checkout master
git branch -d branch_name

Explicación:

cuando su rama está conectada a una rama remota ascendente (en Github, bitbucket o lo que sea), debe fusionarla (empujarla) en el maestro, y debe empujar los nuevos cambios (confirmaciones) al repositorio remoto (Github, bitbucket o lo que sea) de la rama,

Lo que hice en mi código es que cambié a maestro, luego fusioné la rama en él (para asegurarme de que sean idénticos en su máquina local), luego cambié a la rama nuevamente y envié las actualizaciones o cambios al control remoto en línea repositorio usando "git push".

después de eso, cambié al maestro nuevamente, e intenté eliminar la rama, y ​​el problema (mensaje de advertencia) desapareció, y la rama se eliminó con éxito

Elta3lab
fuente
3

Simplemente puedes descubrir:

git log --cherry master ... experimental

--cherry opción es sinónimo de --right-only --cherry-mark --no-merges

la página de manual de git-log dijo

es útil limitar la salida a los commits de nuestro lado y marcar los que se han aplicado al otro lado de una historia bifurcada con git log --cherry upstream ... mybranch, similar a git cherry upstream mybranch.

FYI. --cherry-pickomite confirmaciones equivalentes pero --cherry-marksno lo hace. Es útil encontrar rebase y forzar cambios actualizados entre la rama pública ascendente y colaboradora

Yongbin
fuente
1

No tenía la rama aguas arriba en mi git local. Había creado una sucursal local de master, git checkout -b mybranch. Creé una rama con bitbucket GUI en el git ascendente y empujé mi rama local (mybranch) a esa rama ascendente. Una vez que hice una búsqueda de git en mi git local para recuperar la rama aguas arriba, pude hacer una rama de git -d mybranch.

edW
fuente
0

Creo que la bandera --forcees lo que realmente estás buscando. Solo use git branch -d --force <branch_name>para eliminar la rama por la fuerza.

Sergey Samoylenko
fuente