Como resolver conflitos de mesclagem no git

Existe uma boa maneira de explicar como resolver conflitos de mesclagem no git?

4274
02 окт. Spoike set 02 de outubro . 2008-10-02 14:31 '08 at 2:31 pm 2008-10-02 14:31
@ 37 respostas
  • 1
  • 2

Experimente: git mergetool

Ele abre a interface gráfica que percorre cada conflito e você pode escolher como combinar. Às vezes isso requer um pouco de edição manual depois, mas geralmente é suficiente por si só. Isso é muito melhor do que fazer tudo manualmente.

De acordo com o comentário do @JoshGlover:

O comando não abre necessariamente a GUI, se você não instalá-lo. Correndo git mergetool para mim levou ao uso de vimdiff . Você pode instalar uma das seguintes ferramentas para usá-lo: meld , opendiff , kdiff3 , tkdiff , xxdiff , tortoisemerge , gvimdiff , diffuse , ecmerge , p4merge , araxis , vimdiff , emerge .

Abaixo está um exemplo do procedimento para usar o vimdiff para resolver conflitos de mesclagem. Por este link

Etapa 1 : Execute os seguintes comandos no seu terminal

 git config merge.tool vimdiff git config merge.conflictstyle diff3 git config mergetool.prompt false 

Isso definirá o vimdiff como a ferramenta de mesclagem padrão.

Etapa 2 : execute o seguinte comando no terminal

 git mergetool 

Etapa 3 : Você verá uma exibição do vimdiff no seguinte formato.

  +----------------------+ | | | | |LOCAL |BASE |REMOTE | | | | | +----------------------+ | MERGED | | | +----------------------+ 

Esses 4 tipos

LOCAL é o arquivo da ramificação atual.

BASE - um ancestral comum, como o arquivo parecia antes de ambas as mudanças

REMOTE - um arquivo que você mescla no seu branch

INCORPORADO - o resultado da fusão, é isso que é armazenado no repo

Você pode navegar entre essas visualizações usando ctrl+w Você pode ir diretamente para a visualização MERGED usando ctrl+w j .

Mais informações sobre a navegação do vimdiff aqui e aqui.

Etapa 4 Você pode editar o MERGED da seguinte maneira.

Se você deseja receber alterações do REMOTE

 :diffg RE 

Se você deseja receber alterações do BASE

 :diffg BA 

Se você quiser receber alterações de LOCAL

 :diffg LO 

Passo 5 Salve, saia, bloqueie e limpe

:wqa salvar e sair vi

git commit -m "message"

git clean Exclua arquivos desnecessários (por exemplo, * .orig) criados pela ferramenta diff.

2535
02 окт. resposta é dada por Peter Burns 02 de outubro. 2008-10-02 20:50 '08 às 8:50 pm 2008-10-02 20:50

Aqui está um precedente provável, acima:

Você vai fazer algumas mudanças, mas infelizmente você não sabe:

 git fetch origin git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Updating a030c3a..ee25213 error: Entry 'filename.c' not uptodate. Cannot merge. 

Então, você atualiza e tenta novamente, mas você tem um conflito:

 git add filename.c git commit -m "made some wild and crazy changes" git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Auto-merging filename.c CONFLICT (content): Merge conflict in filename.c Automatic merge failed; fix conflicts and then commit the result. 

Então você decidiu dar uma olhada nas mudanças:

border=0
 git mergetool 

Ah, eu, oh, meu, o upstream mudou algumas coisas, mas só para usar minhas mudanças ... não ... as mudanças deles ...

 git checkout --ours filename.c git checkout --theirs filename.c git add filename.c git commit -m "using theirs" 

E então nós tentamos a última vez.

 git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Already up-to-date. 

Ta-da!

1625
04 авг. a resposta é dada por CoolAJ86 04 ago. 2010-08-04 20:04 '10 em 8:04 PM 2010-08-04 20:04

Acho que as ferramentas de mesclagem raramente me ajudam a entender o conflito ou a resolução. Eu costumo olhar com mais sucesso em marcadores de conflito em um editor de texto e usando o git log como um complemento.

