Polecenie rebase ma kilka niesamowitych opcji dostępnych w swoim --interactive
(lub -i
) trybie, a jedną z najczęściej używanych jest możliwość zgniatania zatwierdzeń. Robi to mniejsze commity i łączy je w większe, co może być przydatne, jeśli kończysz dzień pracy lub po prostu chcesz inaczej spakować zmiany. Omówimy, jak możesz to łatwo zrobić.
Jedna uwaga: rób to tylko w przypadku zatwierdzeń, które nie zostały wypchnięte do zewnętrznego repozytorium. Jeśli inni oparli pracę na zatwierdzeniach, które zamierzasz usunąć, może wystąpić wiele konfliktów. Po prostu nie przepisuj swojej historii, jeśli została udostępniona innym.
Powiedzmy, że właśnie wykonałeś kilka małych zatwierdzeń i chcesz zrobić z nich jedno większe zatwierdzenie. Obecnie historia naszego repozytorium wygląda następująco:
Ostatnie 4 zatwierdzenia byłyby dużo szczęśliwsze, gdyby zostały połączone razem, więc zróbmy to poprzez interaktywne ponowne bazowanie:
$ git rebase -i HEAD~4
pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.
# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Tak więc wydarzyło się tutaj kilka rzeczy. Po pierwsze, powiedziałem Gitowi, że chcę zmienić bazę przy użyciu ostatnich czterech zatwierdzeń, z których HEAD jest z HEAD ~ 4. Git umieścił mnie teraz w edytorze z powyższym tekstem i małym wyjaśnieniem, co można zrobić. Na tym ekranie dostępnych jest wiele opcji, ale teraz zamierzamy zgnieść wszystko do jednego zatwierdzenia. Tak więc zmiana pierwszych czterech wierszy pliku na to załatwi sprawę:
pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.
Zasadniczo mówi to Gitowi, aby połączył wszystkie cztery zatwierdzenia w pierwszym zatwierdzeniu na liście. Po wykonaniu tej czynności i zapisaniu pojawi się inny edytor z następującymi elementami:
# This is a combination of 4 commits.
# The first commit's message is:
Adding license
# This is the 2nd commit message:
Moving license into its own file
# This is the 3rd commit message:
Jekyll has become self-aware.
# This is the 4th commit message:
Changed the tagline in the binary, too.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i nor -o; assuming --only paths...
# Not currently on any branch.
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: LICENSE
# modified: README.textile
# modified: Rakefile
# modified: bin/jekyll
#
Ponieważ łączymy tak wiele zatwierdzeń, Git pozwala modyfikować komunikat nowego zatwierdzenia w oparciu o resztę zatwierdzeń zaangażowanych w proces. Edytuj wiadomość według własnego uznania, a następnie zapisz i zakończ. Gdy to zrobisz, twoje zatwierdzenia zostały pomyślnie zmiażdżone!
Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
4 files changed, 27 insertions(+), 30 deletions(-)
create mode 100644 LICENSE
Successfully rebased and updated refs/heads/master.
A jeśli ponownie spojrzymy na historię…
Jak dotąd było to stosunkowo bezbolesne. Jeśli napotkasz konflikty podczas rebase, zwykle są one dość łatwe do rozwiązania, a Git prowadzi cię przez jak najwięcej. Podstawą tego jest naprawienie konfliktu, git add
pliku, a następnie git rebase --continue
wznowienie procesu. Oczywiście, git rebase --abort
jeśli chcesz, powrócisz do poprzedniego stanu. Jeśli z jakiegoś powodu straciłeś zatwierdzenie w rebase, możesz użyć reflog, aby je odzyskać.
Szczegóły można znaleźć pod tym linkiem .