Eu tenho um cliente que insistiu em manter nosso novo desenvolvimento separado das principais filiais durante todo o ano de 2016. Eles tinham 3-4 outras equipes trabalhando no aplicativo em várias capacidades. Várias grandes alterações foram feitas (alternando como a injeção de dependência é feita, limpando o código com o ReSharper, etc.). Agora cabe a mim mesclar o principal em nosso novo ramo de desenvolvimento para me preparar para impulsionar nossas mudanças na cadeia.
No meu pull de mesclagem inicial, o TFS relatou ~ 6500 arquivos com resolução de conflitos. Alguns deles serão fáceis, mas outros serão muito mais difíceis (especificamente alguns javascript, controladores de API e serviços que suportam esses controladores).
Existe uma abordagem que eu possa adotar que facilitará isso para mim?
Para esclarecer, expressei muita preocupação com essa abordagem várias vezes ao longo do caminho. O cliente estava e está ciente das dificuldades com isso. Como eles escolheram reduzir a equipe de controle de qualidade (1 testador para 4 desenvolvedores, nenhum teste automatizado, pouco teste de regressão), eles insistiram em manter nosso ramo isolado das mudanças no ramo principal sob o pretexto de que isso reduziria a necessidade de nosso testador para saber sobre as alterações sendo feitas em outros lugares.
Um dos maiores problemas aqui é a atualização para a versão angular e alguns dos outros softwares de terceiros - infelizmente não temos uma boa maneira de criar essa solução até que todas as peças sejam colocadas novamente no lugar.
fonte
Respostas:
Teria havido uma maneira simples de manter seu novo desenvolvimento separado do ramo principal sem levar você a esta situação infeliz: qualquer alteração do tronco deveria ser mesclada no seu ramo de desenvolvimento diariamente . (Seu cliente foi realmente tão míope que ele não podia prever que sua filial precisaria ser remetida de volta à linha principal algum dia?)
Enfim, a melhor abordagem é IMHO tentando refazer o que deveria ter acontecido em primeira mão:
Isso pode funcionar quando as equipes obedecem estritamente às regras clássicas de controle de versão ("apenas confirmam estados compiláveis e testados" e "faz check-in antecipado e frequente").
Após 365 repetições (ou 250, se você tiver sorte e puder agrupar o trabalho para alterações no final de semana), estará quase concluído (quase, porque você precisará adicionar o número de alterações que ocorrerão na linha principal durante o período de integração) ) A etapa final será mesclar o ramo de desenvolvimento atualizado no tronco novamente (para que você não perca o histórico do tronco). Isso deve ser fácil, porque tecnicamente deve ser apenas uma substituição dos arquivos afetados.
E sim, estou falando sério, provavelmente não há atalho para isso. Pode ser que as "porções diárias" às vezes sejam muito pequenas, mas eu não esperaria isso, acho que é mais provável que as porções diárias possam ser muito grandes. Espero que seu cliente pague muito bem por isso, e que isso seja tão caro para ele que ele aprenderá com seu fracasso.
Devo acrescentar que você pode tentar isso também com os lados trocados - reintegrando as alterações do seu ramo em pequenas porções para a linha principal. Isso pode ser mais simples quando no seu ramo de desenvolvimento houve muito menos alterações do que no tronco, ou a maioria das alterações ocorreu em novos arquivos de origem que atualmente não fazem parte do tronco. Pode-se ver isso como "portando" um recurso de um produto A (o ramo dev) para um produto um pouco diferente B (estado atual do tronco). Mas se a maioria das refatorações transversais foram feitas na linha principal e afetam seu novo código (as colisões de mesclagem 6500 parecem ser uma evidência disso), talvez seja mais fácil a maneira como a descrevi primeiro.
fonte
Naquele estágio de mesclagem, eu diria que a mesclagem automatizada pode apenas complicar demais o processo. Eu tive problemas semelhantes com filiais que divergiram por mais de um ano e o método mais eficaz que tenho é fazer o seguinte:
Eventualmente, os avisos do compilador e as diferenças serão seus melhores amigos, continue usando a diferença não imersa para ver exatamente o que era diferente e apenas continue. Pode haver várias ferramentas que você pode usar para ajudar, mas isso depende de você descobrir qual é o melhor.
A chave é continuar.
Editar:
Uma palavra de aviso, essa abordagem significa que o histórico de controle de versão ficaria "corrompido", pois você perderia as evidências da mesclagem de ramo a ramo, bem como o histórico do ramo não imerso.
Graças aos comentários de 'Jack Aidley' e '17 de 26 '
fonte
Alguns anos atrás, tínhamos um cliente com os mesmos requisitos de manter filiais separadas. Então nós fizemos.
Nós nunca fundimos o ramo deles de volta. Eles tinham sua própria versão única. Cobramos mais por mudanças, pois basicamente tínhamos dois troncos principais em vez de um tronco e galhos principais.
Tentamos voltar ao tronco, mas após duas semanas decidimos abandonar esse esforço, pois estava queimando horas sem benefícios tangíveis.
Portanto, não mescle de volta. No futuro, mesclar correções críticas para essa filial do cliente, conforme necessário, e qualquer aprimoramento seria um custo cobrado especificamente para esse cliente.
fonte
Não vai ser divertido, mas o quão doloroso será depende da natureza das mudanças e de quão isoladas elas são.
Sugiro que você tente convergir as ramificações através da refatoração, tanto quanto possível, antes de fazer uma mesclagem real.
A ferramenta de mesclagem é meio boba, porque apenas analisa diferenças de texto e não entende o código de forma alguma. Se a ramificação principal alterou o nome de uma classe usada em todo o aplicativo, e a ramificação de recurso usa o nome antigo em algum novo código, a ferramenta de mesclagem não entenderá que o nome da classe também deve ser alterado no novo código. Mas se você fizer uma refatoração na ramificação B para renomear a classe como na ramificação A, ela funcionará no código antigo e no novo e a mesclagem ocorrerá sem problemas.
Em segundo lugar, você deve inspecionar a localização das alterações no ramo de desenvolvimento. Se as alterações na ramificação do recurso estiverem localizadas em algumas áreas, você não precisará convergir o código não afetado, basta copiar e substituir a partir da ramificação principal.
Nas áreas de código em que houve alterações não triviais em ambas as ramificações, você deve inspecionar cuidadosamente o código e decidir como reescrever.
fonte