Aqui estão algumas dicas:

Conselho um

O melhor que eu encontrei é usar o estilo diff3 do conflito de mesclagem:

git config merge.conflictstyle diff3

Cria marcadores de conflito como este:

 <<<<<<< Changes made on the branch that is being merged into. In most cases, this is the branch that I have currently checked out (ie HEAD). ||||||| The common ancestor version. ======= Changes made on the branch that is being merged in. This is often a feature/topic branch. >>>>>>> 

A parte do meio é como o ancestral comum parecia. Isso é útil porque você pode compará-lo com as versões superior e inferior para entender melhor o que foi alterado em cada ramificação, dando a você uma ideia melhor de qual é a finalidade de cada alteração.

Se o conflito consiste em apenas algumas linhas, isso, via de regra, torna o conflito muito óbvio. (Saber como corrigir um conflito é muito diferente: você precisa saber em que outras pessoas estão trabalhando. Se estiver confuso, é melhor ligar para essa pessoa em seu quarto para que ela possa ver o que você está procurando.)

Se o conflito for mais longo, recorte e cole cada uma das três seções em três arquivos separados, como "meu", "comum" e "eles".

Então eu posso executar os seguintes comandos para ver duas situações que causaram o conflito:

 diff common mine diff common theirs 

Isso não é o mesmo que usar a ferramenta de mesclagem, pois a ferramenta de mesclagem incluirá todos os blocos de diferenças não conflitantes. Eu acho isso perturbador.

Dica dois

Alguém já mencionou isso, mas compreender a intenção por trás de cada palavra diff é geralmente útil para entender de onde o conflito se originou e como lidar com ele.

 git log --merge -p <name of file> 

Isso mostra todos os commits que dizem respeito a esse arquivo entre um ancestral comum e dois cabeçalhos que você mescla. (Assim, ele não inclui os commits que já existem em ambos os branches antes da fusão.) Isso ajuda a ignorar diferenças que claramente não são um fator em seu conflito atual.

Dica três

Verifique suas alterações com ferramentas automatizadas.

Se você tiver testes automatizados, execute-os. Se você tiver um fio , execute-o. Se for um projeto de construção, ele deve ser construído antes de ser concluído, etc. Em todos os casos, você precisa fazer um pequeno teste para garantir que suas alterações não sejam interrompidas. (Até mesmo mesclar sem conflitos pode quebrar o código de trabalho.)

Dica quatro

Planeje com antecedência; comunicar com os colegas.

O planejamento antecipado e a percepção de que outras pessoas estão trabalhando podem ajudar a evitar conflitos de fusão e / ou ajudar a resolvê-los antes, enquanto os detalhes ainda são relevantes.

Por exemplo, se você sabe que você e outra pessoa estão trabalhando em refatorações diferentes que afetarão o mesmo conjunto de arquivos, você deve conversar com antecedência e entender melhor os tipos de alterações que cada um está fazendo. Você pode economizar muito tempo e esforço se executar as mudanças planejadas, por sua vez, e não em paralelo.

Para grandes refatorações que cruzam um grande pedaço de código, você deve pensar seriamente em trabalhar sequencialmente: todos param de trabalhar nessa área de código e uma pessoa executa uma refatoração completa.

Se você não puder trabalhar consistentemente (possivelmente devido à pressão temporária), falar sobre conflitos de fusão esperados ajudará você a resolver os problemas mais cedo, enquanto os detalhes ainda estão atualizados. Por exemplo, se um funcionário fizer uma série destrutiva de confirmações em uma semana, convém mesclar / reempacotar esse ramo uma ou duas vezes por dia nesta semana. Dessa forma, se você encontrar conflitos de mesclagem / redirecionamento, poderá solucioná-los mais rapidamente do que se esperar algumas semanas para mesclar tudo em uma só peça.

Dica cinco

Se você não tiver certeza sobre a fusão, não a force.

