Como mesclar conflitos do Git no Emacs


84

Minha recente fusão do Git resultou em um grande número de conflitos. Minha abordagem atual é procurar a próxima ocorrência de '<<<' e executar a mesclagem por edição de texto padrão.

Pergunta : existe uma maneira de o Emacs suportar a fusão usando as informações disponíveis no Git sobre minha versão, sua versão e a versão base do arquivo?


Editar: Esta questão tem um escopo diferente do que esta questão relacionada , uma vez que não se limita a invocar ediff.


7
Se você usar o Magit, poderá carregar o buffer de status e pressionar os earquivos mostrados como conflitantes. O Magit seria iniciado ediffpara fazer a mesclagem e solicitaria depois que você confirmasse suas alterações, para poder preparar o arquivo mesclado.
Wvxvw 09/09/2015

@Beginner: outras 3 pessoas acharam que era uma cópia, e eu fui a última votação. Motivo: o outro tópico citado fornece as mesmas respostas ( smergee vc-resolve-conflict, assim como uma ediff) e existe há mais tempo. Concordo que o primeiro tópico poderia usar um título melhor, no entanto.
Dan

@ Dan Eu discordo: é uma pergunta diferente e que a resposta é semelhante não muda isso.
Iniciante

1
@IqbalAnsari: Acho que o outro tópico precisa de um título melhor para que as pessoas possam encontrá-lo mais facilmente. Na verdade, acho que o título do tópico para iniciantes seria ótimo para ele. No entanto, vamos esperar um pouco para ver se as pessoas querem reabrir esse segmento. Caso contrário, eu seria a favor de renomear o primeiro segmento com o título do Iniciante.
Dan

1
E pelo que vale a pena, acho que é uma boa pergunta com boas respostas. Apenas acho que também é uma duplicata - mas outras pessoas podem não compartilhar essa opinião (sobre a duplicação).
Dan

Respostas:


86

Você pode tentar smerge-modeapenas abrir o arquivo em conflito e fazer M-xsmerge-modeRET. Irá destacar todas as regiões em conflito. Ele também adiciona combinações de teclas para resolver facilmente os conflitos, consulte sua documentação C-hfsmerge-modeRETpara conhecê-los.

Prefixo padrão

Eu acho o prefixo padrão para smerge-mode C-c^complicado, então mudei para C-cv

(setq smerge-command-prefix "\C-cv")

Keybindings importantes

Para mim, as ligações mais importantes são:

smerge-nextobrigado a smerge-command-prefixnpassar para o próximo conflito.

smerge-previousobrigado a smerge-command-prefixppassar para o conflito anterior.

smerge-keep-currentobrigado a smerge-command-prefixRETmanter a versão em que o cursor está.

smerge-keep-mineobrigado a smerge-command-prefixmmanter suas alterações.

smerge-keep-otherobrigado a smerge-command-prefixomanter outras alterações.

smerge-ediffobrigado a smerge-command-prefixEiniciar uma sessão ediff para mesclar os conflitos. É o mesmo que vc-resolve-conflicts(obrigado @phils e @Malabarba por apontar isso).

Ativando o modo de junção automaticamente

ATUALIZAÇÃO: O seguinte é relevante apenas nas versões do Emacs anteriores 25.1; o seguinte pode causar problemas em versões posteriores, consulte https://github.com/magit/magit/issues/3897

Além disso, você pode estar interessado em ativar automaticamente smerge-modeao visitar um arquivo / buffer com marcadores de conflito, pode usar algo como o seguinte para conseguir isso

(defun my-enable-smerge-maybe ()
  (when (and buffer-file-name (vc-backend buffer-file-name))
    (save-excursion
      (goto-char (point-min))
      (when (re-search-forward "^<<<<<<< " nil t)
        (smerge-mode +1)))))

(add-hook 'buffer-list-update-hook #'my-enable-smerge-maybe)

Observe que estou usando buffer-list-update-hooke não, find-file-hookpois na maioria das vezes eu recebo conflitos em um buffer que já está aberto no emacs, caso em que find-file-hooknão ajuda em nada.

Verifique também outros métodos mencionados nesta resposta


