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 topic
ramo criado com git checkout -b topic origin/master
, o histórico do ramo de rastreamento remoto origin/master
pode 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/master
usado para apontar para commits B3
, B2
, B1
e agora aponta para B
, e seu topic
ramo foi iniciado em cima dela de volta quando origin/master
estava em B3
.
Este modo usa o reflog de origin/master
para encontrar B3
como o ponto de bifurcação, de modo que o topic
possa 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-base
comando 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 --rebase
comando " " calcula o ponto de bifurcação da ramificação sendo realocada usando as entradas de reflog da base
ramificaçã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
base
branch " " está em B
, mas fetch anterior observou que sua dica costumava ser B3
e then B2
and 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 B3
atravessando 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 Derived
um 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 B
que não é idêntica ao patch B
;
C*
e D*
são idênticos ao patch C
e D
respectivamente e conflitam textualmente se aplicados na ordem errada;
E
depende textualmente D
.
O resultado correto da git rebase master dev
é que B
é identificado como o ponto de bifurcação do dev
e master
, de modo que C
, D
, E
são os commits que precisam ser repetidos para master
; mas C
e D
sã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 B
um branch contendo B'
resulta em um conflito e se os commits idênticos ao patch não forem identificados corretamente, então pegar C
um 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-point
correçã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.