Começando com git 1.9 / 2.0 Q1 2014, você não terá de marcar a sua origem ramo anterior antes rebasing-lo no ramo montante regravados, conforme descrito em Aristóteles Pagaltzis 's resposta :
Veja cometer 07d406b e cometer d96855f :
Depois de trabalhar no topicramo criado com git checkout -b topic origin/master, o histórico do ramo de rastreamento remoto origin/masterpode ter sido rebobinado e reconstruído, levando a um histórico desta forma:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
onde origin/masterusado para apontar para commits B3, B2, B1e agora aponta para B, e seu topicramo foi iniciado em cima dela de volta quando origin/masterestava em B3.
Este modo usa o reflog de origin/masterpara encontrar B3como o ponto de bifurcação, de modo que o topicpossa ser realocado em cima do atualizadoorigin/master por:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
É por isso que o git merge-basecomando tem uma nova opção:
--fork-point::
Encontre o ponto em que uma ramificação (ou qualquer histórico que leve a <commit>) bifurcou-se de outra ramificação (ou qualquer referência) <ref>.
Isso não apenas procura pelo ancestral comum dos dois commits, mas também leva em consideração o reflog de <ref>para ver se a história que levou a <commit>bifurcou-se de uma encarnação anterior do ramo<ref> .
O git pull --rebasecomando " " calcula o ponto de bifurcação da ramificação sendo realocada usando as entradas de reflog da baseramificação " " (normalmente uma ramificação de rastreamento remoto) em que o trabalho da ramificação foi baseado, a fim de lidar com o caso em que a "base" ramo foi rebobinado e reconstruído.
Por exemplo, se o histórico fosse assim:
- a dica atual do
basebranch " " está em B, mas fetch anterior observou que sua dica costumava ser B3e then B2and then B1
antes de chegar ao commit atual, e
- o branch sendo rebaseado no topo da "base" mais recente é baseado em commit
B3,
ele tenta encontrar B3atravessando a saída do " git rev-list --reflog base" (ou seja B, B1, B2, B3) até encontrar uma confirmação de que é um antepassado da ponta atual " Derived (topic)".
Internamente, temos get_merge_bases_many()que computar isso de uma só vez.
Queríamos uma base de mesclagem entre Derivedum commit de mesclagem fictício que resultaria da mesclagem de todas as dicas históricas de " base (origin/master)".
Quando existe tal confirmação, devemos obter um único resultado, que corresponda exatamente a uma das entradas de reflog de " base".
Git 2.1 (Q3 2014) irá adicionar tornar este recurso mais robusto para isso: consulte commit 1e0dacd de John Keeping ( johnkeeping)
lidar corretamente com o cenário em que temos a seguinte topologia:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
Onde:
B'é uma versão corrigida do Bque não é idêntica ao patch B;
C*e D*são idênticos ao patch Ce Drespectivamente e conflitam textualmente se aplicados na ordem errada;
Edepende textualmente D.
O resultado correto da git rebase master devé que Bé identificado como o ponto de bifurcação do deve master, de modo que C, D, Esão os commits que precisam ser repetidos para master; mas Ce Dsão idênticos ao patch com C*e D*e podem ser eliminados, de modo que o resultado final seja:
o --- B' --- C* --- D* --- E <- dev
Se o ponto de bifurcação não for identificado, pegar Bum branch contendo B'resulta em um conflito e se os commits idênticos ao patch não forem identificados corretamente, então pegar Cum branch contendo D(ou equivalentemente D*) resulta em um conflito.
O " --fork-point" modo de " git rebase" regrediu quando o comando foi reescrito em C na era 2.20, que foi corrigido com Git 2.27 (Q2 2020).
Veja o commit f08132f (09 de dezembro de 2019) de Junio C Hamano ( gitster) .
(Incorporado por Junio C Hamano - gitster- no commit fb4175b , 27 de março de 2020)
rebase: --fork-pointcorreção de regressão
Assinado por: Alex Torok
[jc: reformulou a correção e usou os testes de Alex]
Assinado por: Junio C Hamano
" git rebase --fork-point master" costumava funcionar bem, porque era chamado internamente de " git merge-base --fork-point" que sabia como lidar com refname curto e defini-lo como refname completo antes de chamar a get_fork_point()função subjacente .
Isso não é mais verdade depois que o comando foi reescrito em C, pois sua chamada interna feita diretamente para get_fork_point()não desativa uma referência curta.
Mova a lógica "dwim the refname para o refname completo" que é usada em "git merge-base" para a get_fork_point()função subjacente , de modo que o outro chamador da função na implementação de "git rebase" se comporte da mesma maneira para corrigir esta regressão.