/ / Merge diff entre dois ramos para o terceiro ramo - git, diff

Mesclar diff entre dois ramos no terceiro ramo - git, diff

Suponha que tenho dois ramos, master e new_feature

Eu deveria trabalhar em um recurso específico, pensei que esse recurso faria parte de new_feature então, eu verifiquei specific_feature ramificar para fora do new_feature ramo, assim

git checkout -b specific_feature

Agora eu desenvolvi muito neste specific_feature ramo, fundido upstream/new_feature nele algumas vezes para obter as alterações remotas.

Agora, eu vim saber que meu specific_feature deveria ter sido ramificado de master não new_feature. (new_feature branch não está pronto para ser empurrado)

Existe uma maneira de fazer a diferença entre os meus specific_feature ramo e new_feature ramo, e aplicar essas mudanças ao novo ramo, digamos specific_feature_master (ramificado para fora do mestre)?

Respostas:

4 para resposta № 1

Isso parece um trabalho para git rebase --onto:

git rebase --onto master new_feature specific_feature

Isso levará apenas os commits depois de new_feature até specific_feature HEAD e reproduzi-los em master.

Observe que você terá que forçar o envio de specific_feature para o upstream (se já tiver feito push antes): git push --force specific_feature.

Isso pode ser um problema se outros já retiraram esse branch e estão trabalhando nisso.


davidriod aponta corretamente que:

Eu não acho que isso funcionará como o OP fundido várias vezes upstream/new_feature ramo no ramo specific_feature

E se new_feature nunca foi atualizado (buscar apenas, nunca puxar), então ainda pode funcionar.
E se new_feature foi atualizado (puxado) e mesclado com specific_feature, então o rebase --onto tocaria apenas os últimos commits desde a última fusão: aqui, apenas z" commits seriam repetidos, não o primeiro z.

x--x--x

y--y--Y--y--y (new_feature)
  
z--M--z"--z" (specific_feature)

Em vez de escolher seletivamente, eu:

  • faço specific_feature fora de master (e marque o specific_feature ramo como tmp)
  • fundir Y (o último new_feature commit que foi fundido em specifc_feature) para o novo specific_feature ramo

Isso é:

git checkout -b tmp specific_feature
git checkout -B specific_feature master
git merge $(git merge-base tmp new_feature) # that merges Y

----------M (specific_feature)
/         /
x--x--x         /
       /
y--y--Y--y--y (new_feature)
  
z--M--z"--z" (tmp)

Então o rebase --onto pode usar o mesmo ancestral comum Y como a base correta:

git rebase --onto specific_feature $(git merge-base tmp new_feature) tmp
git branch -D tmp

----------M--z""--z"" (specific_feature)
/         /
x--x--x         /
       /
y--y--Y--y--y (new_feature)

1 para resposta № 2

Você pode usar o comando git cherry para recuperar o commit feito no branch specific_feature e que não aparece no branch origin / new_feature.

git cherry origin/new_feature specific_feature

Você pode então criar uma nova ramificação do mestre eescolha a dedo todos esses commits. Mas se você depender de seu desenvolvimento em specific_feature e origin / new_feature, nenhum scm vai resolver isso para você.

git checkout -b specific_feature_master master
git cherry origin/new_feature specific_feature | egrep "^+" | awk "{print $2} | xargs git cherry-pick

Algo assim deve servir de ponto de partida para resolver seu problema.