Como o git ajuda a lidar com o cenário abaixo:
Eu tenho uma tarefa dividida em 2 partes: tarefa de back-end e tarefa de front-end. Eu faço uma solicitação pull para mesclar as alterações de back-end e espero que sejam mescladas (e endereçar comentários). Enquanto aguardo, não posso trabalhar nas alterações de front-end, pois depende de alterações de back-end e elas ainda não estão disponíveis na ramificação principal.
Qual é a melhor maneira de obter alterações para ramificação de alterações de front-end do ramo de alterações de back-end enquanto ele ainda está sendo revisado?
Respostas:
Eu também tenho esse problema algumas vezes. Git é muito flexível. Aqui está uma maneira de fazer isso.
Sua primeira filial
featureA
está em revisão.Seu segundo ramo
featureB
está em desenvolvimento e depende do código nofeatureA
ramo.Mesclar a
featureA
ramificação nafeatureB
ramificação.Se você fizer alterações na
featureA
ramificação, deverá mesclarfeatureA
afeatureB
ramificação novamente para incorporar as alterações.Você também deve se fundir
featureA
ao tronco principal primeiro, caso contrário, ao se fundirfeatureB
no tronco principal, você inadvertidamente também será mescladofeatureA
. Depois defeatureA
mesclado no tronco principal, você pode se livrar dofeatureA
ramo, pois agorafeatureB
só depende do tronco principal.Eu prefiro quando meus ramos de recursos não dependem um do outro, mas às vezes eles dependem e você precisa seguir com ele.
fonte
featureA
para,featureB
se necessário?featureA
caso precise começar de novo. É bom pensar nos galhos do Git como descartáveis. Eles são baratos e fáceis, você sempre pode fazer uma nova filial. Você pode até criar uma ramificação de teste fora de suafeatureB
ramificação, se quiser brincar com algo que não tem certeza, e depois descartá-la se não der certo, ou mesclar de volta para suafeatureB
ramificação, se isso acontecer.Espere, pule a fusão
Para esta abordagem, você não deseja mesclar sua
feature_a
emfeature_b
repetidamente.O rebase foi mencionado em outras respostas, mas apenas para rebater as coisas
master
. O que você quer fazer no seu caso é:Comece o seu
feature_b
defeature_a
, ou seja:Sempre que
feature_a
mudar enquanto aguarda a fusãomaster
, você a refazfeature_b
:Por fim, assim que
feature_a
for mescladomaster
, você simplesmente obtém o novomaster
e o refazfeature_a
uma última vez:Essa nova versão final enxertará todos os commits que estão pendurados no
feature_a
commit (que agora é irrelevante como foi mescladomaster
) diretamentemaster
. Seufeature_b
agora é um ramo simples, padrão indo para a direita a partirmaster
.EDIT: inspirado nos comentários, um pouco de atenção: se você precisar fazer alguma alteração que afeta os dois recursos, certifique-se de inseri-lo
feature_a
(e depois refazê-lo conforme mostrado). Você não fazê-lo em dois commits diferentes em ambos os ramos, mesmo que possa ser tentador; comofeature_a
faz parte da história defeature_b
, ter uma única alteração em dois commits diferentes estará semanticamente errada e possivelmente levará a conflitos ou "ressurreições" de código indesejado posteriormente.fonte
feature_a
várias vezes, é possível que ocorram problemas mais tarde, quando ofeature_a
mesmo foi rebatizado nesse meio tempo. Como resultado da execução,git checkout feature_b; git rebase feature_a
você pode ter conflitos ou algumas confirmações engraçadas contendo confirmações, revertendo novas alterações defeature_a
. Isso geralmente é solucionável usando--interactive
e ignorando confirmações retiradas da versão antiga do outro ramo (eu tive que fazer isso várias vezes recentemente).rebase
como muitas etapas individuais, mais do que uma simplesmerge
, há certamente uma chance muito maior de criar conflitos; por outro lado,merge
seria semântica o bastante errado nesse caso.merge
que teria problemas semelhantes ou piores (um conflito não é tão ruim quanto entrar em uma mudança indesejada). Eu vejo um ramo como uma sequência de alterações desejadas precedidas por muitas alterações não relacionadas (pertencendo logicamente a um ramo diferente). Ao refazer repetidamente o mesmo ramo, sempre removo as alterações não relacionadas, pois sei que elas ocorrerão de qualquer maneira (possivelmente em uma forma atualizada) e elas funcionam bem.git rebase --onto
FTW: DVocê já possui uma ramificação da qual cada ramificação de recursos depende e que continua mudando. É chamado
master
.A maneira típica de uma ramificação de recurso permanecer sincronizada
master
é ficar em cima dela. Quandomaster
muda, você normalmente estágit fetch origin master:master && git rebase master
no diretório de trabalho de sua filial.Você pode fazer o mesmo com outra ramificação de recursos: continue a buscá-la e a refazê-la em cima dela.
Se, por algum motivo, você precisar mover suas alterações para uma ramificação diferente, poderá escolher suas confirmações, que nunca serão misturadas com as confirmações de outras ramificações.
fonte
feature-b
-sefeature-a
e fazer uma reformulação repetidas vezes, conforme afeature-a
mudança. Essa é uma maneira típica de tornar uma grande alteração observável: divida-a empart-A
(com base emmaster
),part-B
(com base empart-A
) e muito mais, se necessário. Em seguida, faça uma solicitação de recebimento para cada peça, e os revisores terão mais facilidade em analisar peças menores e agrupadas logicamente.Nesse caso, em que a tarefa de front-end tem uma dependência crítica do código de back-end e você deseja iniciar o trabalho no front-end antes que o back-end seja finalizado e aceito no master, eu simplesmente iniciaria a tarefa de front-end como uma ramificação de recurso proveniente do ramificação de back-end, em vez de ramificar a interface no mestre.
Um ramo de recurso que dura o tempo suficiente precisa mesclar alterações do mestre ocasionalmente (para garantir que você reconcilie qualquer conflito de mesclagem ou semântica como parte do trabalho de desenvolvimento no ramo de recurso, em vez de como parte da "revisão, qa, mesclagem dominar "). Portanto, você faz isso no seu ramo de front-end e, quando o trabalho de back-end for aceito como mestre, você receberá pequenas alterações feitas no back-end como parte de sua revisão / aceitação automaticamente, pela mesma rota que você obtenha outras alterações de código no master.
Se o ramo de back-end precisar de muito mais trabalho e continuar a mudar por um período de tempo antes de ser mesclado para mestre (por exemplo, se forem encontrados grandes problemas durante a revisão), você provavelmente desejará fazer mesclagens periódicas diretamente do ramo de back-end para o ramo de front-end (para que você não continue baseando todo o seu trabalho de front-end em código de back-end obsoleto). Isso é fácil se você é o único desenvolvedor que executa os dois recursos (já que você sabe se faz grandes alterações), mas mesmo que os dois acabem sendo trabalhados em paralelo por desenvolvedores diferentes, tudo bem; você só precisa manter a comunicação (o que você precisaria de qualquer maneira, se estiver trabalhando em tarefas paralelas em que uma tenha uma dependência crítica da outra).
Se acontecer que todo o ramo de back-end precisa ser abandonado e nunca será mesclado (parece que isso seria um negócio muito importante que raramente aconteceria), então você escolhe seus compromissos para um novo ramo saindo do master sem o trabalho de back-end ou você aplica confirmações reversas que removem todo o código de back-end para a ramificação de front-end. Mas, como posso ver, seria mais provável pausar o trabalho de front-end até você descobrir o que iria substituir o back-end que está jogando fora e depois decidir o que fazer.
fonte
Não vejo o problema aqui.
Você já tem isso o tempo todo com sua
master
filial, que continua mudando enquanto os recursos são desenvolvidos e depois mesclados.Portanto, em seu exemplo concreto, você primeiro cria a
feature_xxx_backend
ramificação e desenvolve as alterações de back-end. Quando isso for feito, a filial poderá revisar e será mescladamaster
assim que a revisão for concluída.Então, simplesmente inicie outro ramo
feature_yyy_frontend
,. Você provavelmente desejará ramificar diretamente defeature_xxx_backend
, para que você já tenha essas alterações em seu branc. então simplesmente desenvolva o recurso de front-end como o ramo eramaster
.Quando a
feature_xxx_backend
ramificação muda, por exemplo, porque existem coisas que surgem durante a revisão que precisam ser corrigidas, basta fazer essas alterações e fundi-las nafeature_yyy_frontend
ramificação. Continue na ramificação da interface.Depois que a revisão da ramificação de back-end é concluída, ela é mesclada
master
. Nesse ponto, seria aconselhável refazer afeature_yyy_frontend
ramificação paramaster
que os revisores precisem revisar apenas as novas alterações para as quais essa ramificação contribuimaster
e não precisem revisar novamente as alterações feitas no back-end (que já foram aprovadas )Isso também pode ser feito quando você tem dois, três ou mais ramos dependentes. Se você possui dois ramos de recurso dos quais você depende, basta criar um ramo derivado com ambos os recursos mesclados. Ramificar a partir daí, desenvolver o terceiro recurso, mesclar os dois ramos de recurso ao longo do caminho quando cada um deles mudar. Quando os dois recursos estiverem concluídos e forem mesclados na ramificação derivada, refazem-se a isso ou, se eles forem mesclados no mestre, faça uma nova recuperação no mestre.
O rebaseamento (como sugerido acima) é realmente poderoso e ajuda a manter um registro limpo das alterações, facilitando muito as revisões.
fonte
Como o Polygnome mencionou, você pode realmente mesclar seu ramo de front-end com o ramo de back-end em vez dos mestres. Mesmo com a configuração de ramificação atual que você tem agora, você pode simplesmente:
ou simplesmente
Lembre-se de que, se as alterações no back-end não forem aceitas e mais trabalho for necessário, você precisará mesclar as atualizações do back-end no front-end para evitar conflitos. Depois que as alterações forem aceitas no mestre, você poderá refazer o frontend no master para se livrar das confirmações de mesclagem do backend.
Tecnicamente, você também pode fazer tudo com o rebase, mas isso atrapalha o histórico de consolidação do seu ramo de front-end. De onde eu venho, isso é considerado uma prática ruim. YMMV
fonte
A maioria das respostas aqui descreve corretamente o processo de mesclar as alterações da segunda ramificação para a primeira, mas elas não abordam como minimizar a quantidade de conflitos que talvez você precise resolver.
Sempre que você tiver dois conjuntos de grandes alterações que deseja revisar individualmente (como
featureA
efeatureB
), crie um PR que NÃO deve ser mesclado, mas para obter feedback antecipado sobre um PoC defeatureA
.As pessoas poderão revisá-lo rapidamente (é apenas um PoC), e o objetivo é validar o design ou a abordagem geral.
Em seguida, você pode continuar trabalhando no recurso A, criar uma solicitação de recebimento e ramificar e trabalhar no recurso B.
A grande diferença é que agora você pode esperar
featureA
não mudar radicalmente: o design e a abordagem já foram validados. A revisão do código e as alterações necessárias podem ser sutis e locais, em vez de "woops, você precisa de uma abordagem diferente". Isso irá minimizar a quantidade de trabalho que você precisa fazer para mesclar mais tardefeatureB
emfeatureA
'código s, independentemente do método que você escolheu.fonte