1
(1) Não esqueça smerge-ediff. (2) Em qual versão do Emacs você está? No ramo principal do emacs atual, o smerge é ativado automaticamente. (3) Por que você está usando em buffer-list-update-hookvez de find-file-hook?
Malabarba 9/09/15

Para esclarecimentos adicionais, observe que smerge-ediffe vc-resolve-conflictssão a mesma coisa.
9788 phillips #

@ Malabarba 1) Eu mencionei que smerge-modeas combinações de teclas estão documentadas em sua documentação. Talvez eu possa citar o manual aqui para ser completo. Obrigado pelo feedback. 2) Estou na v24.5, embora às vezes tente o master branch, não me lembro de o smerge ter sido ativado automaticamente (é uma alteração recente?). 3) Isso é porque na maioria das vezes eu fico conflitos em buffers já abertos, caso em que eu precisaria para transformar explicitamentesmerge-mode
Iqbal Ansari

@IqbalAnsari existe algum motivo para não ter smerge-modeativado o tempo todo? Talvez não faça muito até ser invocado.
precisa saber é o seguinte

@PythonNut Boa pergunta, infelizmente, eu não tenho uma resposta desde que eu nunca tentou mantê-lo ativado o tempo todo, vale a pena experimentar embora
Iqbal Ansari

32

Edit: como essa resposta foi mais positiva do que eu esperava, eu a expandi um pouco.

Para complementar a resposta de @IqbalAnsari, você também pode usar vc-resolve-conflicts(como mencionado por outros, é um apelido para smerge-ediff). Isso iniciará a ediffinterface. À esquerda, estará o primeiro pai de mesclagem e o segundo pai de mesclagem, à direita. Eles são rotulados na modelagem com MINEe OTHERrespectivamente. O buffer mesclado é mostrado abaixo (veja a captura de tela).

Uma captura de tela da interface <code> ediff </code>

Combinações de teclas

  • Navegue pelos conflitos com ne p.
  • Aceite versões com aou b.
  • Olhe para o ancestral com /!
  • Saia da sessão ediff com q.

Você também pode navegar para o buffer mesclado other-windowe editar manualmente, caso a solução de um conflito seja mais complicada do que aceitar uma versão. Quando terminar, você pode salvar o buffer e sair do Emacs como de costume. Para obter mais ajuda, basta usar ?durante a ediffsessão, há um monte de comandos muito úteis lá. Ainda não sei o que metade deles faz!


2
Este é o melhor método IMO. Estou vinculado a isso C-x v <, embora, na prática, seja mais provável que eu o invoque com o Magit (conforme comentário de wvxvw).
phils

1
Como o ano de 2000 vc-resolve-conflicté um apelido para smerge-ediff, que, como o nome sugere, inicia uma sessão do Ediff, não uma sessão do Emerge. A propósito, o cabeçalho da biblioteca ediff.elreconhece emerge.ela influência de s e continua dizendo "A versão atual do Ediff substitui o Emerge. Ele fornece uma interface de usuário superior e possui vários recursos importantes não encontrados no Emerge. Em particular, ele pode fazer correções e Operações de comparação, mesclagem e diretório de arquivos de duas e três vias ".
tarsius 11/09/15

6
Observe também que magit-ediff-resolve( Emou eem um arquivo com conflitos) usa smerge-ediffinternamente. No entanto, substitui o ediff-quit-hookpara fornecer uma experiência de finalização de sessão um pouco melhor. Em vez de dizer que você pode salvar "o buffer" (existem vários buffers), ele pergunta se você deseja salvar o buffer (enquanto mostra seu nome).
tarsius 11/09/15

Existe uma maneira de mostrar 4 janelas (nossa, mãe, mãe, área de trabalho) como vimdiff?
precisa saber é o seguinte

9

Se você usar o Spacemacs, recomendo ativar o "modo transitório de imersão", que exibe um menu de hidra com todos os comandos possíveis de imersão.

Para fazer isso, basta chamar Mx spacemacs/smerge-transient-state/body, que é por padrão atribuído SPC-g-r.

Aqui está uma captura de tela:

insira a descrição da imagem aqui

A edição do seu arquivo deve ser intuitiva:

  1. Pressione npara ir para o próximo pedaço.
  2. Escolha uma ação de mesclagem .
  3. Repita até terminar.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.