Encontrei um conflito de mesclagem. Como posso cancelar a mesclagem?

2539

Eu usei git pulle tive um conflito de mesclagem:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

Eu sei que a outra versão do arquivo é boa e a minha é ruim, portanto todas as minhas alterações devem ser abandonadas. Como posso fazer isso?

Gwyn Morfey
fonte
30
Sei que essa é uma pergunta super antiga, mas você deseja abortar toda a mesclagem e deixar o ramo que estava mesclando imerso ou simplesmente ignorar esse arquivo como parte de uma mesclagem maior, permitindo que todos os outros arquivos sejam mesclados como normal? Para mim, seu título implica o primeiro, seu corpo de perguntas quer o último. As respostas fazem as duas coisas, sem deixar as coisas claras.
Rjmunro 07/10/2013
Eu tive um caso semelhante ao confirmar dizendo que a fusão automática falhou; corrigir conflitos e, em seguida, cometer o resultado:[rejected] gh-pages -> gh-pages (non-fast-forward)
Chetabahana
4
Gwyn, pode ser útil selecionar uma resposta aceita aqui. O topo eleito um é um pouco menos seguro do que alguns dos mais atualizado soluções, então eu acho que ele iria ajudar a destacar os outros sobre ele :)
Amicable

Respostas:

2222

Como você pullnão teve êxito, então HEAD(não HEAD^) é o último commit "válido" em sua filial:

git reset --hard HEAD

A outra peça que você deseja é deixar que as alterações deles substituam suas alterações.

As versões mais antigas do git permitiam usar a estratégia de mesclagem "deles":

git pull --strategy=theirs remote_branch

Mas isso já foi removido, como explicado nesta mensagem por Junio ​​Hamano (o mantenedor do Git). Conforme observado no link , você faria o seguinte:

git fetch origin
git reset --hard origin
Pat Notz
fonte
49
Em vez de fazer uma redefinição definitiva, você pode trazê-la para um nível mais granular fazendo: 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) Eu nunca mais uso o git pull. Como em uma briga entre meu código mais recente e a origem, a origem deve sempre vencer, eu sempre git fetche git rebase origin. Isso realmente torna minhas fusões e conflitos poucos e distantes entre si.
Kzqai
7
Concordo. Também gosto de buscar primeiro e depois examinar as alterações upstream ( git log ..@{upstream}ou git diff ..@{upstream}). Depois disso, como você, vou refazer o meu trabalho.
Pat Notz
162
Como observado em uma resposta mais recente, a partir da versão 1.6.1, é possível usar '--merge git reset'
Matt Bola
5
Eu usei em git merge -X theirs remote_branchvez de git pull --strategy=theirs remote_branchcomo theirsparece uma opção derecursive
mlt
14
git merge --aborté muito preferível.
Daniel Cassidy
1956

Se sua versão do git for> = 1.6.1, você poderá usar git reset --merge.

Além disso, como o @Michael Johnson menciona, se sua versão do git for> = 1.7.4, você também poderá usá-lo git merge --abort.

Como sempre, verifique se não há alterações não confirmadas antes de iniciar uma mesclagem.

Na página do manual git merge

git merge --aborté equivalente a git reset --mergequando MERGE_HEADestá presente.

MERGE_HEAD está presente quando uma mesclagem está em andamento.

Além disso, em relação às alterações não confirmadas ao iniciar uma mesclagem:

Se você tiver alterações que não deseja confirmar antes de iniciar uma mesclagem, apenas git stashelas antes da mesclagem e git stash popapós concluir a mesclagem ou abortá-la.

Carl
fonte
3
Interessante - mas o manual me assusta. Quando exatamente é apropriado usar? Quando você precisaria especificar o opcional <commit>? #GitMoment: -o
conny
1
Você normalmente usaria isso quando quiser refazer a mesclagem desde o início. Eu nunca tive que especificar a confirmação opcional, então o padrão (sem opção <commit>) está bem.
Carl
44
Eu gostaria que esta resposta tivesse mais votos! Neste ponto, parece ser a solução mais relevante em muitos casos.
Jay Taylor
1
Mesmo com alterações não confirmadas, o git foi capaz de restaurar o estado antes da mesclagem. Agradável!
T3rm1
2
É git merge --abortapenas um sinônimo git reset --merge? O nome certamente faz mais sentido, mas tem a mesma funcionalidade?
Tikhon Jelvis
518
git merge --abort

Interrompa o processo atual de resolução de conflitos e tente reconstruir o estado de pré-mesclagem.

Se houver alterações não confirmadas na árvore de trabalho quando a mesclagem foi iniciada, git merge --abortem alguns casos, não será possível reconstruir essas alterações. Portanto, é recomendável sempre confirmar ou ocultar suas alterações antes de executar o git merge.

git merge --aborté equivalente a git reset --mergequando MERGE_HEADestá presente.

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

ignis
fonte
16
Está disponível desde o git v1.7.4. É um apelido para git reset --merge.
Michael Johnson
162

É tão simples.

git merge --abort

