Weźmy następujący przypadek:
Mam trochę pracy w gałęzi tematycznej i teraz jestem gotowy do powrotu do mastera:
* eb3b733 3 [master] [origin/master]
| * b62cae6 2 [topic]
|/
* 38abeae 1
Wykonuję scalanie z mastera, rozwiązuję konflikty i mam:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | eb3b733 3 [origin/master]
|/
* 38abeae 1
Teraz scalanie zajęło mi trochę czasu, więc ponownie pobieram i zauważam, że zdalna gałąź główna ma nowe zmiany:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
| | * e7affba 4 [origin/master]
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Jeśli spróbuję `` git rebase origin / master '' z poziomu głównego, jestem zmuszony ponownie rozwiązać wszystkie konflikty, a także stracę zatwierdzenie scalania:
* d4de423 2 [master]
* e7affba 4 [origin/master]
* eb3b733 3
| * b62cae6 2 [topic]
|/
* 38abeae 1
Czy istnieje czysty sposób na zmianę bazy zatwierdzenia scalenia, aby otrzymać historię taką jak ta, którą pokazuję poniżej?
* 51984c7 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | e7affba 4 [origin/master]
* | eb3b733 3
|/
* 38abeae 1
git
merge
rebase
git-rebase
git-rewrite-history
jipumarino
źródło
źródło
git rebase --preserve-merges origin/master
git config --global pull.rebase preserve
aby zawsze zachować fuzję, zobowiązuje się podczas rebasegit --rebase-merges
ostatecznie zastąpi starygit --preserve-merges
. Zobacz, co dokładnie robi Git „rebase --preserve-merges
” (i dlaczego?)--preserve-merges
jest przestarzałe. Użyjgit rebase --rebase-merges origin/master
Odpowiedzi:
Istnieją dwie opcje.
Jednym z nich jest wykonanie interaktywnej rebase i edytowanie zatwierdzenia scalania, ponowne ręczne scalenie i kontynuowanie rebase.
Innym jest użycie
--rebase-merges
opcji ongit rebase
, która jest opisana w następujący sposób z podręcznika: „Domyślnie rebase po prostu usuwa polecenia scalające z listy zadań do wykonania i umieszcza zatwierdzone zmiany w pojedynczej, liniowej gałęzi. Z --rebase- scalenia, rebase spróbuje zamiast tego zachować strukturę rozgałęzień w zatwierdzeniach, które mają zostać zmienione, poprzez odtworzenie zatwierdzeń scalających. Wszelkie rozwiązane konflikty scalania lub ręczne zmiany w tych zatwierdzeniach scalających będą musiały zostać rozwiązane / ponownie zastosowane ręcznie. "źródło
Ok, to stare pytanie i już zaakceptowałem odpowiedź
@siride
, ale ta odpowiedź w moim przypadku nie była wystarczająca, ponieważ--preserve-merges
zmusza cię do rozwiązania wszystkich konfliktów po raz drugi. Moje rozwiązanie oparte na pomyśle,@Tobi B
ale z dokładnymi poleceniami krok po krokuWięc zaczniemy od takiego stanu na podstawie przykładu w pytaniu:
Zauważ, że mamy 2 commits ahead master, więc wybór cherry nie zadziała.
Przede wszystkim stwórzmy poprawną historię, której chcemy:
Używamy,
--preserve-merges
aby zapisać nasze zobowiązanie do łączenia w historii. Używamy--strategy=ours
ignorować wszelkie konflikty scalania, bo nie dbam o to, co będzie w treść tej seryjnej commit, musimy tylko teraz miłą historię.Historia będzie wyglądać tak (pomijając mistrza):
Uzyskajmy teraz poprawny indeks.
W tym miejscu mogą pojawić się dodatkowe konflikty przy scalaniu, ale byłyby to tylko konflikty z plików zmienionych między
8101fe3
af5a7ca8
, ale nie obejmują już rozwiązanych konfliktów ztopic
Historia będzie wyglądać następująco (pomijając poprawną historię):
Ostatnim etapem jest połączenie naszej gałęzi z poprawną historią i gałęzią z odpowiednim indeksem
Używamy
reset --soft
do resetowania naszej gałęzi (i historii) do poprawnej historii, ale pozostawiamy indeks i drzewo robocze bez zmian. Następnie używamycommit --amend
do przepisania naszego zatwierdzenia merge, które miało nieprawidłowy indeks, z naszym dobrym indeksem z master.W końcu będziemy mieli taki stan (zwróć uwagę na inny identyfikator top commit):
źródło
git commit --amend
dodaje zmiany do ostatniego zatwierdzenia (HEAD, w tym przypadku zatwierdzenia scalającego). Ponieważ zmienia się zawartość zatwierdzenia, skrót jest aktualizowany.Biorąc pod uwagę, że właśnie straciłem dzień, próbując to rozgryźć i faktycznie znalazłem rozwiązanie z pomocą współpracownika, pomyślałem, że powinienem się przyłączyć.
Mamy dużą bazę kodu i mamy do czynienia z 2 gałęziami, które są jednocześnie mocno modyfikowane. Istnieje gałąź główna i gałąź drugorzędna, jeśli tak jest.
Podczas scalania gałęzi dodatkowej z gałęzią główną, praca jest kontynuowana w gałęzi głównej i zanim skończę, nie mogę przesłać zmian, ponieważ są one niezgodne.
Dlatego muszę „zmienić bazę” mojego „scalenia”.
Tak to w końcu zrobiliśmy:
1) zanotuj SHA. np .: c4a924d458ea0629c0d694f1b9e9576a3ecf506b
2) Utwórz odpowiednią historię, ale to przerwie scalanie.
3) zanotuj SHA. np .: 29dd8101d78
4) Teraz zresetuj do miejsca, w którym byłeś wcześniej
5) Teraz połącz aktualny master z gałęzią roboczą
6) Teraz, gdy masz już właściwe pliki, ale złą historię, uzyskaj odpowiednią historię na szczycie swojej zmiany za pomocą:
7) A następnie - popraw wyniki w oryginalnym zatwierdzeniu scalania
Voila!
źródło
Wygląda na to, że chcesz usunąć swoje pierwsze scalenie. Możesz postępować zgodnie z następującą procedurą:
To dałoby ci to, czego chcesz.
źródło
źródło