Tópico Solução
O comando correto para responder à pergunta postada pode ser um dos seguintes (supondo que a ramificação topic
já esteja com check-out):
git rebase --onto B master
git rebase --onto master~1 master
git rebase --onto B A
git rebase --onto B C
git rebase --onto B
Se topic
não estiver marcado, basta anexar topic
ao comando (exceto o último) da seguinte forma:
git rebase --onto B master topic
Como alternativa, verifique primeiro o ramo com:
git checkout topic
Rebase qualquer sequência de confirmações para uma confirmação de destino
A forma básica do comando que precisamos, extraída da documentação, é:
git rebase --onto <Target> [<Upstream> [<Branch>]]
<Branch>
é opcional e tudo o que faz é fazer check-out da ramificação especificada antes de executar o restante do comando. Se você já fez check-out da ramificação que deseja refazer a recuperação, não precisa disso. Observe que você deve ter especificado <Upstream>
para especificar <Branch>
ou o git pensará que você está especificando<Upstream>
.
<Target>
é o commit ao qual anexaremos nossa cadeia de commits. Ao fornecer um nome de filial, você está simplesmente especificando o commit principal dessa filial. <Target>
pode ser qualquer confirmação que não esteja contida na cadeia de confirmações que está sendo movida. Por exemplo:
A --- B --- C --- D master
\
\-- X --- Y --- Z feature
Para mover todo o ramo de funcionalidade, você não pode selecionar X
, Y
, Z
, ou feature
como o<Target>
desde os todos são commits dentro do grupo que está sendo movido.
<Upstream>
é especial porque pode significar duas coisas diferentes. Se for um commit que é um ancestral do ramo com check-out, ele servirá como ponto de corte. No exemplo que eu forneci, isso seria qualquer coisa que não é C
, D
ou master
. Todas as confirmações depois <Upstream>
até o chefe da ramificação com check-out são as que serão movidas.
No entanto, se <Upstream>
não for um ancestral, o git fará o backup da cadeia a partir do commit especificado até que encontre um ancestral comum com o ramo com check-out (e interrompa se não conseguir encontrar um). No nosso caso, um <Upstream>
dos B
, C
, D
, ou master
tudo vai resultar em comprometer B
servindo como ponto de corte. <Upstream>
é ele próprio um comando opcional e, se não for especificado, o git examinará o pai do ramo com check-out equivalente à entradamaster
.
Agora que o git selecionou os commits que serão cortados e movidos, aplica-os para <Target>
, ignorando os que já estão aplicados ao alvo.
Exemplos e resultados interessantes
Usando este ponto de partida:
A --- B --- C --- D --- E master
\
\-- X --- Y --- Z feature
git rebase --onto D A feature
Será aplicada commits B
, C
, X
, Y
, Z
para cometer D
e acabam pulando B
e C
porque eles já foram aplicadas.
git rebase --onto C X feature
Aplicará confirmações Y
e Z
confirmações C
, excluindo efetivamente as confirmaçõesX
git checkout B
antes de executargit rebase
?