Wszyscy słyszeliśmy, że nigdy nie powinno się zmieniać bazy opublikowanych prac, że jest to niebezpieczne itp. Jednak nie widziałem żadnych opublikowanych przepisów na to, jak radzić sobie w sytuacji, gdy zostanie opublikowana rebase .
Teraz zwróć uwagę, że jest to naprawdę wykonalne tylko wtedy, gdy repozytorium jest sklonowane tylko przez znaną (i najlepiej małą) grupę ludzi, tak aby każdy, kto popycha rebase lub reset, mógł powiadomić wszystkich innych, że będzie musiał zwrócić uwagę następnym razem sprowadzać(!).
Jedno oczywiste rozwiązanie, które widziałem, zadziała, jeśli nie masz lokalnych zatwierdzeń foo
i zostanie zmienione:
git fetch
git checkout foo
git reset --hard origin/foo
Spowoduje to po prostu odrzucenie lokalnego stanu foo
na korzyść jego historii zgodnie ze zdalnym repozytorium.
Ale jak sobie radzić z sytuacją, jeśli w tej branży nastąpiły istotne zmiany lokalne?
źródło
git pull --rebase && git push
. Jeśli będziesz pracowaćmaster
tylko nad tym, to prawie niezawodnie zrobi to, co trzeba, nawet jeśli zmienisz bazę i popchniesz na drugim końcu.git reset --hard @{upstream}
teraz, gdy wiem, że magiczne zaklęcie refspec dla „zapomnij, co mam / miałem, użyj tego, co pobrałem z pilota”. Zobacz mój ostatni komentarz do stackoverflow.com/a/15284176/717355push -f
): zobacz moją odpowiedź poniżejOdpowiedzi:
W większości przypadków przywrócenie synchronizacji po wymuszonej rebase nie jest tak skomplikowane.
To znaczy. najpierw ustawiasz zakładkę dla miejsca, w którym pierwotnie znajdowała się zdalna gałąź, a następnie używasz jej do odtwarzania lokalnych zatwierdzeń od tego momentu do zdalnej gałęzi ponownie bazującej.
Rebasing jest jak przemoc: jeśli nie rozwiąże twojego problemu, potrzebujesz go więcej. ☺
Możesz to zrobić oczywiście bez zakładki, jeśli odszukasz
origin/foo
identyfikator zatwierdzenia przed rebase i użyjesz go.W ten sposób radzisz sobie również z sytuacją, w której zapomniałeś utworzyć zakładkę przed pobraniem. Nic nie jest stracone - wystarczy sprawdzić reflog dla zdalnego oddziału:
Spowoduje to wydrukowanie identyfikatora zatwierdzenia, który
origin/foo
wskazywał przed ostatnim pobieraniem, które zmieniło jego historię.Możesz wtedy po prostu
źródło
git reflog show origin/foo
jednolinijkowy po prostu przegląda dane wyjściowe polecenia dla pierwszej linii i mówi „pobierz: wymuszona aktualizacja”; to właśnie rejestruje git, gdy pobieranie powoduje, że zdalna gałąź robi cokolwiek innego niż przewijanie do przodu. (Możesz też zrobić to ręcznie - wymuszona aktualizacja jest prawdopodobnie najnowszą rzeczą).Powiedziałbym, że sekcja odzyskiwania z górnej części strony podręcznika git-rebase obejmuje prawie wszystko.
Naprawdę nie różni się to od odzyskiwania z własnej bazy - przenosisz jedną gałąź i ponownie bazujesz wszystkie gałęzie, które miały ją w swojej historii, na nową pozycję.
źródło
Począwszy od git 1,9 / 2,0 Q1 2014, nie będzie musiał zaznaczyć swoją poprzednią pochodzenie oddział przed przebazowania go na przepisany upstream oddziału, jak opisano w Arystoteles Pagaltzis „s odpowiedź :
See popełnić 07d406b i popełnić d96855f :
Dlatego
git merge-base
polecenie ma nową opcję:Na przykład, jeśli historia wyglądała tak, gdzie:
Git 2.1 (Q3 2014) doda, że ta funkcja będzie bardziej niezawodna: zobacz commit 1e0dacd autorstwa Johna Keeping (
johnkeeping
)poprawnie obsłużmy scenariusz, w którym mamy następującą topologię:
gdzie:
B'
jest poprawioną wersją programu,B
która nie jest łatka zB
;C*
iD*
są identyczne z poprawkamiC
iD
odpowiednio i powodują konflikt tekstowy, jeśli zostaną zastosowane w złej kolejności;E
zależy od tekstuD
.Prawidłowe wynikiem
git rebase master dev
jest to, żeB
jest określona jako widełek punktudev
imaster
tak, abyC
,D
,E
to dopuszcza, które muszą być odtwarzane namaster
; aleC
iD
są patch-identyczne zC*
iD*
i tak mogą być usunięte, tak że efekt końcowy to:Jeśli punkt rozwidlenia nie zostanie zidentyfikowany, to wybranie
B
gałęzi zawierającejB'
powoduje konflikt, a jeśli zatwierdzenia identyczne z łatą nie są poprawnie zidentyfikowane, wybranieC
do gałęzi zawierającejD
(lub równoważnieD*
) powoduje konflikt."
--fork-point
" Tryb "git rebase
" cofnął się, gdy polecenie zostało przepisane w C w 2.20 era, co zostało poprawione w Git 2.27 (Q2 2020).Zobacz commit f08132f (09 grudnia 2019) autorstwa Junio C Hamano (
gitster
) .(Scalone przez Junio C Hamano -
gitster
- w zobowiązaniu fb4175b , 27 marca 2020 r.)źródło