A partir de git 1.9 / 2.0 Q1 2014, no tendrá que marcar el origen de su rama anterior antes de volver a basarlo en la rama ascendente reescrita, como se describe en la respuesta de Aristóteles Pagaltzis :
consulte la confirmación 07d406b y la confirmación d96855f :
Después de trabajar en la topic
rama creada con git checkout -b topic origin/master
, es posible que el historial de la rama de seguimiento remoto origin/master
se haya rebobinado y reconstruido, lo que lleva a un historial de esta forma:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
donde origin/master
se utiliza para señalar compromete B3
, B2
, B1
y ahora apunta a B
, y su topic
rama se inició en la parte superior de nuevo cuando origin/master
estaba en B3
.
Este modo usa el reflog de origin/master
para encontrar B3
como punto de bifurcación, de modo que se topic
pueda volver a basar en la parte superior de la actualizaciónorigin/master
mediante:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
Es por eso que el git merge-base
comando tiene una nueva opción:
--fork-point::
Encuentre el punto en el que una rama (o cualquier historial que conduzca a <commit>
) se bifurcó desde otra rama (o cualquier referencia) <ref>
.
Esto no solo busca el ancestro común de las dos confirmaciones, sino que también tiene en cuenta el re-registro de <ref>
para ver si la historia que lleva a <commit>
bifurcar desde una encarnación anterior de la rama<ref>
.
El git pull --rebase
comando " " calcula el punto de bifurcación de la rama que se está rebasando utilizando las entradas de " base
" reflog de la rama (normalmente una rama de seguimiento remoto) en la que se basó el trabajo de la rama, para hacer frente al caso en el que la "base" La rama ha sido rebobinada y reconstruida.
Por ejemplo, si el historial se parece a dónde:
- la punta actual de la
base
rama " " está en B
, pero la recuperación anterior observó que su punta solía estar B3
y luego B2
y luego B1
antes de llegar a la confirmación actual, y
- la rama que se está rebasando sobre la última "base" se basa en la confirmación
B3
,
se trata de encontrar B3
yendo a través de la salida de " git rev-list --reflog base
" (es decir B
, B1
, B2
, B3
) hasta que encuentra una confirmación de que es un antepasado de la punta actual " Derived (topic)
".
Internamente, tenemos get_merge_bases_many()
que puede calcular esto con una sola vez.
Querríamos una base de fusión entre Derived
y un compromiso de fusión ficticio que resultaría al fusionar todos los consejos históricos de " base (origin/master)
".
Cuando existe tal compromiso, deberíamos obtener un único resultado, que coincida exactamente con una de las entradas de reflog de " base
".
Git 2.1 (Q3 2014) agregará hacer que esta característica sea más robusta para esto: vea el compromiso 1e0dacd de John Keeping ( johnkeeping
)
Manejar correctamente el escenario donde tenemos la siguiente topología:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
dónde:
B'
es una versión corregida B
que no es idéntica al parche B
;
C*
y D*
son idénticos al parche C
y, D
respectivamente, y entran en conflicto textualmente si se aplican en el orden incorrecto;
E
depende textualmente de D
.
El resultado correcto de git rebase master dev
es que B
se identifica como el tenedor-punto de dev
y master
, de manera que C
, D
, E
son los commit esa necesidad para que se reproduzca en master
; pero C
y D
son patch-idéntico C*
y D*
por lo que puede ser bajado, de modo que el resultado final es:
o --- B' --- C* --- D* --- E <- dev
Si no se identifica el punto de bifurcación, elegir B
una rama que contenga B'
da como resultado un conflicto y si las confirmaciones idénticas al parche no se identifican correctamente, elegir C
una rama que contenga D
(o de manera equivalente D*
) da como resultado un conflicto.
El " --fork-point
" modo de " git rebase
" retrocedió cuando el comando se reescribió en C en la era 2.20, que se corrigió con Git 2.27 (Q2 2020).
Consulte la confirmación f08132f (09 de diciembre de 2019) de Junio C Hamano ( gitster
) .
(Combinado por Junio C Hamano - gitster
- en commit fb4175b , 27 de marzo de 2020)
rebase
: --fork-point
corrección de regresión
Firmado por: Alex Torok
[jc: renovó la corrección y usó las pruebas de Alex]
Firmado por: Junio C Hamano
" git rebase --fork-point master
" solía funcionar bien, como llamaba internamente " git merge-base --fork-point
" que sabía cómo manejar el nombre de referencia corto y dwim al nombre de referencia completo antes de llamar a la get_fork_point()
función subyacente .
Esto ya no es cierto después de que el comando se reescribió en C, ya que su llamada interna hecha directamente a get_fork_point()
no muestra una referencia corta.
Mueva la lógica "dwim the refname a la lógica refname completa" que se usa en "git merge-base" a la get_fork_point()
función subyacente , de modo que la otra persona que llama a la función en la implementación de "git rebase" se comporte de la misma manera para corregir esta regresión.