Todos hemos oído que uno nunca debe publicada rebase el trabajo, que es peligroso, etc. Sin embargo, no he visto ninguna de las recetas publicadas de cómo hacer frente a la situación en caso de un rebase se publicó.
Ahora, tenga en cuenta que esto solo es realmente factible si el repositorio solo es clonado por un grupo conocido (y preferiblemente pequeño) de personas, de modo que quien empuje el rebase o reinicio pueda notificar a todos los demás que deberán prestar atención la próxima vez que lo hagan. ir a buscar(!).
Una solución obvia que he visto funcionará si no tiene confirmaciones locales foo
y se vuelve a basar:
git fetch
git checkout foo
git reset --hard origin/foo
Esto simplemente descartará el estado local de foo
a favor de su historial según el repositorio remoto.
Pero, ¿cómo se maneja la situación si se han realizado cambios locales sustanciales en esa rama?
fuente
git pull --rebase && git push
. Simaster
solo trabajas , esto hará casi infaliblemente lo correcto para ti, incluso si has rebasado y empujado al otro extremo.git reset --hard @{upstream}
ahora que sé que el encantamiento refspec mágico para "olvidar lo que tengo / tuve, usar lo que obtuve del control remoto". Ver mi comentario final en stackoverflow.com/a/15284176/717355push -f
): vea mi respuesta a continuaciónRespuestas:
Volver a sincronizarse después de un rebase empujado no es realmente tan complicado en la mayoría de los casos.
Es decir. primero configura un marcador para el lugar donde originalmente estaba la rama remota, luego lo usa para reproducir sus confirmaciones locales desde ese punto en adelante en la rama remota rebasada.
Volver a basarse es como la violencia: si no resuelve tu problema, solo necesitas más. ☺
Puede hacer esto sin el marcador, por supuesto, si busca el
origin/foo
ID de confirmación anterior a la rebase y lo usa.Así es también como maneja la situación en la que olvidó hacer un marcador antes de buscar. No se pierde nada, solo necesita verificar el reflog de la rama remota:
Esto imprimirá el ID de confirmación que
origin/foo
apuntaba antes de la recuperación más reciente que cambió su historial.Entonces puede simplemente
fuente
git reflog show origin/foo
frase de una sola línea solo busca en la salida de la primera línea que dice "fetch: force-update"; eso es lo que registra git cuando una búsqueda hace que la rama remota haga cualquier cosa menos adelantar. (También puede hacerlo a mano; la actualización forzada es probablemente lo más reciente).Yo diría que la sección de recuperación de la rebase ascendente de la página de manual de git-rebase cubre prácticamente todo esto.
Realmente no es diferente de recuperarse de su propia base de datos: mueve una rama y vuelve a ajustar todas las ramas que la tenían en su historial en su nueva posición.
fuente
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 :
Es por eso que el
git merge-base
comando tiene una nueva opción:Por ejemplo, si el historial se parece a dónde:
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:
dónde:
B'
es una versión corregidaB
que no es idéntica al parcheB
;C*
yD*
son idénticos al parcheC
y,D
respectivamente, y entran en conflicto textualmente si se aplican en el orden incorrecto;E
depende textualmente deD
.El resultado correcto de
git rebase master dev
es queB
se identifica como el tenedor-punto dedev
ymaster
, de manera queC
,D
,E
son los commit esa necesidad para que se reproduzca enmaster
; peroC
yD
son patch-idénticoC*
yD*
por lo que puede ser bajado, de modo que el resultado final es:Si no se identifica el punto de bifurcación, elegir
B
una rama que contengaB'
da como resultado un conflicto y si las confirmaciones idénticas al parche no se identifican correctamente, elegirC
una rama que contengaD
(o de manera equivalenteD*
) 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)fuente