Git Cherry-pick vs Merge Workflow

302

Supondo que eu sou o mantenedor de um repositório e desejo receber alterações de um colaborador, existem alguns fluxos de trabalho possíveis:

  1. I cherry-pickcada commit do controle remoto (em ordem). Nesse caso, o git registra a confirmação como não relacionada à ramificação remota.
  2. I mergedo ramo, puxando em todas as alterações, e adicionando uma nova "conflito" commit (se necessário).
  3. I mergecada commit do branch remoto individualmente (de novo em ordem), permitindo que os conflitos devem ser registadas para cada commit, em vez de agrupados todos juntos como um só.
  4. Para completar, você pode fazer um rebase(igual à cherry-pickopção?), No entanto, meu entendimento é que isso pode causar confusão para o colaborador. Talvez isso elimine a opção 1.

Nos dois casos 2 e 3, o git registra o histórico de ramificações dos commit, diferente de 1.

Quais são os prós e contras entre o uso de um cherry-pickou dos mergemétodos descritos? Meu entendimento é que o método 2 é a norma, mas acho que resolver uma grande consolidação com uma única mesclagem de "conflitos" não é a solução mais limpa.

cmcginty
fonte

Respostas:

297

Ambos rebase(e cherry-pick) e mergetêm suas vantagens e desvantagens. Eu defendo mergeaqui, mas vale a pena entender os dois. (Procure aqui uma resposta alternativa bem fundamentada, enumerando os casos em que rebaseé preferível.)

mergeé preferido em vez de cherry-picke rebasepor algumas razões.

  1. Robustez . O identificador SHA1 de uma confirmação identifica-a não apenas em si mesma, mas também em relação a todas as outras confirmações que a precedem. Isso oferece uma garantia de que o estado do repositório em um determinado SHA1 é idêntico em todos os clones. Não há (em teoria) chance de alguém ter feito o que parece ser a mesma mudança, mas na verdade está corrompendo ou sequestrando seu repositório. Você pode escolher as mudanças individualmente e elas provavelmente são as mesmas, mas você não tem garantia. (Como uma questão secundária secundária, as novas confirmações escolhidas pela cereja ocuparão espaço extra se alguém escolher novamente a mesma confirmação, pois ambas estarão presentes na história, mesmo que suas cópias de trabalho acabem sendo idênticas.)
  2. Facilidade de uso . As pessoas tendem a entender o mergefluxo de trabalho com bastante facilidade. rebasetende a ser considerado mais avançado. É melhor entender os dois, mas as pessoas que não querem ser especialistas em controle de versão (que na minha experiência incluiu muitos colegas que são muito bons no que fazem, mas não querem gastar o tempo extra) são mais fáceis. tempo apenas se fundindo.

Mesmo com um fluxo de trabalho pesado de mesclagem rebasee cherry-pickainda são úteis para casos específicos:

  1. Uma desvantagem mergeé a história desordenada. rebaseimpede que uma longa série de confirmações seja espalhada no seu histórico, como seria se você mesclasse periodicamente as alterações de outras pessoas. Na verdade, esse é o seu principal objetivo, como eu o uso. O que você deseja ter muito cuidado é nunca rebasecodificar que você compartilhou com outros repositórios. Depois que um commit é pusheditado, alguém pode ter cometido o mesmo, e o rebasing causará, na melhor das hipóteses, o tipo de duplicação discutido acima. Na pior das hipóteses, você pode acabar com um repositório muito confuso e com erros sutis que levarão muito tempo para serem descobertos.
  2. cherry-pick é útil para amostrar um pequeno subconjunto de alterações de um ramo de tópico que você basicamente decidiu descartar, mas percebeu que existem algumas partes úteis.

Quanto a preferir mesclar muitas alterações a uma: é muito mais simples. Pode ser muito entediante fazer mesclagens de conjuntos de alterações individuais quando você começar a ter muitos deles. A resolução de mesclagem no git (e no Mercurial e no Bazaar) é muito, muito boa. Você não terá grandes problemas ao mesclar ramos longos na maioria das vezes. Geralmente, mesclo tudo de uma só vez e, somente se tiver um grande número de conflitos, faço backup e re-executo a mesclagem aos poucos. Mesmo assim, faço-o em grandes pedaços. Como um exemplo muito real, tive um colega que tinha três meses de alterações a serem mescladas e obtive cerca de 9000 conflitos em 250000 linhas de código-base. O que fizemos para correção é fazer vale o merge um mês de cada vez: conflitos não acumular linearmente, e fazê-lo em pedaços resultados em muitomenos de 9000 conflitos. Ainda era muito trabalho, mas não tanto quanto tentar fazer um commit de cada vez.