O próprio Git mostra a solução quando você está nesse tipo de problema e executa o comando git status.

git status

Espero que isso ajude as pessoas.

Jagruttam Panchal
fonte
97

Eu acho que git resetvocê precisa.

Cuidado, isso git revertsignifica algo muito diferente de, digamos, svn revert- no Subversion, a reversão descartará suas alterações (não confirmadas), retornando o arquivo para a versão atual do repositório, enquanto git revert"desfaz" um commit.

git resetdeve fazer o equivalente a svn revert, ou seja, descartar as alterações indesejadas.

David Precious
fonte
76

Nesse caso de uso específico, você realmente não deseja interromper a mesclagem, apenas resolva o conflito de uma maneira específica.

Também não há necessidade de redefinir e executar uma mesclagem com uma estratégia diferente. Os conflitos foram destacados corretamente pelo git e o requisito de aceitar as alterações dos outros lados é apenas para este arquivo.

Para um arquivo não mesclado em um conflito, o git disponibiliza as versões base, local e remota comuns do arquivo no índice. (É daí que eles são lidos para serem usados ​​em uma ferramenta de diferenças de três vias git mergetool.) Você pode usá git show-los para visualizá-los.

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

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

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

A maneira mais simples de resolver o conflito para usar a versão remota literalmente é:

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

Ou, com git> = 1.6.1:

git checkout --theirs _widget.html.erb
CB Bailey
fonte
5
obrigado pela dica. isso não parece uma interface de usuário pobre do git?
Peter
@ Peter: Eu não estou convencido. O resultado desejado é possível com alguns comandos básicos com opções simples. Que melhorias você sugeriria?
CB Bailey
10
Eu acho que o git 1.6.1comando faz muito sentido e é bom. Era exatamente o que eu queria. Eu acho que a solução anterior à 1.6.1 é deselegante e requer conhecimento sobre outras partes do git que devem ser separadas do processo de resolução de mesclagem. Mas a nova versão é ótima!
Peter Peter
67

Para um cenário como, eu fiz git fetche git pullpercebi que o ramo upstream não era ramo principal, o que resultou em conflitos indesejados.

git reset --merge 

Isso foi revertido sem redefinir minhas alterações locais.

naamadheya
fonte
45

Os comentários sugerem que git reset --mergeé um alias para git merge --abort. Vale a pena notar que isso git merge --aborté apenas equivalente ao git reset --mergedado que a MERGE_HEADestá presente. Isso pode ser lido na ajuda do git para o comando mesclar.

git merge --abort é equivalente a git reset --merge quando MERGE_HEAD está presente.

Após uma mesclagem com falha, quando não há MERGE_HEAD, a mesclagem com falha pode ser desfeita git reset --merge, mas não necessariamente com git merge --abort. Eles não são apenas sintaxe antiga e nova para a mesma coisa .

Pessoalmente, acho git reset --mergemuito mais poderoso para cenários semelhantes ao descrito e falho mesclas em geral.

Martin G
fonte
2
o que aqui realmente significa "fusão falhada"? Mesclar com conflitos ou algo mais? Ou, para reformulá-lo: quando MERGE_HEAD não está presente? Minha pergunta de acompanhamento está aí para entender melhor o uso do "git reset --merge".
Ewoks
O @Ewoks git stash applycausou um conflito de mesclagem para mim, mas git merge --abortnão ajudou git reset --merge.
Nitzel 06/12/19
27

Se você acabar com um conflito de mesclagem e não tiver nada a confirmar, mas ainda assim um erro de mesclagem estiver sendo exibido. Depois de aplicar todos os comandos mencionados abaixo,

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

Por favor remova

.git \ index.lock

Arquive [recortar e colar para outro local em caso de recuperação] e, em seguida, insira qualquer um dos comandos abaixo, dependendo da versão desejada.

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

Espero que ajude!!!

Nirav Mehta
fonte
19

Uma alternativa, que preserva o estado da cópia de trabalho é:

git stash
git merge --abort
git stash pop

Eu geralmente desaconselho isso, porque é efetivamente como mesclar no Subversion, pois descarta os relacionamentos de ramificação no commit a seguir.

Alain O'Dea
fonte
Achei essa abordagem útil quando acidentalmente fui mesclada a um ramo git-svn, que não lida bem com isso. Mesclagens de squash ou escolhas de cereja são melhores quando se trabalha com ramos de rastreamento git-svn. De fato, minha solução transforma uma mesclagem em uma squash após o fato.
Alain O'Dea
Melhor resposta para a pergunta
Fouad Boukredine 29/02
18

Desde que o Git 1.6.1.3 git checkoutconseguiu efetuar o checkout de ambos os lados de uma mesclagem:

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

Eu encontrei o seguinte funcionou para mim (reverter um único arquivo para pré-mesclar o estado):

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

Sourcetree

Como você não compromete sua mesclagem, basta clicar duas vezes em outro ramo (o que significa fazer checkout) e, quando o sourcetree perguntar sobre como descartar todas as alterações, concorde :)

Kamil Kiełczewski
fonte