A mesclagem pode ser esmagadora, especialmente quando há muitos arquivos conflitantes, e os marcadores de conflito abrangem centenas de linhas. Muitas vezes, quando avaliamos projetos de software, não incluímos tempo suficiente para sobretaxas, como o processamento de uma fusão louca, então parece uma resistência real gastar várias horas analisando cada conflito.

No longo prazo, o planejamento antecipado e a percepção de que os outros estão trabalhando são as melhores ferramentas para prever conflitos de fusão e preparar a solução certa em menos tempo.

696
29 сент. A resposta é dada por Mark E. Haase 29 de setembro. 2011-09-29 00:08 '11 às 0:08 2011-09-29 00:08
  • Determine quais arquivos estão em conflito (o Git deve informar isso).

  • Abra cada arquivo e aprenda as diferenças; Git demarca eles. Espero que seja óbvio qual versão de cada bloco manter. Talvez seja necessário discutir isso com outros desenvolvedores que concluíram o código.

  • Depois de ter resolvido o conflito no arquivo git add the_file .

  • Assim que você resolver todos os conflitos, execute git rebase --continue ou qualquer comando que Git tenha dito quando terminar.

326
02 окт. a resposta é dada davetron5000 02 oct. 2008-10-02 15:41 '08 at 3:41 pm 2008-10-02 15:41

Verifique as respostas na pergunta Abort Git Cancellation , especialmente Charles Bailey's Answer , que mostra como visualizar várias versões de um arquivo com problema, por exemplo

100
03 окт. Resposta dada por Pat Notz em 03 Out 2008-10-03 18:15 '08 at 6:15 pm 2008-10-03 18:15

A fusão de conflitos ocorre quando são feitas alterações em um arquivo ao mesmo tempo. Veja como resolvê-lo.

git CLI

Aqui estão os passos simples que você precisa seguir quando está em um estado de conflito:

  • Observe a lista de arquivos conflitantes: git status (na seção Unmerged paths ).
  • Resolva os conflitos separadamente para cada arquivo com uma das seguintes abordagens:

    • Use a GUI para resolver conflitos: git mergetool (a maneira mais fácil).

    • Para aceitar uma versão remota / outra, use: git checkout --theirs path/file . Isso rejeitará as alterações locais feitas nesse arquivo.

    • Para aceitar o local / nossa versão, use: git checkout --ours path/file

      No entanto, você deve ter cuidado, porque as alterações excluídas foram eliminadas por algum motivo.

      Relacionado: Qual é o significado exato de "ours" e "them" no git?

    • Edite os arquivos conflitantes manualmente e localize o bloco de código entre <<<<< / >>>>> e selecione a versão acima ou abaixo de ===== . Veja: Como os conflitos são apresentados .

    • Conflitos de caminho e nome de arquivo podem ser resolvidos com git add / git rm .

  • Finalmente, revise os arquivos prontos para consolidação usando: git status .

    Se você ainda tem arquivos em Unmerged paths , e você resolveu o conflito manualmente, então deixe o Git saber que você o resolveu: git add path/file .

  • Se todos os conflitos foram resolvidos com sucesso, copie as mudanças: git commit -a e clique no deletado como de costume.

Consulte também: Resolvendo um conflito de mesclagem da linha de comando no GitHub

DiffMerge

Eu usei com sucesso o DiffMerge , que pode comparar visualmente e mesclar arquivos no Windows, macOS e Linux / Unix.

Ele graficamente exibe alterações entre 3 arquivos e permite a fusão automática (quando é seguro) e controle total sobre a edição do arquivo resultante.

2019

05 авг. a resposta é dada kenorb 05 ago. 2015-08-05 17:29 '15 às 17:29 2015-08-05 17:29

Se você fizer pequenos commits freqüentes, comece visualizando os comentários de commit com git log --merge . Então o git diff mostrará seus conflitos.

Para conflitos que envolvem várias linhas, é mais fácil ver o que está acontecendo na ferramenta de GUI externa. Eu gosto de opendiff - Git também suporta vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, emergir da caixa, e você pode instalar outros: git config merge.tool "your.tool" instalar a ferramenta escolhida e depois git mergetool depois de malsucedido A mesclagem mostrará as diferenças no contexto.

