Dokumentacjarebase
Gita dla tego polecenia jest dość krótka:
--preserve-merges
Instead of ignoring merges, try to recreate them.
This uses the --interactive machinery internally, but combining it
with the --interactive option explicitly is generally not a good idea
unless you know what you are doing (see BUGS below).
Co się dzieje, kiedy używasz --preserve-merges
? Czym różni się od domyślnego zachowania (bez tej flagi)? Co to znaczy „odtworzyć” scalenie itp.
git
git-rebase
Chris
źródło
źródło
git --rebase-merges
ostatecznie zastąpi starygit --preserve-merges
. Zobacz moją odpowiedź poniżejOdpowiedzi:
Podobnie jak w przypadku zwykłego git rebase, git z
--preserve-merges
najpierw identyfikuje listę zatwierdzeń wykonanych w jednej części wykresu zatwierdzeń, a następnie odtwarza te zatwierdzenia na innej części. Różnice dotyczące--preserve-merges
obaw, które zatwierdzenia są wybierane do powtórki, oraz sposób, w jaki to powtórzenie działa w przypadku zatwierdzeń scalania.Aby być bardziej precyzyjnym na temat głównych różnic między normalnym a zachowującym scalanie rebase:
git checkout <desired first parent>
), podczas gdy normalny rebase nie musi się o to martwić.Najpierw spróbuję opisać „wystarczająco dokładnie”, co
--preserve-merges
robi baza , a potem będzie kilka przykładów. Oczywiście można zacząć od przykładów, jeśli wydaje się to bardziej przydatne.Algorytm w skrócie
Jeśli naprawdę chcesz dostać się do chwastów, pobierz źródło git i przejrzyj plik
git-rebase--interactive.sh
. (Rebase nie jest częścią jądra Git, ale jest napisane bash. A poza tym dzieli kod z „interaktywnym rebase”).Ale tutaj naszkicuję to, co według mnie jest jego esencją. Aby zmniejszyć liczbę rzeczy do przemyślenia, podjąłem kilka swobód. (np. nie staram się uchwycić ze 100% dokładnością dokładnej kolejności, w jakiej odbywają się obliczenia, i ignoruję niektóre mniej pozornie centralne tematy, np. co zrobić z zatwierdzeniami, które zostały już wybrane pomiędzy gałęziami).
Po pierwsze, zauważ, że rebase nie zachowujący łączenia jest raczej prosty. To mniej więcej:
Rebase
--preserve-merges
jest stosunkowo skomplikowane. Oto, co udało mi się zrobić bez utraty rzeczy, które wydają się bardzo ważne:Rebase z
--onto C
argumentem powinien być bardzo podobny. Zamiast rozpocząć odtwarzanie zatwierdzenia na GŁOWIE B, zamiast tego zacznij odtwarzanie zatwierdzenia na GŁOWIE C. (I użyj C_new zamiast B_new.)Przykład 1
Na przykład weź wykres zatwierdzania
m jest zatwierdzeniem przez scalenie z rodzicami E i G.
Załóżmy, że zmieniliśmy temat (H) na master (C) przy użyciu normalnego, nie zachowującego scalania rebase. (Na przykład temat kasy; master bazy danych ). W takim przypadku git wybrałby następujące zatwierdzenia do odtworzenia:
a następnie zaktualizuj wykres zatwierdzania w następujący sposób:
(D 'to odtworzony odpowiednik D itp.)
Zauważ, że zatwierdzenie scalania m nie jest wybrane do odtworzenia.
Gdybyśmy zamiast tego zrobili
--preserve-merges
rebase z H na C. (Na przykład, sprawdź temat; rebase - zachowaj-scala wzorzec ). W tym nowym przypadku git wybrałby następujące zatwierdzenia do odtworzenia:Teraz m został wybrany do odtwarzania. Zauważ też, że rodzice E i G scaleni zostali wybrani do włączenia przed scaleniem zatwierdzenia m.
Oto wynikowy wykres zatwierdzenia:
Ponownie, D 'jest wybieralną (tj. Odtworzoną) wersją D. To samo dla E', itp. Każde zatwierdzenie poza masterem zostało odtworzone. Zarówno E, jak i G (łączący rodzice m) zostały odtworzone jako E 'i G', aby służyć jako rodzice m '(po zmianie baza drzew nadal pozostaje taka sama).
Przykład 2
W odróżnieniu od zwykłego rebase, rebase zachowujący scalanie może tworzyć wiele potomków upstream.
Rozważ na przykład:
Jeśli bazujemy na H (temat) na C (master), wówczas zatwierdzenia wybrane dla rebase to:
Wynik jest taki:
Przykład 3
W powyższych przykładach zarówno zatwierdzenie scalania, jak i jego dwoje rodziców są odtwarzane, zamiast oryginalnych rodziców, które mają oryginalne zatwierdzenie scalania. Jednak w innych wersjach ponownie odtworzone zatwierdzenie scalania może skończyć z rodzicami, którzy byli już na wykresie zatwierdzeń przed scaleniem.
Rozważ na przykład:
Jeśli zmienimy temat na master (zachowując scalenia), wówczas zatwierdzenia do odtworzenia będą
Przepisany wykres zatwierdzenia będzie wyglądał tak:
Tutaj odtworzone scalenie zatwierdzenia m 'pobiera rodziców, którzy wcześniej istnieli na wykresie zatwierdzeń, a mianowicie D (HEAD mistrza) i E (jeden z rodziców oryginalnego scalenia zatwierdzenia m).
Przykład 4
Baza zachowująca scalanie może się mylić w niektórych przypadkach „pustego zatwierdzenia”. Przynajmniej tak jest tylko niektóre starsze wersje git (np. 1.7.8.)
Weź ten wykres zatwierdzania:
Zauważ, że zarówno zatwierdzenie m1, jak i m2 powinny były uwzględniać wszystkie zmiany z B i F.
Jeśli spróbujemy wykonać
git rebase --preserve-merges
H (temat) na D (master), wówczas do odtworzenia zostaną wybrane następujące zatwierdzenia:Zauważ, że zmiany (B, F) zjednoczone w m1 powinny już zostać włączone do D. (Te zmiany powinny już zostać włączone do m2, ponieważ m2 łączy ze sobą dzieci B i F.) Dlatego, koncepcyjnie, odtwarzanie m1 na D prawdopodobnie powinien być albo brakiem operacji, albo utworzyć pusty zatwierdzenie (tzn. Taki, w którym różnica między kolejnymi wersjami jest pusta).
Zamiast tego git może odrzucić próbę odtworzenia m1 na górze D. Możesz otrzymać taki błąd:
Wygląda na to, że zapomniano przekazać flagi gitowi, ale podstawowym problemem jest to, że git nie lubi tworzyć pustych zatwierdzeń.
źródło
git rebase --preserve-merges
jest to znacznie wolniejsze niżrebase
bez--preserve-merges
. Czy to efekt uboczny znalezienia właściwych zobowiązań? Czy można coś zrobić, aby przyspieszyć? (Nawiasem mówiąc… dzięki za bardzo szczegółową odpowiedź!)Git 2.18 (Q2 2018) znacznie poprawi tę
--preserve-merge
opcję, dodając nową opcję.„
git rebase
” Dowiedział się „--rebase-merges
”, aby przeszczepić całą topologię popełnić wykres gdzie indziej .(Uwaga: Git 2.22, drugi kwartał 2019 r. , Przestaje być aktualny
--preserve-merge
, a Git 2.25, pierwszy kwartał 2020 r., Przestaje reklamować go w wynikach „git rebase --help
” )Patrz popełnienia 25cff9f , popełnienia 7543f6f , popełnienia 1131ec9 , popełnienia 7ccdf65 , popełnienia 537e7d6 , popełnienia a9be29c , popełnienia 8f6aed7 , popełnienia 1644c73 , popełnienia d1e8b01 , popełnienia 4c68e7d , popełnienia 9055e40 , popełnienia cb5206e , popełnienia a01c2a5 , popełnienia 2f6b1d1 , popełnienia bf5c057 (25 Maj 2018) autor: Johannes Schindelin (
dscho
) .Zobacz commit f431d73 (25 kwietnia 2018 r.) Autor: Stefan Beller (
stefanbeller
) .Zobacz zatwierdzenie 2429335 (25 kwietnia 2018 r.) Autor: Phillip Wood (
phillipwood
) .(Połączone przez Junio C Hamano -
gitster
- w commit 2c18e6a , 23 maja 2018 r.)git rebase
strona man ma teraz pełną sekcję poświęconą ponownej publikacji historii przy scalaniu .Wyciąg:
Zobacz mały przykład, patrz 1644c73 :
Jaka jest różnica
--preserve-merge
?Commit 8f6aed7 wyjaśnia:
I przez „twoje naprawdę” autor odnosi się do siebie: Johannes Schindelin (
dscho
) , który jest głównym powodem (wraz z kilkoma innymi bohaterami - Hannes, Steffen, Sebastian, ...), że mamy Git For Windows (chociaż w ciągu dnia - 2009 - to nie było łatwe ).Pracuje w firmie Microsoft od września 2015 r. , Co ma sens, biorąc pod uwagę, że Microsoft intensywnie korzysta z Git i potrzebuje jego usług. Trend
ten rozpoczął się w 2013 r. Wraz z TFS . Od tego czasu Microsoft zarządza największym repozytorium Git na świecie ! I od października 2018, Microsoft przejął GitHub .
Możesz zobaczyć, jak Johannes mówi w tym filmie dla Git Merge 2018 w kwietniu 2018 roku.
Tutaj Jonathan mówi o Andreasie Schwabie z Suse.
Niektóre z ich dyskusji można zobaczyć w 2012 roku .
(Skrypt nożyc ogrodowych Git jest wymieniony w tej łatce w zatwierdzeniu 9055e40 )
Git 2.19 (III kwartał 2018 r.) Ulepsza nową
--rebase-merges
opcję, umożliwiając jej działanie--exec
.„
--exec
” Opcja „git rebase --rebase-merges
” umieściła polecenia exec w niewłaściwych miejscach, co zostało poprawione.Zobacz zatwierdzenie 1ace63b (09 sierpnia 2018) i zatwierdzenie f0880f7 (06 sierpnia 2018) przez Johannesa Schindelina (
dscho
) .(Połączone przez Junio C Hamano -
gitster
- w commit 750eb11 , 20 sierpnia 2018)Git 2.22 (drugi kwartał 2019 r.) Naprawia użycie refs / przepisanych / hierarchii do przechowywania stanów pośrednich bazy danych, co z natury sprawia, że hierarchia jest zależna od drzewa roboczego.
Zobacz zatwierdzenie b9317d5 , zatwierdzenie 90d31ff , zatwierdzenie 09e6564 (07 marca 2019) autor: Nguyễn Thái Ngọc Duy (
pclouds
) .(Połączone przez Junio C Hamano -
gitster
- w commit 917f2cd , 09 kwietnia 2019)a9be29c (sekwencer: tworzenie odnośników wygenerowanych przez
label
polecenie worktree-local, 2018-04-25, Git 2.19) dodajerefs/rewritten/
jako przestrzeń odniesienia dla drzewa roboczego.Niestety (moje złe) jest kilka miejsc, które wymagają aktualizacji, aby upewnić się, że to naprawdę działa.
Dzięki Git 2.24 (czwarty kwartał 2019 r.)
git rebase --rebase-merges
Nauczył się prowadzić różne strategie łączenia i przekazywać im opcje specyficzne dla strategii.Zobacz commit 476998d (04 września 2019) autor: Elijah Newren (
newren
) .Zobacz popełnić e1fac53 , popełnić a63f990 , popełnić 5dcdd74 , popełnić e145d99 , popełnić 4e6023b , popełnić f67336d , popełnić a9c7107 , popełnić b8c6f24 , popełnić d51b771 , popełnić c248d32 , popełnić 8c1e240 , popełnić 5efed0e , popełnić 68b54f6 , popełnić 2e7bbac , popełnić 6180b20 , popełnić d5b581f (31 Lip 2019) przezJohannes Schindelin (
dscho
) .(Połączone przez Junio C Hamano -
gitster
- w commit 917a319 , 18 września 2019)W Git 2.25 (Q1 2020) logika używana do rozróżnienia lokalnych referencji lokalnych i repozytorium od siebie jest stała, aby ułatwić scalenie zachowaj.
Zobacz zatwierdzenie f45f88b , zatwierdzenie c72fc40 , zatwierdzenie 8a64881 , zatwierdzenie 7cb8c92 , zatwierdzenie e536b1f (21 października 2019 r.) Autor: SZEDER Gábor (
szeder
) .(Połączone przez Junio C Hamano -
gitster
- w commit db806d7 , 10 listopada 2019)źródło
--preserve-merges
rzeczywistości nie „zachowuje” połączeń, jak chcesz, jest bardzo naiwna. Pozwala to zachować zobowiązania do scalania i ich relacje nadrzędne zatwierdzania, zapewniając jednocześnie elastyczność interaktywnego bazowania. Ta nowa funkcja jest niesamowita i gdyby nie ta dobrze napisana odpowiedź SO, nie wiedziałbym!