Me encontré con un conflicto de fusión. ¿Cómo puedo abortar la fusión?

2539

Usé git pully tuve un conflicto de fusión:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

Sé que la otra versión del archivo es buena y que la mía es mala, por lo que todos mis cambios deberían abandonarse. ¿Cómo puedo hacer esto?

Gwyn Morfey
fuente
30
Me doy cuenta de que esta es una pregunta muy antigua, pero ¿desea cancelar la fusión completa y dejar la rama que estaba fusionando sin fusionar, o simplemente ignorar este archivo como parte de una fusión más grande, dejando que todos los demás archivos se fusionen como ¿normal? Para mí, su título implica lo primero, su cuerpo de preguntas quiere lo segundo. Las respuestas hacen ambas cosas, sin dejar las cosas claras.
rjmunro
Obtuve un caso similar en commit diciendo que la fusión automática falló; solucionar conflictos y luego cometer el resultado:[rejected] gh-pages -> gh-pages (non-fast-forward)
Chetabahana
44
Gwyn, podría ser útil seleccionar una respuesta aceptada aquí. La mejor votada es un poco menos segura que algunas de las soluciones más actualizadas, por lo que creo que ayudaría a destacar a otras sobre ella :)
Amistoso el

Respuestas:

2222

Como pullno tuvo éxito, entonces HEAD(no HEAD^) es el último compromiso "válido" en su rama:

git reset --hard HEAD

La otra pieza que desea es dejar que sus cambios anulen sus cambios.

Las versiones anteriores de git le permitían usar la estrategia de fusión "de ellos":

git pull --strategy=theirs remote_branch

Pero esto se ha eliminado desde entonces, como lo explica Junio ​​Hamano (el responsable de mantenimiento de Git) en este mensaje . Como se señaló en el enlace , en su lugar haría esto:

git fetch origin
git reset --hard origin
Pat Notz
fuente
49
En lugar de hacer un restablecimiento completo, puede llevarlo a un nivel más granular haciendo: git fetch origin -> git reset origin (soft reset, your changes are still present) -> git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin) Ya nunca uso git pull. Como en una pelea entre mi último código y el origen, el origen siempre debe ganar, siempre git fetchy git rebase origin. Esto realmente hace que mis fusiones y conflictos sean pocos y distantes entre sí.
Kzqai
77
Estoy de acuerdo. También me gusta buscar primero, y luego examinar los cambios aguas arriba ( git log ..@{upstream}o git diff ..@{upstream}). Después de eso, como tú, rebajaré mi trabajo.
Pat Notz
162
Como se señaló en una respuesta más reciente, a partir de la versión 1.6.1, es posible usar 'git reset --merge'
Matt Ball
55
He utilizado git merge -X theirs remote_branchen lugar de git pull --strategy=theirs remote_branchque theirsse parece a una opción derecursive
MLT
14
git merge --abortEs muy preferible.
Daniel Cassidy
1956

Si su versión de git es> = 1.6.1, puede usar git reset --merge.

Además, como menciona @Michael Johnson, si su versión de git es> = 1.7.4, también puede usarla git merge --abort.

Como siempre, asegúrese de no tener cambios sin confirmar antes de comenzar una fusión.

Desde la página de manual de git merge

git merge --abortes equivalente a git reset --mergecuando MERGE_HEADestá presente.

MERGE_HEAD está presente cuando hay una fusión en curso.

Además, con respecto a los cambios no confirmados al iniciar una fusión:

Si tiene cambios que no desea confirmar antes de comenzar una fusión, solo git stashellos antes de la fusión y git stash popdespués de terminar la fusión o cancelarla.

Carl
fuente
3
Interesante, pero el manual me da miedo. ¿Cuándo es exactamente apropiado usar? ¿Cuándo tendría que especificar el opcional <commit>? #GitMoment: -o
conny
1
Normalmente usaría esto cuando desee rehacer la fusión desde el principio. Nunca he tenido que especificar el commit opcional, así que el valor predeterminado (no <commit> opcional) está bien.
Carl
44
¡Ojalá esta respuesta tuviera más votos! En este punto, parece ser la solución más relevante en muchos casos.
Jay Taylor
1
Incluso con cambios no comprometidos, git pudo restaurar el estado antes de la fusión. ¡Agradable!
T3rm1
2
¿Es git merge --abortsolo un sinónimo de git reset --merge? El nombre ciertamente tiene más sentido, pero ¿tiene la misma funcionalidad?
Tikhon Jelvis
518
git merge --abort

Anule el proceso actual de resolución de conflictos e intente reconstruir el estado previo a la fusión.

Si hubo cambios de árbol de trabajo no confirmados presentes cuando comenzó la fusión, git merge --aborten algunos casos no podrá reconstruir estos cambios. Por lo tanto, se recomienda confirmar o guardar siempre los cambios antes de ejecutar git merge.

git merge --abortes equivalente a git reset --mergecuando MERGE_HEADestá presente.

http://www.git-scm.com/docs/git-merge

ignis
fuente
16
Esto ha estado disponible desde git v1.7.4. Es un alias para git reset --merge.
Michael Johnson
162

Es tan simple.

git merge --abort

Git mismo le muestra la solución cuando se encuentra en este tipo de problemas y ejecuta el comando git status.

git status

