Quando você usaria as diferentes estratégias de mesclagem do git?

430

Na página de manual do git-merge, há várias estratégias de mesclagem que você pode usar.

  • resolver - Isso pode resolver apenas duas cabeças (ou seja, a ramificação atual e outra ramificada da qual você retirou) usando o algoritmo de mesclagem de 3 vias. Ele tenta detectar cuidadosamente ambiguidades cruzadas de mesclagem e é considerado geralmente seguro e rápido.

  • recursivo - Isso pode resolver apenas duas cabeças usando o algoritmo de mesclagem de 3 vias. Quando há mais de um ancestral comum que pode ser usado para mesclagem de 3 vias, ele cria uma árvore mesclada dos ancestrais comuns e a usa como a árvore de referência para a mesclagem de 3 vias. Foi relatado que isso resulta em menos conflitos de mesclagem sem causar fusões incorretas por testes feitos em confirmações de mesclagem reais retiradas do histórico de desenvolvimento do kernel Linux 2.6. Além disso, isso pode detectar e manipular fusões envolvendo renomeações. Essa é a estratégia de mesclagem padrão ao extrair ou mesclar uma ramificação.

  • polvo - Isso resolve mais de dois casos, mas se recusa a fazer mesclagens complexas que precisam de resolução manual. Destina-se principalmente a ser usado para agrupar cabeças de ramificação de tópicos. Essa é a estratégia de mesclagem padrão ao extrair ou mesclar mais de uma ramificação.

  • our - Isso resolve qualquer número de cabeças, mas o resultado da mesclagem é sempre a cabeça de ramificação atual. Ele deve ser usado para substituir o histórico antigo de desenvolvimento de ramificações laterais.

  • subárvore - Esta é uma estratégia recursiva modificada. Ao mesclar as árvores A e B, se B corresponder a uma subárvore de A, B será ajustado primeiro para corresponder à estrutura de árvore de A, em vez de ler as árvores no mesmo nível. Esse ajuste também é feito na árvore ancestral comum.

Quando devo especificar algo diferente do padrão? Quais são os melhores cenários?

Otto
fonte

Respostas:

305

Não estou familiarizado com a resolução, mas usei os outros:

Recursivo

Recursiva é o padrão para mesclagens sem avanço rápido. Estamos todos familiarizados com isso.

Polvo

Eu usei polvo quando tive várias árvores que precisavam ser mescladas. Você vê isso em projetos maiores, onde muitas filiais tiveram desenvolvimento independente e está tudo pronto para se unir em um único cabeçalho.

Um ramo de polvo mescla várias cabeças em um commit, desde que seja possível.

Para ilustração, imagine que você tenha um projeto que tenha um mestre e, em seguida, três ramos para mesclar (chame-os de a, bec).

Uma série de mesclagens recursivas seria assim (observe que a primeira mesclagem foi um avanço rápido, pois não forcei a recursão):

série de mesclagens recursivas

No entanto, uma única mesclagem de polvo ficaria assim:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

fusão de polvo

Nosso

Nosso == Quero puxar outra cabeça, mas jogar fora todas as mudanças que a cabeça introduz.

Isso mantém o histórico de uma ramificação sem nenhum dos efeitos da ramificação.

(Leia: nem sequer são analisadas as alterações entre esses ramos. Os ramos são apenas mesclados e nada é feito nos arquivos. Se você deseja mesclar no outro ramo e sempre que houver a pergunta "nossa versão do arquivo ou sua versão "você pode usar git merge -X ours)

Subárvore

A subárvore é útil quando você deseja mesclar outro projeto em um subdiretório do seu projeto atual. Útil quando você tem uma biblioteca que não deseja incluir como submódulo.

Dustin
fonte
1
Portanto, a única vantagem real do Ocotopus é reduzir o número de confirmações de mesclagem na árvore?
Otto
60
Você não precisa especificar a estratégia de mesclagem de polvo : ela será usada automaticamente se você mesclar mais de duas ramificações ( git merge A B ...).
Jakub Narębski 4/12/2009
Desculpe por sair do tópico, mas de que ferramenta você criou essas capturas de tela? Parece realmente um grande visualização / muito da história ramo ...
Bernd Haug
4
Gitg para aqueles em ambiente Linux.
precisa saber é o seguinte
2
Essa dica -X oursé incrível, só me salvou uma hora de trabalho.
Michael
49

