„proszę o rebase na master i połączymy twoje żądanie pull request”.
” Czy możesz zgnieść swoje commity razem, abyśmy mieli czystą, odwracalną githistorię?”.
„Czy możesz przepisać wiadomość swojego commita, aby lepiej opisać rozwiązywany przez niego problem i jak go rozwiązuje?”.
takie pytania są często zadawane w pull requests. Zobaczmy, dlaczego sąhistoryczne, jak je wykonać i ich Możliwe problemy.,
Przeredaguj ostatnią wiadomość zatwierdzającą
jednym z najprostszych przepisań historii, jakie możemy zrobić z Gitem, jest zmiana ostatniej wiadomości zatwierdzającej. Załóżmy, że zaraz po dokonaniu commita znajdujesz literówkę w jego opisie, lub znajdujesz lepszy sposób opisania zestawu zmian. Aby dokonać korekcji, Uruchom:
git commit --amend
otworzy Edytor z Ostatnią wiadomością zatwierdzenia, więc możesz go zmodyfikować. Po zapisaniu zostanie utworzony nowy commit z tymi samymi zmianami i nową wiadomością, zastępując commit z poprzednią wiadomością.,
może to być przydatne do dołączania plików, które zapomniałeś śledzić, lub dołączania modyfikacji do plików, które właśnie uruchomiłeś. Aby to zrobić, możesz dodać zmiany i wykonać poprawkę:
git add README.md config/routes.rb git rm notes.txt git commit --amend
oprócz edycji Komunikatu o zatwierdzeniu, nowy commit będzie zawierał zmiany określone za pomocą git add
I git rm
. Możesz także edytować autora. Przykład:
git commit --amend --author="Tute Costa and Dan Croak <[email protected]>"
osiągnięcie odblokowane!, Możesz teraz zmienić ostatni commit swojego repozytorium tak, aby zawierał nowsze zmiany w plikach i/lub poprawiał komunikat commit. Ale nie zaczynaj zmieniać wszystkiego, zanim zrozumiesz ostatnią sekcję tego postu na blogu zatytułowaną „niebezpieczeństwo”.
Przeredaguj inne komunikaty commit
chciałbym teraz o tym porozmawiać, ale musimy wcześniej zrozumieć bardziej ogólne zasady. Zostańcie z nami! Wszystko inne będzie łatwiejsze, gdy przeczytamy o…
interaktywny Rebase
git rebase
ponownie zastosuje commity, jeden po drugim, w kolejności, z bieżącej gałęzi na inną., Akceptuje kilka opcji i parametrów, więc jest to wskazówka do wyjaśnienia góry lodowej, wystarczająca, aby pomostować thegap pomiędzy komentarzami StackOverflow lub GitHub a stronami podręcznika Gita.
interesującą opcją, którą akceptuje, jest--interactive
(-i
w skrócie), która otworzy Edytor z listą commitów, które mają zostać zmienione. Ta lista akceptuje polecenia, umożliwiając użytkownikowi edycję listy przed rozpoczęciem akcji therbase.
zobaczmy przykład.,
Przeredaguj inne commity, weź 2
powiedzmy, że chcę przeredagować każdy z ostatnich 4 commitów tego bloga. Następnie uruchamiamgit rebase -i HEAD~4
I oto co widzę:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls pick 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend # Rebase 8db7e8b..fa20af3 onto 8db7e8b # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
widzimy cztery ostatnie commity, od starszych do nowszych. Zobacz komentarz pod listą commitów? Dobra robota z wyjaśnieniem, git! pick
(p
w skrócie) jest domyślną czynnością. W takim przypadku ponownie zastosuje commit w takim stanie, w jakim jest, bez zmian w jego komentarzach lub wiadomości. Zapisanie (i wykonanie) tego pliku nie spowoduje żadnych zmian w repozytorium.,
jeśli powiem reword
(r
w skrócie) w commicie, który chcę edytować:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls r 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Kiedy zapiszę i zamknę edytor, git będzie wykonywał opisane polecenia, wylądowałem ponownie w edytorze, jakbym zmienił commit 3e7ee36
. Edytuję ten Komunikat, zapisuję i zamykam edytor, a oto wynik:
teraz Caleb mówi w swoim komunikacie commit „Stop all the highlighting”, niezależnie od tego, czy jesteś dzieckiem, czy nie.
osiągnięcie odblokowane! Możesz teraz zmienić wiadomość dowolnego zlecenia., Możesz to zrobić, po prostu upewnij się, że rozumiesz sekcję „niebezpieczeństwo”.
squash commits together
dwa inne polecenia rebase interactive nam oferuje:
-
squash
(s
w skrócie), które łączy commit z poprzednim (theone w linii przed) -
fixup
(f
w skrócie), który działa jak „squash”, ale odrzuca wiadomość tego commita
będziemy kontynuować pracę nad przykładem rebase, nad którym pracowaliśmy., Mieliśmy cztery commity, moje własne dla tego postu na blogu, oraz trzy inne od Caleba, które były związane z jego poprzednim postem na PGP:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls pick 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
powiedzmy, że chcę połączyć commity Caleba ze sobą, ponieważ należą one do tego samego logicznego zestawu zmian, więc możemy git revert
łatwo je znaleźć nie możemy mieć tych zmian w tym repozytorium. Będziemy chcieli zachować pierwszy komunikat commit i zmiażdżyć dwa kolejne commity do poprzedniego., Zmieniam pick
na squash
gdzie jest to właściwe:
pick 07c5abd Introduce OpenPGP and teach basic usage s de9b1eb Fix PostChecker::Post#urls s 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Zapisz i ląduję w edytorze, aby zdecydować o zatwierdzeniu commitów meldedthree (zobacz, jak są one połączone jeden po drugim):
# This is a combination of 3 commits. # The first commit's message is: Introduce OpenPGP and teach basic usage Besides demystifying a relatively complex tool, protocol, and etiquette, this post is intended to help with problems such as the one outlined in this tweet: > Emailed sensitive info to someone with PGP. They replied, with my > original email, all in clear text. They didn't realize it. # This is the 2nd commit message: Fix PostChecker::Post#urls # This is the 3rd commit message: Hey kids, stop all the highlighting # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Author: Caleb Hearth # Date: Tue Sep 2 09:39:07 2014 -0500 # # rebase in progress; onto 71d4789 # You are currently editing a commit while rebasing branch 'tc-git-rebase' on '71d4789'.
decyduję się usunąć trzecią wiadomość zatwierdzającą i dodać bardziej odpowiednią notatkę do drugiej wiadomości zatwierdzającej. Uratuj redaktora, a cztery commity zostały przekształcone w dwa: jeden od Caleba, a potem mój. Dobrze!,
moglibyśmy użyć poleceniafixup
, gdybyśmy widzieli wcześniej, że chcemy zmiany, ale nie komunikat commit trzeciego commita. W takim przypadku polecenia wyglądałyby następująco:
pick 07c5abd Introduce OpenPGP and teach basic usage s de9b1eb Fix PostChecker::Post#urls f 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Po zapisaniu edytor włączyłby już trzecią wiadomość commit:
Save, a wyjścia:
wynik jest taki sam: 2 commity zamiast 4, każdy z jednym, innym wpisem na blogu.
osiągnięcie odblokowane! Możesz teraz scalić commity razem. Zawsze pamiętajcie o niebezpieczeństwie.,
Rebase na szczycie master
rozwidlamy bibliotekę open source, rozpoczynamy pracę nad gałęzią funkcji, a master w projekcie upstream idzie do przodu. Nasza historia wygląda następująco:
A---B---C feature / D---E---F---G upstream/master
opiekun biblioteki pyta o „rebase on top of master”, więc naprawiamy wszelkie mergeconflicts, które mogą pojawić się między obiema gałęziami i zachowujemy nasz zestaw zmian razem.Opiekun chciałby zobaczyć historię w stylu:
A'--B'--C' feature / D---E---F---G upstream/master
chcemy ponownie zastosować nasze commity, jeden po drugim, w kolejności, NA master.,Brzmi jak opis polecenia rebase! Zobaczmy, jakie polecenia wpędziłyby nas w pożądany scenariusz:
osiągnięcie odblokowane! Twoja gałąź funkcji zostanie zastosowana na najnowszym wzorcu oryginalnego widelca.
i tak dojdziemy do…
niebezpieczeństwo: przepisujesz historię
Zobacz --force
w ostatnim git push
polecenie? Oznacza to, że nadpisujemy jej historię., Jest to zawsze bezpieczne w commitach, których nie udostępniamy innym członkom zespołu, lub w oddziałach, które należą do nas (zobacz moje inicjały na przykładzie tego posta na blogu).
ale jeśli wymusisz edycje push, które zostały już udostępnione zespołowi (commity, które istnieją poza moim repozytorium, jak zmiany, które wprowadziłem do commitów PGP, które zostały już udostępnione), gałąź WSZYSTKICH zostanie zsynchronizowana.
przepisywanie historii oznacza rezygnację z istniejących commitów i tworzenie nowych, które mogą być bardzo podobne, ale są inne., Jeśli inni bazują na twoich poprzednich zleceniach, a następnie przepisujesz i wymuszasz zmiany, członkowie Twojego zespołu będą musieli ponownie scalić swoją pracę (jeśli zauważą potencjalną stratę).
w thoughtbot umieszczamy przedrostki naszych gałęzi naszymi Inicjałami, sygnalizując, że te polecenia mogą zostać przepisane, a inne nie powinny dodawać commitów do gałęzi. Po zatwierdzeniu landu do master lub współdzielonej gałęzi nigdy nie przepisujemy ich ponownie.
więc przepisuj historię Gita, pod warunkiem, że przepisane commity istnieją tylko w Twoim repository, lub ty i twój zespół wiecie, że nikt inny nie powinien od nich bazować.,
osiągnięcie odblokowane! Teraz wiesz, jak rebase będąc dobrym obywatelem.