Espero que esto ayude a la gente.

Jagruttam Panchal
fuente
97

Creo que es lo git resetque necesitas.

Tenga en cuenta que eso git revertsignifica algo muy diferente a, digamos, svn reverten Subversion, la reversión descartará sus cambios (no confirmados), devolviendo el archivo a la versión actual desde el repositorio, mientras que git revert"deshace" una confirmación.

git resetdebe hacer el equivalente de svn revert, es decir, descartar los cambios no deseados.

David precioso
fuente
76

En este caso de uso en particular, realmente no desea abortar la fusión, solo resuelva el conflicto de una manera particular.

Tampoco hay necesidad particular de reiniciar y fusionar con una estrategia diferente. Los conflictos han sido resaltados correctamente por git y el requisito de aceptar los cambios de los otros lados es solo para este archivo.

Para un archivo no fusionado en un conflicto, git pone a disposición la base común, las versiones locales y remotas del archivo en el índice. (Aquí es donde se leen para usar en una herramienta de diferencias de 3 vías git mergetool). Puede usar git showpara verlos.

# common base:
git show :1:_widget.html.erb

# 'ours'
git show :2:_widget.html.erb

# 'theirs'
git show :3:_widget.html.erb

La forma más simple de resolver el conflicto para usar la versión remota textualmente es:

git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb

O, con git> = 1.6.1:

git checkout --theirs _widget.html.erb
CB Bailey
fuente
55
gracias por la pista. Sin embargo, ¿no parece una interfaz de usuario git pobre?
Peter
@ Peter: No estoy convencido. El resultado deseado se puede lograr con algunos comandos básicos con opciones simples. ¿Qué mejoras sugerirías?
CB Bailey
10
Creo que el git 1.6.1comando tiene mucho sentido y es bueno. Eso es exactamente lo que hubiera querido. Creo que la solución anterior a 1.6.1 no es elegante y requiere conocimiento sobre otras partes de git que deberían separarse del proceso de resolución de fusión. ¡Pero la nueva versión es genial!
Peter
67

Por ejemplo, lo hice git fetchy git pullluego me di cuenta de que la rama ascendente no era la rama maestra, lo que resultó en conflictos no deseados.

git reset --merge 

Esto se revirtió sin restablecer mis cambios locales.

naamadheya
fuente
45

Los comentarios sugieren que git reset --mergees un alias para git merge --abort. Vale la pena notar que git merge --abortsolo es equivalente a git reset --mergedado que a MERGE_HEADestá presente. Esto se puede leer en el comando git help for merge.

git merge --abort es equivalente a git reset --merge cuando MERGE_HEAD está presente.

Después de una fusión fallida, cuando no existe MERGE_HEAD, la fusión fallida se puede deshacer git reset --merge, pero no necesariamente con git merge --abort. No son solo sintaxis antiguas y nuevas para la misma cosa .

Personalmente, encuentro git reset --mergemucho más poderoso para escenarios similares al descrito, y las fusiones fallidas en general.

Martin G
fuente
2
¿Qué se entiende aquí por "fusión fallida"? ¿Fusionarse con conflictos u otra cosa? O para reformularlo: ¿cuándo MERGE_HEAD no está presente? Mi pregunta de seguimiento está ahí para entender mejor el uso de "git reset --merge".
Ewoks
@Ewoks me git stash applycausó un conflicto de fusión, pero git merge --abortno ayudó mientras lo git reset --mergehizo.
nitzel
27

Si termina con un conflicto de fusión y no tiene nada que confirmar, pero aún se muestra un error de fusión. Después de aplicar todos los comandos mencionados a continuación,

git reset --hard HEAD
git pull --strategy=theirs remote_branch
git fetch origin
git reset --hard origin

Por favor eliminar

.git \ index.lock

Archivo [cortar y pegar en otra ubicación en caso de recuperación] y luego ingresar cualquiera de los comandos a continuación según la versión que desee.

git reset --hard HEAD
git reset --hard origin

¡¡¡Espero que ayude!!!

Nirav Mehta
fuente
19

Una alternativa, que conserva el estado de la copia de trabajo es:

git stash
git merge --abort
git stash pop

En general, desaconsejo esto, porque es efectivamente como fusionarse en Subversion, ya que descarta las relaciones de ramificación en la siguiente confirmación.

Alain O'Dea
fuente
Encontré este enfoque útil cuando accidentalmente me fusioné con una rama git-svn, que no funciona tan bien. Las fusiones de calabaza o las selecciones de cereza son mejores cuando se trabaja con ramas de seguimiento git-svn. En efecto, mi solución convierte una fusión en una fusión de calabaza después del hecho.
Alain O'Dea
La mejor respuesta a la pregunta
Fouad Boukredine
18

Desde que Git 1.6.1.3 git checkoutha podido pagar desde cualquier lado de una fusión:

git checkout --theirs _widget.html.erb
Alain O'Dea
fuente
3

Encontré que lo siguiente funcionó para mí (revertir un solo archivo al estado previo a la fusión):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*
Malcolm Boekhoff
fuente
-5

Sourcetree

Debido a que no confirma su fusión, simplemente haga doble clic en otra rama (lo que significa verificarla) y cuando sourcetree le pregunte si desea descartar todos los cambios, entonces acepte :)

Kamil Kiełczewski
fuente