Aqui está o acordo: entrei para uma nova empresa e fui solicitado a terminar o trabalho em uma filial que não é tocada há quase um ano. Enquanto isso, o ramo principal tem crescido a um ritmo constante. Idealmente, eu gostaria de mesclar todas as alterações do ramo mestre no ramo de recursos e continuar o trabalho a partir daí, mas não tenho muita certeza de como abordar isso.
Como executo essa mesclagem com segurança, preservando alterações importantes nos dois lados da ramificação?
version-control
git
gitflow
Vlad Spreys
fonte
fonte
git cherry-pick
aqui?Respostas:
Em essência, como combinar dois trechos de código (possivelmente não compatíveis) é um problema de desenvolvimento , não um problema de controle de versão . O comando Git merge pode ajudar nesse processo, mas depende da forma do problema.
Comparar as duas versões com a base primeiro faz mais sentido. Isso lhe dará uma idéia da melhor estratégia para levar isso adiante. Sua abordagem pode ser diferente com base na natureza e sobreposição das alterações em cada ramo.
Imagine o cenário ideal: você descobriria que a ramificação principal e a ramificação de recursos apenas modificaram partes mutuamente exclusivas do código, para que você pudesse apenas confirmar todas as alterações e estar pronto.
Certamente, isso quase certamente não será o caso, mas a questão é: a que distância estará desse cenário ideal? ou seja, quão entrelaçadas são as mudanças?
Além disso, qual era a maturidade do antigo ramo de recursos? Estava em bom estado de funcionamento ou não (ou desconhecido)? Quanto do recurso foi concluído?
Se o código relevante na ramificação principal mudou muito no ano passado, ou o recurso não está em um estado muito maduro, posso considerar criar um novo fork da versão mais recente e incorporar manualmente o recurso antigo novamente. Isso permitirá que você adote uma abordagem incremental para fazê-lo funcionar.
Se você fizer uma mescla bagunçada de muito código e ele não funcionar, será muito difícil depurar. Se a ramificação principal mudou muito no ano passado, podem ser necessárias alterações importantes no design do recurso para que ele funcione. Não seria apropriado fazer essas alterações via "resolver conflitos", pois isso exigiria fazer todas as alterações de uma só vez e esperar que funcionasse. Esse problema seria agravado pela possibilidade de erros no ramo parcialmente finalizado antigo.
fonte
Na minha experiência limitada com o git, posso dizer que, às vezes, é mais rápido reiniciar o ramo de recursos novamente se o mestre foi longe demais do ponto de desanexação.
Mesclar duas ramificações sem conhecer o histórico por trás do código (já que você acabou de ingressar no projeto) é realmente difícil, e aposto que mesmo um desenvolvedor que acompanhou o projeto desde o início provavelmente cometeria alguns erros na mesclagem.
É claro que isso faz sentido se o ramo do recurso não for enorme, mas você pode simplesmente manter o ramo do recurso antigo aberto, ramificar novamente do mestre e reintroduzir manualmente as alterações que compõem esse recurso. Eu sei que é a abordagem mais manual, mas permite que você tenha controle total em caso de código ausente ou movido.
Emparelhar a programação com um senior nesse caso seria o melhor cenário, ajudando você a conhecer melhor o código.
Pode até ser mais rápido também, se você levar em conta conflitos de mesclagem e tempo de teste!
Eu meio que assumi que pelo menos tentar fazer uma mesclagem é obviamente a melhor coisa a fazer. Se isso falhar ou for muito difícil, tente a escolha da cereja, se isso der errado, siga o caminho manual.
fonte
O git-imerge foi projetado exatamente para esse fim. É uma ferramenta git que fornece um método para mesclagem incremental . Ao mesclar de forma incremental, você só precisa lidar com as colisões entre duas versões, nunca mais. Além disso, um número muito maior de mesclagens pode ser realizado automaticamente, pois os conjuntos de alterações individuais são menores.
fonte
Tentar mesclar a cabeça da linha principal em um ramo obsoleto de um ano pode ser um exercício de frustrações e aprofundar o dente na mesa com a testa.
A linha principal não chegou ao local de uma só vez ao longo dos meses. Também teve desenvolvimento e lançamentos. Tentar atualizar tudo em uma mesclagem monolítica pode ser esmagador.
Em vez disso, comece mesclando a partir do primeiro recurso novamente para a linha principal após a divisão de ramificação antiga. Faça essa mesclagem funcionar. Em seguida, o próximo recurso será mesclado. E assim por diante. Muitos desses recursos são mesclados sem conflito. Ainda é importante garantir que a funcionalidade atual da ramificação obsoleta permaneça compatível com a direção da linha principal.
Você pode ramificar da cabeça do ramo obsoleto para o papel de mesclar em outras alterações. Trata-se de garantir que o commit e o histórico quando alguém olha para trás sejam claros e comuniquem qual é o papel e a política de cada ramo. O ramo obsoleto era um ramo de recurso. O que você está trabalhando é um ramo de acumulação e reconciliação.
Muito disso será mais fácil se o recurso antigo ou as ramificações de lançamento ainda existirem e forem facilmente acessíveis (alguns lugares têm uma política de limpar os nomes das ramificações mais antigas que em alguma data, para que a lista de ramificações não seja excessiva. )
O importante em tudo isso é garantir que você teste e corrija após mesclar com êxito cada parte do histórico da linha principal no lugar. Mesmo que algo possa se fundir sem conflitos, isso significa apenas que o código não entrou em conflito. Se a maneira como o recurso obsoleto foi acessado foi descontinuada ou removida, pode ser necessário corrigir após a mesclagem bem-sucedida.
Como um aparte, isso também funciona para outros sistemas de controle de versão. Ocasionalmente, precisei mesclar um grupo específico de commits svn em um ramo (cherry cherry) para um recurso, corrigir o branch para trabalhar com esse recurso e mesclar o próximo grupo de commits svn em vez de apenas fazer um svn atacado mesclar.
Embora se possa fazer uma escolha de git aqui, e permitir trazer confirmações específicas , isso tem algumas desvantagens que podem complicar o processo. A seleção de cereja não mostrará informações sobre o commit que você selecionou (você pode anexá-lo à mensagem de confirmação). Isso dificulta o rastreamento dos commits na história.
Além disso, significa que você não reproduzirá efetivamente o mestre no ramo obsoleto - estará escolhendo recursos possivelmente incompletos - e esses recursos poderão ser reproduzidos fora de ordem.
A principal razão pela qual você deve mesclar as confirmações históricas para dominar o ramo obsoleto é poder manter o, vamos chamá-lo de "histórico futuro" do ramo obsoleto em um estado em que você possa raciocinar. Você pode ver claramente as mesclagens do histórico na ramificação obsoleta e as correções para reintegrar a funcionalidade. Os recursos estão sendo adicionados na mesma ordem em que deveriam ser dominados. E quando você terminar, e finalmente fazer a mesclagem do chefe do mestre para o ramo obsoleto, você sabe que tudo foi mesclado e não está perdendo nenhum comprometimento.
fonte
Etapa 1. Aprenda sobre o código, analise sua arquitetura e as alterações que foram feitas nos dois ramos desde o último ancestral comum.
Etapa 2. Se o recurso parecer amplamente independente e abordar principalmente áreas diferentes de código, mesclar, corrigir conflitos, testar, corrigir etc. Caso contrário, vá para a Etapa 3
Etapa 3. Analise as áreas de conflito, entenda o impacto funcional e os motivos em detalhes. Pode haver facilmente conflitos nos requisitos de negócios que vêm à tona aqui. Discuta com os BAs, outros desenvolvedores, conforme apropriado. Experimente a complexidade envolvida na resolução da interferência.
Etapa 4. À luz do acima exposto, decida se deseja mesclar / colher de cerejeira / até colar e colar apenas as partes que não conflitam e reescrevem as peças conflitantes, OU se reescreve todo o recurso do zero .
fonte
1. Alterne para a ramificação que é usada como uma ramificação principal de desenvolvedor / versão.
Este é o ramo que contém as alterações mais recentes no sistema. Pode ser
master
,core
,dev
, isso depende da empresa. No seu caso, provavelmente émaster
diretamente.Puxe para garantir que você tenha a versão mais recente do principal ramo de desenvolvimento adquirido.
2. Faça o checkout e puxe o ramo que contém o trabalho que você deve concluir.
Você puxa para garantir que realmente tenha o conteúdo mais recente da ramificação. Ao fazer o check-out diretamente, sem criá-lo localmente primeiro, você garante que não haja o novo conteúdo
master
(ou o principal ramo de desenvolvimento, respectivamente) nele.3. Mesclar o ramo principal de desenvolvimento ao ramo obsoleto.
O
git merge
comando tentará mesclar o conteúdo da ramificação especificada, neste casomaster
, para a ramificação em que você está atualmente.A ênfase será tentada . Pode haver conflitos de mesclagem, que precisarão ser resolvidos somente por você e você.
4. Corrija os conflitos de mesclagem, confirme e envie a correção de conflitos
Depois de corrigir o conflito de mesclagem em todos os arquivos onde houver, prepare, confirme e envie a resolução de conflitos para
origin
.Você geralmente pode ligar
git add .
para preparar todos os arquivos para confirmação. Ao lidar com conflitos de mesclagem, você deseja que todos os arquivos necessários sejam atualizados.Nota adicional
Resolver conflitos de mesclagem pode ser um trabalho tedioso. Especialmente se você é novo em uma empresa. Talvez você ainda não tenha o conhecimento adequado para resolver todos os conflitos de mesclagem.
Tome seu tempo para inspecionar cuidadosamente todos os conflitos que ocorreram e resolvê-los adequadamente, antes de continuar seu trabalho.
Pode acontecer, então, você começa a trabalhar em uma ramificação de um ano, mescla o estado de desenvolvimento atual e não terá nenhum conflito de mesclagem.
Isso acontece quando, embora o sistema tenha mudado muito no ano, ninguém tocou nos arquivos que foram realmente alterados no ramo de um ano.
fonte