Cada vez que você edita um arquivo para resolver um conflito, o git add filename atualiza o índice, e seu diff não o mostrará mais. Quando todos os conflitos tiverem sido processados ​​e seus arquivos tiverem sido git add , git commit completará a mesclagem.

75
02 окт. a resposta é dada Paul 02 de outubro. 2008-10-02 19:11 '08 at 7:11 pm 2008-10-02 19:11

Veja Como os Conflitos São Apresentados ou no Git, a documentação do git merge , para entender o que são marcadores de conflito de conflitos.

Além disso, a seção Como resolver conflitos explica como resolver conflitos:

Depois de ver o conflito, você pode fazer duas coisas:

  • Decida não se fundir. Os únicos limpadores de que você precisa são um arquivo de índice de reconfiguração para fixar o HEAD para a transformada inversa 2. e para limpar as mudanças da vila de trabalho feitas em 2. e 3; git merge --abort pode ser usado para isso.

  • Resolva conflitos. O Git irá marcar conflitos na árvore de trabalho. Edite os arquivos no formulário e git add os ao índice. Use git commit para selar um acordo.

Você pode trabalhar em conflito com várias ferramentas:

  • Use o mergetool. git mergetool para executar um mergetool gráfico que funcionará através de uma mesclagem.

  • Veja as diferenças. git diff exibe um git diff três lados, destacando as alterações nas versões HEAD e MERGE_HEAD .

  • Veja as diferenças entre cada ramo. git log --merge -p <path> mostrará o diff primeiro para a versão HEAD e depois para a versão MERGE_HEAD .

  • Olhe os originais. git show :1:filename mostra o ancestral comum, git show :2:filename mostra a versão do HEAD , e git show :3:filename mostra a versão do MERGE_HEAD .

Você também pode ler sobre a marca do conflito de mesclagem e como resolvê-los na seção Conflitos de mesclagem do Pro Git Main .

43
14 июля '13 в 21:34 2013-07-14 21:34 a resposta é dada por user456814 14 julho '13 at 21:34 2013-07-14 21:34

Para o Emacs, usuários que desejam resolver conflitos de mesclagem semi-manual:

 git diff --name-status --diff-filter=U 

Exibe todos os arquivos que exigem resolução de conflitos.

Abra cada um desses arquivos um por um ou todos de uma vez:

 emacs $(git diff --name-only --diff-filter=U) 

Ao visitar um buffer que requer edição no Emacs, digite

 ALT+x vc-resolve-conflicts 

Isto irá abrir os três buffers (meus, eles e o buffer de saída). Navegue pressionando "n" (próxima área), "p" (área de previsão). Pressione "a" e "b" para copiar minha ou sua área no buffer de saída, respectivamente. E / ou edite o buffer de saída diretamente.

Quando terminar: pressione "q". O Emacs pergunta se você quer salvar este buffer: sim. Quando o buffer estiver concluído, marque-o como resolvido no lançamento do lançador:

 git add FILENAME 

Ter terminado de trabalhar com todos os tipos de buffers

 git commit 

para concluir a mesclagem.

36
23 февр. a resposta é dada 23 de fevereiro 2013-02-23 02:04 '13 às 2:04 2013-02-23 02:04

Eu quero minha versão ou sua versão completamente, ou quero ver as mudanças individuais e tomar uma decisão para cada uma delas.

Aceito totalmente minha ou sua versão :

Aceite minha versão (local, nossa):

 git checkout --ours -- <filename> git add <filename> # Marks conflict as resolved git commit -m "merged bla bla" # An "empty" commit 

Aceite sua versão (exclua-os):

 git checkout --theirs -- <filename> git add <filename> git commit -m "merged bla bla" 

Se você quiser fazer para todos os arquivos conflitantes, execute:

 git merge --strategy-option ours 

ou

 git merge --strategy-option theirs 

Revise todas as alterações e aceite-as individualmente.

  1. git mergetool
  2. Revise as alterações e aceite qualquer versão para cada uma delas.
  3. git add <filename>
  4. git commit -m "merged bla bla"

