Ulepszyłem swoją historię i chcę wprowadzić do niej zmiany. Problem polega na tym, że mam zatwierdzenie z dwiema niepowiązanymi zmianami, a zatwierdzenie to jest otoczone innymi zmianami w mojej lokalnej (nieprzesuniętej) historii.
Chcę podzielić to zatwierdzenie, zanim go wypchnę, ale większość przewodników, które widzę, ma związek z podzieleniem ostatniego zatwierdzenia lub niezatwierdzonych zmian lokalnych. Czy jest to możliwe, aby zrobić to z zatwierdzeniem, które jest trochę zakopane w historii, bez konieczności „ponownego dokonywania” moich zobowiązań od tego czasu?
Odpowiedzi:
Na stronie podręcznika rebase znajduje się przewodnik do dzielenia zatwierdzeń . Szybkie podsumowanie to:
Wykonaj interaktywną zmianę bazy, w tym zatwierdzenie celu (np.
git rebase -i <commit-to-split>^ branch
) I zaznacz ją do edycji.Kiedy rebase osiągnie to zatwierdzenie, użyj,
git reset HEAD^
aby zresetować do przed zatwierdzeniem, ale nie zmieniaj drzewa roboczego.Stopniowo dodawaj zmiany i zatwierdzaj je, wykonując tyle zatwierdzeń, ile chcesz.
add -p
może być użyteczne dodanie tylko niektórych zmian w danym pliku. Posługiwać sięcommit -c ORIG_HEAD
jeśli chcesz ponownie użyć oryginalnej wiadomości zatwierdzenia dla określonego zatwierdzenia.Jeśli chcesz przetestować to, co popełniasz (dobry pomysł!), Użyj,
git stash
aby ukryć część, której nie popełniłeś (lubstash --keep-index
jeszcze zanim ją wykonasz), przetestuj, a następniegit stash pop
przywróć resztę do drzewa roboczego. Wykonuj zatwierdzenia, dopóki nie wprowadzisz wszystkich modyfikacji, tzn. Nie będziesz mieć czystego drzewa roboczego.Uruchom,
git rebase --continue
aby kontynuować stosowanie zatwierdzeń po podzielonym teraz zatwierdzeniu.źródło
git rebase -i <sha1_of_the_commit_to_split>^ branch
. Igit gui
jest dobrym narzędziem do zadania dzielenia, którego można użyć do dodania różnych części pliku do różnych zatwierdzeń.git add -p
, który może zrobić więcej niżgit gui
może w tym dziale (zwłaszcza edytowanie kawałków, ustawianie wszystkiego, zaczynając od bieżącego kawałka i szukanie kawałków według wyrażenia regularnego).Oto jak to zrobić za pomocą Magit .
Powiedzmy, że ed417ae jest tym, który chcesz zmienić; zawiera dwie niepowiązane zmiany i jest pochowany pod co najmniej jednym zatwierdzeniem. Naciśnij,
ll
aby wyświetlić dziennik i przejdź do ed417ae:Następnie naciśnij,
r
aby otworzyć okienko rebasei
m
zmodyfikować zatwierdzenie w punkcie.Zauważ,
@
że teraz jest zatwierdzenie, które chcesz podzielić - oznacza to, że HEAD jest teraz przy tym zatwierdzeniu:Chcemy przenieść HEAD do nadrzędnego, więc przejdź do nadrzędnego (47e18b3) i naciśnij
x
(magit-reset-quickly
, związany,o
jeśli używaszevil-magit
) i wejdź, aby powiedzieć „tak, miałem na myśli zatwierdzenie w punkcie”. Twój dziennik powinien teraz wyglądać następująco:Teraz wciśnij,
q
aby przejść do normalnego statusu Magit, a następnie użyj zwykłegou
polecenia unstage, aby cofnąć scenę, co nie idzie w pierwszym zatwierdzeniu,c
resztę zatwierdzić jak zwykle, a następnie tages
ic
pominąć to, co wchodzi w drugie zatwierdzenie, a po zakończeniu: naciśnij,r
aby otworzyć wyskakujące okienkoi kolejny,
r
aby kontynuować, i gotowe!ll
teraz pokazuje:źródło
Aby podzielić zatwierdzenie
<commit>
i dodać nowe zatwierdzenie przed tym , i zapisać datę autora<commit>
, - kroki są następujące:Edytuj zatwierdzenie wcześniej
<commit>
Uwaga: być może będzie również konieczna edycja
<commit>
.Cherry pick
<commit>
do indeksuInteraktywnie resetuj niepotrzebne zmiany z indeksu i resetuj działające drzewo
Alternatywnie, po prostu interaktywnie przechowuj niepotrzebne zmiany:
git stash push -p -m "tmp other changes"
Wprowadź inne zmiany (jeśli występują) i utwórz nowy zatwierdzenie
Opcjonalnie powtórz pozycje 2-4, aby dodać więcej pośrednich zatwierdzeń.
Kontynuuj bazowanie
źródło
Istnieje szybsza wersja, jeśli chcesz wyodrębnić zawartość tylko z jednego pliku. Jest szybszy, ponieważ interaktywny rebase nie jest już tak naprawdę interaktywny (i oczywiście jest jeszcze szybszy, jeśli chcesz wyodrębnić z ostatniego zatwierdzenia, to nie musisz wcale go rebase)
the_file
. Closethe_file
. To jedyne wydanie, którego potrzebujesz, cała reszta to tylko polecenia git.Etap usuwania z indeksu:
Przywróć właśnie usunięte linie do pliku bez wpływu na indeks !
„SHA1” to zatwierdzenie, z którego chcesz wyodrębnić linie:
Utwórz drugi, zupełnie nowy zatwierdzenie z zawartością do wyodrębnienia przywróconą przez krok 3:
Nie edytuj, nie zatrzymuj / kontynuuj - akceptuj wszystko:
Oczywiście jeszcze szybciej, gdy zatwierdzenie do wyodrębnienia jest ostatnim zatwierdzeniem:
Jeśli używasz,
magit
wówczas kroki 4, 5 i 6 są pojedynczym działaniem: Zatwierdź, natychmiastowa naprawaźródło
Jeśli jeszcze nie naciskałeś, po prostu użyj
git rebase
. Co więcej, użyjgit rebase -i
do interaktywnego przemieszczania zatwierdzeń. Możesz przesunąć naruszający zatwierdzenie na przód, a następnie podzielić go według własnego uznania i przesunąć łatki do tyłu (w razie potrzeby).źródło