Chciałbym zmienić bazę do konkretnego zatwierdzenia, a nie do HEAD z innej gałęzi:
A --- B --- C master
\
\-- D topic
do
A --- B --- C master
\
\-- D topic
zamiast
A --- B --- C master
\
\-- D topic
Jak mogę to osiągnąć?
git
version-control
rebase
git-rebase
Ondra Žižka
źródło
źródło
git checkout B
przed biegiemgit rebase
?rebase
polecenia.Odpowiedzi:
Możesz uniknąć używania parametru --onto, tworząc tymczasową gałąź na zatwierdzonym zatwierdzeniu, a następnie używając rebase w jego prostej postaci:
źródło
git rebase temp
(kiedy na grupie ) poddaje się z komunikatem „Obecne grupy branżowe są aktualne”.git rebase --onto <target> <from> <to>
, aby można było określić zatwierdzenie <from>.Możesz nawet podejść bezpośrednio:
źródło
topic
icommitB
.It works by going to the common ancestor of the two branches (the one you’re on and the one you’re rebasing onto), getting the diff introduced by each commit of the branch you’re on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn.
spróbowałem ponownie teraz i wydawało się, że działa dobrze.m > n
.Użyj opcji „na”:
źródło
D
iD^
czy będzie hashem ostatniego i przedostatniego zatwierdzenia „topic”?git rebase --onto <new-parent> <old-parent>
. Zobacz Ustawianie wskaźnika git parent na innego rodzica . W twoim przypadku <new-parent> to B, a <old-parent> to A.git rebase --onto <commit-ID> master
git rebase --onto master <commit-ID-of-old-parent>
i dla OPgit rebase --onto B A
.Komentarz jsz powyżej uratował mi mnóstwo bólu, więc oto oparty na nim przepis krok po kroku, którego używałem do zmiany bazy / przeniesienia dowolnego zatwierdzenia na inne zatwierdzenie:
git rebase --onto <new parent> <old parent>
W powyższym przykładzie jest to tak proste, jak:
źródło
git rebase --onto B master
, zobacz moją odpowiedź, aby uzyskać dokładniejsze wyjaśnienie.Rozwiązanie tematu
Prawidłowym poleceniem odpowiadającym na wysłane pytanie może być dowolne z poniższych (zakładając, że gałąź
topic
jest już wyewidencjonowana):Jeśli
topic
nie jest wyrejestrowany, po prostu dodajesztopic
do polecenia (z wyjątkiem ostatniego) w następujący sposób:Alternatywnie, najpierw sprawdź oddział z:
Zmień wartość dowolnego ciągu zatwierdzeń na zatwierdzenie docelowe
Podstawowa forma polecenia, którego potrzebujemy, zaczerpnięta z dokumentacji, to:
<Branch>
jest opcjonalna i wszystko, co robi, to sprawdzenie określonej gałęzi przed wykonaniem reszty polecenia. Jeśli już wyewidencjonowałeś gałąź, którą chcesz przestawić, nie potrzebujesz tego. Zauważ, że musisz określić<Upstream>
, aby określić, w<Branch>
przeciwnym razie git pomyśli, że określasz<Upstream>
.<Target>
jest zatwierdzeniem, do którego dołączymy nasz ciąg zatwierdzeń. Podając nazwę gałęzi, po prostu określasz zatwierdzenie głowy tej gałęzi.<Target>
może być dowolnym zatwierdzeniem, które nie będzie zawarte w ciągu przenoszonych zatwierdzeń. Na przykład:Aby przenieść całą gałąź funkcji, nie można wybrać
X
,Y
,Z
lubfeature
gdy<Target>
od tych, wszystkie są rewizje wewnątrz grupy są przenoszone.<Upstream>
jest wyjątkowy, ponieważ może oznaczać dwie różne rzeczy. Jeśli jest to zatwierdzenie, które jest przodkiem wyewidencjonowanej gałęzi, wówczas służy jako punkt odcięcia. W przykładzie I, pod warunkiem, byłoby to wszystko, co jest nieC
,D
albomaster
. Wszystkie zatwierdzenia po<Upstream>
do głowy wyrejestrowanej gałęzi są tymi, które zostaną przeniesione.Jednakże, jeśli
<Upstream>
nie jest przodkiem, to git tworzy kopię zapasową łańcucha od określonego zatwierdzenia, aż znajdzie wspólnego przodka z wyewidencjonowaną gałęzią (i przerywa, jeśli nie może go znaleźć). W naszym przypadku,<Upstream>
zB
,C
,D
czymaster
będzie w ogóle wynik popełnićB
służąc jako punkt przecięcia.<Upstream>
jest sam w sobie poleceniem opcjonalnym i jeśli nie jest określone, to git sprawdza rodzica wyewidencjonowanej gałęzi, co jest odpowiednikiem wprowadzeniamaster
.Teraz, gdy git wybrał zatwierdzenia, które będzie wycinał i przesuwał, stosuje je w kolejności
<Target>
, pomijając te, które zostały już zastosowane do celu.Ciekawe przykłady i wyniki
Korzystając z tego punktu wyjścia:
git rebase --onto D A feature
Zastosuje zobowiązuje
B
,C
,X
,Y
,Z
aby popełnićD
i skończyć omijającB
aC
ponieważ już zostały zastosowane.git rebase --onto C X feature
Zastosuje zatwierdzenia
Y
iZ
zatwierdzenieC
, skutecznie usuwając zatwierdzenieX
źródło
Prostszym rozwiązaniem jest
git rebase <SHA1 of B> topic
. Działa to niezależnie od tego, gdzie jesteśHEAD
.Możemy potwierdzić to zachowanie z dokumentu git rebase
Możesz się zastanawiać, co się stanie, jeśli wspomnę o SHA1
topic
w powyższym poleceniu?git rebase <SHA1 of B> <SHA1 of topic>
To również zadziała, ale rebase nie
Topic
wskaże wtedy nowej gałęzi tak utworzonej iHEAD
będzie w stanie odłączonym. Z tego miejsca musisz ręcznie usunąć stareTopic
i utworzyć nowe odniesienie do gałęzi w nowej gałęzi utworzonej przez rebase.źródło
Użyłem mieszanki opisanych powyżej rozwiązań:
O wiele łatwiej było mi to przeczytać i zrozumieć. Przyjęte rozwiązanie doprowadziło mnie do konfliktu scalania (zbyt leniwego, by naprawić go ręcznie):
źródło
Ponieważ zmiana bazy jest tak fundamentalna, oto rozwinięcie odpowiedzi Nestora Milyaeva . Łącząc JSZ użytkownika i Simon Południowej komentarze z odpowiedzią Adama Dymitruk za daje tej komendy, który pracuje na
topic
oddziale, niezależnie od tego, czy gałązki zmaster
oddziału popełnićA
alboC
:Zauważ, że ostatni argument jest wymagany (w przeciwnym razie przewija twoją gałąź do zatwierdzenia
B
).Przykłady:
Więc ostatnie polecenie jest tym, którego zwykle używam.
źródło
Jest inny sposób, aby to zrobić lub jeśli chcesz wrócić do więcej niż jednego zatwierdzenia.
Oto przykład, aby wrócić do
n
liczby zatwierdzeń:Ze względu na to pytanie można to również zrobić:
Polecenie działa idealnie na
git version 2.7.4
. Nie testowałem tego na żadnej innej wersji.źródło