Por padrão, o mergetool funciona na linha de comando . Como usar a linha de comando do mergetool deve ser um problema separado.

Você também pode instalar uma ferramenta visual para isso, por exemplo, meld e executar

 git mergetool -t meld 

A versão local (nossa), "básica" ou "unificada" (o resultado atual da mesclagem) e o (s) controle (s) remoto (s) serão abertos. Salve a versão mesclada quando terminar, execute git mergetool -t meld até obter "Não é necessário mesclar arquivos" e vá para a Etapa 3. e 4.

28
29 сент. A resposta é dada por Noidea 29 set . 2016-09-29 16:02 '16 às 16:02 2016-09-29 16:02

Por favor, complete os seguintes passos para corrigir conflitos de mesclagem no git:

  1. Verificar Status do Git : Status do Git

  2. Obter o conjunto de patches: git fetch (verifique o patch correto do seu git commit)

  3. Extrair ramificação local (no meu exemplo, temp1): git checkout -b temp1

  4. Extraia o conteúdo recente do master: git pull --rebase origin master

  5. Execute o mergetool, verifique os conflitos e corrija-os ... e verifique as mudanças na ramificação remota com sua ramificação atual: git mergetool

  6. Verifique o status novamente: git status

  7. Exclua arquivos desnecessários criados localmente com o mergetool, geralmente o mergetool cria um arquivo adicional com a extensão * .orig. Por favor, apague este arquivo, pois é apenas uma duplicata, corrija as alterações localmente e adicione a versão correta dos seus arquivos. git add #your_changed_correct_files

  8. Verifique o status novamente: git status

  9. Confirme as alterações no mesmo identificador (isso evita um novo conjunto separado de correções): git commit --amend

  10. Push to master branch: git push (para o seu repositório Git)

28
16 апр. A resposta é dada Chactory 16 abr. 2015-04-16 10:02 '15 às 10:02 2015-04-16 10:02

Simplificando, se você sabe bem que mudanças em um dos repositórios não são importantes, e você quer permitir todas as mudanças em favor do outro, use:

 git checkout . --ours 

permitir mudanças em favor do seu repositório , ou

 git checkout . --theirs 

permitir alterações em favor de outro repositório ou principal .

Ou você terá que usar a ferramenta de mesclagem de GUI para percorrer os arquivos, digamos, a p4merge mesclagem p4merge , ou escrever qualquer nome que você já tenha definido.

 git mergetool -t p4merge 

e depois de completar o arquivo você terá que salvar e fechar para abrir o próximo.

27
26 янв. Resposta de Mohamed Selim em 26 de janeiro 2016-01-26 20:42 '16 às 8:42 pm 2016-01-26 20:42

Você pode corrigir conflitos de mesclagem de várias maneiras, como outros detalham.

Eu acho que a chave real é saber como as mudanças fluem com repositórios locais e remotos. A chave para isso é entender os ramos de rastreamento. Descobri que penso na ramificação de rastreamento como a “parte ausente no meio” entre mim, meu diretório de arquivos local e real e o remoto, definido como origem.

Eu pessoalmente me acostumei com duas coisas para ajudar a evitar isso.

Em vez de:

 git add . git commit -m"some msg" 

O que tem dois inconvenientes?

a) Todos os arquivos novos / modificados são adicionados e podem conter algumas alterações indesejadas.
b) Você não pode primeiro visualizar a lista de arquivos.

Então, ao invés disso:

 git add file,file2,file3... git commit # Then type the files in the editor and save-quit. 

Desta forma, você está deliberadamente discutindo quais arquivos estão sendo adicionados, e você também pode rolar pela lista e pensar um pouco mais usando o editor para a mensagem. Eu acho que isso também melhora minhas mensagens de commit quando eu uso o editor de tela cheia, ao invés da opção -m .

[Atualização - como o tempo passou, mudei mais para:

 git status # Make sure I know whats going on git add . git commit # Then use the editor 

]