git commit —fixup=...
Czasami zdarza się, że zatwierdziłem jakieś zmiany, ale coś tam jednak wymaga poprawy. Pewnie skorzystam z git rebase -i
, tym niemniej po takich poprawkach uporządkowanie commitów wymaga trochę pracy i tu z pomocą przychodzi opcja --fixup
.
Załóżmy, że mam jakieś repozytorium git:
$ git log --oneline
63594c0 (HEAD -> master) Initial
W przykładzie jest tylko jeden commit, ale to nie istotne.
Zaczynam więc standardowo:
$ git switch -c feature-1
$ nano README.md # Tu wpisuję treść mojego README
$ git add README.md
$ git commit -m "Dodano README.md"
W wyniku tych działań mam coś takiego:
$ git log --oneline
87aeca8 (HEAD -> feature-1) Dodano README.md
63594c0 (master) Initial
Powiedzmy, że jednak odkrywam, że w README zrobiłem paskudny błąd ortograficzny:
$ nano README.md # poprawiam wstydliwy błąd
$ git add README.md
$ git commit --amend
Ponowne sprawdzenie logu:
$ git log --oneline
6f3d411 (HEAD -> feature-1) Dodano README.md
63594c0 (master) Initial
Jak widać ostatni commit został przepisany (87aeca8 został zastąpiony przez 6f3d411). Efekt w postaci poprawionego błędu i czystej historii commitów został osiągnięty.
To jest ten prostszy przypadek ale co, jeśli błąd w README.md uświadomię sobie dopiero po jakimś czasie, gdy już zdążyłem dodać inne commity. Np mam taką historię:
$ git log --oneline
6e8a8dd (HEAD -> feature-1) Dodano main.c
6f3d411 Dodano README.md
63594c0 (master) Initial
I dopiero teraz stwierdzam konieczność poprawienia pliku README.md.
Opcja --amend
już nie zadziała i trzeba skorzystać z dobrodziejstw git rebase -i
. “Rebase” pozwoli ponownie przeedytować istniejące commity, choć każdy kto to robił wie, że będzie trochę zabawy.
I tu wracam do wspomnianej opcji --fixup
operacji commit.
Mogę zrobić następującą rzecz:
$ nano README.md # poprawiam (kolejny pewnie) błąd ortograficzny
$ git add README.md
$ git commit --fixup=6f3d411 # wskazuję poprawiany commit
Poprawiany commit, to ten z opisem “Dodano README.md”. Polecenie nie pyta mnie nawet o komentarz i mam następującą historię:
$ git log --oneline
9fadf75 (HEAD -> feature-1) fixup! Dodano README.md
6e8a8dd Dodano main.c
6f3d411 Dodano README.md
63594c0 (master) Initial
I teraz ta fajna część:
$ git rebase -i --autosquash master
Otwiera się edytor umożliwiający ustawienie poleceń odnośnie commitów następujących po master
(commity pojawiają się od najstarszego do najnowszego):
pick 6f3d411 Dodano README.md
fixup 9fadf75 fixup! Dodano README.md
pick 6e8a8dd Dodano main.c
Widać, że “fixup! Dodano README.md” zostało umieszczone zaraz po “Dodano README.md” i ma automatycznie (dzięki opcji --autosquash
) wybrane polecenie fixup
. Po zamknięciu edytora powstaje taka oto historia commitów:
$ git log --oneline
8abcc8e (HEAD -> feature-1) Dodano main.c
3c9672d Dodano README.md
63594c0 (master) Initial
Commity powyżej “63594c0” zostały przepisane, w tym “Dodano README.md” zebrał zmiany, które dodałem w “fixup! Dodano README.md”.
Błędy poprawione, historia czysta. Można robić git merge
.
Kontakt ze mną: @ark_r@mastodon.social