quark
fonte
1
Na verdade, em teoria, há uma chance de Mallory corromper seu repositório criando commits com o mesmo SHA1, mas com conteúdo diferente, provavelmente isso nunca acontecerá na prática. :)
Bombe
1
Ha :) Eu quis dizer "em teoria, as probabilidades são tão baixas que você pode confiar que isso não aconteça", mas você está certo que diz que ele está de cabeça para baixo.
quark
O que você acha sobre "mesclar --squash"?
cmcginty 29/09/09
@Bombe Se Mallory quiser ter sucesso, ela precisará criar especificamente o commit original e o segundo commit com o mesmo SHA1. Então, outra pergunta poderia ser: quais são as chances de dois commits (um tanto) falsos aparecerem e você não perceber? ;)
João Portela
64
9000 conflitos? Largaria o emprego e me tornaria apicultor.
Sebastian Patten
95

Na minha opinião, a escolha da cereja deve ser reservada para situações raras em que é necessária, por exemplo, se você corrigiu diretamente o ramo 'mestre' (tronco, ramo de desenvolvimento principal) e percebeu que deveria ser aplicado também ao 'maint ' Você deve basear o fluxo de trabalho na mesclagem ou no rebase (ou "git pull --rebase").

Lembre-se de que a confirmação escolhida ou rebaseada é diferente do ponto de vista do Git (possui um identificador SHA-1 diferente) do original, portanto, é diferente da confirmação no repositório remoto. (O rebase geralmente pode lidar com isso, pois verifica o ID do patch, ou seja, as alterações, não o ID de confirmação).

Também no git, você pode mesclar vários ramos de uma só vez: a chamada fusão de polvos . Observe que a fusão do polvo precisa ter sucesso sem conflitos. No entanto, pode ser útil.

HTH.

Jakub Narębski
fonte
19
+1 para o ponto em que a rebase / seleção de cereja realmente "copia" as confirmações e, portanto, perde a ligação à confirmação original.
studgeek
1
Usamos cherry-pick dessa maneira, exclusivamente para mover confirmações para correções de bugs (talvez recursos MUITO PEQUENOS) em um ramo de lançamento existente para preparar um patch. Os recursos que abrangem várias confirmações geralmente garantem a entrada em uma ramificação de release baseada no mestre.
foxxtrot
3
@foxxtrot: Outra solução é criar uma ramificação separada para uma correção de bug, com base na confirmação mais antiga que exibe esse bug, e mesclá-la em 'maint' e em 'master' ... embora, nesse caso, você precise saber que a correção de bug aplica-se a ambos os ramos.
Jakub Narębski
4
@Jakub Dois comandos indispensáveis ​​para criar e mesclar uma ramificação de bugfix: git blameencontrar a confirmação que introduziu o bug e git branch --containsdeterminar onde mesclar a ramificação. Descrito com mais detalhes neste post
gcbenison
-10

Rebase e Cherry-pick são a única maneira de manter um histórico de consolidação limpo. Evite usar mesclagem e evite criar conflito de mesclagem. Se você estiver usando o gerrit, configure um projeto para Mesclar, se necessário, e um projeto para o modo de seleção de cereja e tente você mesmo.

Nagaraj Magadum
fonte
não está claro como isso responde à pergunta, talvez alguns exemplos traga alguma luz.
Adrian Nasui
1
O fato de sua história parecer correta não implica que seria mais fácil de entender.
Nicolimo86
Mesclar é a maneira usual de ter um histórico limpo. A escolha e a recuperação da cereja são usadas principalmente para situações em que você deve modificar o histórico. O que significa que a fusão deve sempre ser a primeira escolha. Porque rebase mudou o comitê do que é muito perigoso quando você trabalha com controles remotos e várias pessoas.
Radon8472
Esse cara aqui merece uma medalha. Ele sabe que continuará recebendo votos negativos, mas é a resposta certa. Parabéns.
PW Kad
Desculpe, mas não vi esses comentários até agora. Experimente-o no ambiente de teste antes de concluir e faça o que funciona para você! Eu tenho cerca de 600 desenvolvedores contribuindo para várias ramificações de produtos. Não me importo com o que os desenvolvedores fazem no espaço de trabalho local. Quando uma alteração é submetida à integração, ela deve ser capaz de escolher a ramificação do desenvolvimento ou, às vezes, lançar ou ramificar correções de bugs. Para sua informação ... eu uso o Gerrit.
Nagaraj Magadum 21/01