Na verdade, as únicas duas estratégias que você gostaria de escolher são as nossas, se você deseja abandonar as alterações trazidas por ramificação, mas mantém a ramificação no histórico e a subárvore, se estiver mesclando um projeto independente no subdiretório do superprojeto (como 'git-gui' em ' repositório git ').

a mesclagem de polvo é usada automaticamente ao mesclar mais de duas ramificações. A resolução está aqui principalmente por razões históricas e para quando você é atingido por casos de canto de estratégia de mesclagem recursiva .

Jakub Narębski
fonte
Eu tive que escolher 'resolver' em vez do padrão 'recursivo' para uma mesclagem de duas cabeças que apresentava erros fatais da árvore de gravação e git. A estratégia de 'resolução' se fundiu de maneira limpa. Pode ter a ver com a movimentação de muitos arquivos na ramificação que está sendo mesclada.
Thaddeusmt
@thaddeusmt: Interessante. Você poderia, se possível, postar um relatório de bug sobre esta falha da estratégia de mesclagem "recursiva" na lista de discussão git? Desde já, obrigado.
Jakub Narębski
@ JakubNarębski Não tenho certeza de como reunir informações suficientes para registrar um relatório de erro significativo, sou um n00b com o Git, desculpe. Como mencionei na minha resposta aqui ( stackoverflow.com/a/10636464/164439 ), meu palpite é que isso tinha a ver comigo duplicando as alterações nos dois ramos, e "resolver" faz um trabalho melhor de ignorar as alterações duplicadas.
Thaddeusmt
@ JakubNarębski agora você também pode escolher deles , o que está de acordo com o manual "o oposto do nosso . Deles não é nem escolhido automaticamente para você pode você pode atualizar um pouco o seu anwser, acrescentando o. Deles opção
SebNag
3
@ SebTu: não há theirsestratégia de mesclagem (isto é --strategy=theirs), mas há theirsopção para a recursiveestratégia de mesclagem padrão (ou seja --strategy=recursive --strategy-option=theirs, apenas -Xtheirs).
Jakub Narębski
23

Estratégia de mesclagem "resolver" vs "recursiva"

Recursiva é a atual estratégia de duas cabeças padrão, mas depois de algumas pesquisas, finalmente encontrei algumas informações sobre a estratégia de mesclagem "resolver".

Retirado do livro O'Reilly, Version Control with Git ( Amazon ) (parafraseado):

Originalmente, "resolver" era a estratégia padrão para mesclagens do Git.

Em situações de mesclagem cruzada, em que há mais de uma base de mesclagem possível, a estratégia de resolução funciona da seguinte maneira: escolha uma das possíveis bases de mesclagem e espere o melhor. Na verdade, isso não é tão ruim quanto parece. Geralmente, os usuários trabalham em diferentes partes do código. Nesse caso, o Git detecta que está realizando algumas alterações já existentes e ignora as alterações duplicadas, evitando o conflito. Ou, se essas são pequenas alterações que causam conflitos, pelo menos o conflito deve ser fácil para o desenvolvedor lidar.

Eu mesclei árvores com êxito usando "resolve" que falhou com a estratégia recursiva padrão. Eu estava recebendo fatal: git write-tree failed to write a treeerros e, graças a esta postagem no blog ( espelho ), tentei "-s resolve", que funcionou. Ainda não sei exatamente por que ... mas acho que foi porque eu tive alterações duplicadas nas duas árvores e resolvi "ignorá-las" adequadamente.

thaddeusmt
fonte
Estou usando a fusão de três vias (p4merge) e tive conflitos gravados no arquivo .BASE quando a fusão recursiva falhou. Voltar para a estratégia de resolução ajudou nesse caso.
Mrzl
-2

Como as respostas acima não estão mostrando todos os detalhes da estratégia. Por exemplo, alguma resposta está faltando os detalhes sobre a importação resolveopção eo recursiveque tem muitas opções de sub como ours, theirs, patience, renormalize, etc.

Portanto, eu recomendaria visitar a gitdocumentação oficial que explica todos os recursos possíveis:

https://git-scm.com/docs/merge-strategies

Rene B.
fonte