Git – wersja 2.22 – przegląd nowości

W dzisiejszym wpisie przedstawię trzy nowe opcje, który doszły w Git, w wersji 2.22. Zmian w tej wersji doszło więcej, ale te moim zdaniem są najciekawsze.
Rebase merges, interactively
Załóżmy, że mamy taką sytuację:

Mamy branch master, od którego w pewnym momencie zrobiono branch feature. Na branchu feature idzie praca, powstają nowe commity oraz dodatkowo był zrobiony jeszcze kolejny branch, który został scalony z feature (widać dodatkowe wybrzuszenie 🙂 ). Na masterze oczywiście również ktoś pracuje i powstają nowe commity.
Prawie zakończyliśmy nasze zadanie. Chcemy zrobić tak:
- Usunąć ostatni commit.
- Zmienić commit message innego commita.
- Zrobić rebase brancha feature do master z zachowaniem obecnej struktury commitów, czyli, żeby na grafie było widać dodatkowe wybrzuszenie 🙂
Chcemy osiągnąć coś takiego:

Do tej pory aby to zrobić trzeba było wykonać dwie operacje:
1. git rebase -i --preserve-merges
2. git rebase master
Oba polecenia wykonujemy na branchu feature. Pierwsze robi rebase w trybie interaktywnym. W nim możemy usuwać commit, zmieniać commit message i jeszcze parę innych rzeczy. Musimy pamiętać o opcji --preserve-merges
, aby zachować merge commity i wygląd naszego brancha. Bez tej opcji commity zostaną ustawione w linii prostej.
Po tej operacji wykonujemy standardowy rebase i już gotowe 🙂
Od wersji 2.22 można to zrobić już jednym poleceniem:
git rebase -i --rebase-merges master
To polecenie wykona Nam powyższe dwie rzeczy, które opisałem wcześniej.
Poza tym opcja --preserve-merges
została uznana za przestarzałą (deprecated) i w dokumentacji Git jest napisane, aby zamiast tego używać --rebase-merges
.
Create branches from merge bases
Drugą ciekawą opcją, która doszła w wersji 2.22 jest możliwość szybkiego tworzenia nowego brancha z commita, z którego wystartowaliśmy obecny branch.
Mamy sytuację taką, że chcemy stworzyć nowego brancha, ale chcemy go zacząć w tym samym miejscu co obecny branch, czyli chcemy zacząć od tego samego commita. Patrząc na sytuację z poprzedniego akapitu, będzie to commit zaznaczony na czerwono.

W przypadku branchy na którym zrobiliśmy mało commitów nie będzie trudno znaleźć commita startowego. W przypadku większych branchy może to być już trochę kłopotliwe.
Można również użyć polecenia merge-base
np.:
git merge-base master feature
To nam zwróci ID commita, z którego rozpoczęliśmy nasz feature branch. Tak dokładniej to polecenie jest do tego, aby zwróciło nam wspólnego przodka tych dwóch podanych branchy. Następnie musimy skopiować to ID i stworzyć nowy branch.
Od Gita w wersji 2.22 można to zrobić od razu jednym poleceniem:
$ git branch my-new-feature feature...master
Albo tak:
$ git checkout -b my-new_feature feature...master
Nie trzeba ręcznie szukać, nie trzeba nic kopiować. Branch zostanie od razu stworzony z commita, który jest wspólnym przodkiem obu podanych branchy.
Nadpisywanie zmian przez git checkout
W tym akapicie opiszę nową opcję dla polecenia git checkout
. Nie chodzi mi o zmianę branchy. To polecenie ma kilka różnych zastosowań. Aktualnie chcę odnieść się do jego zastosowania do plików i katalogów w naszym repozytorium. Opisywałem w poście git checkout – operacje na plikach. Jeśli nie wiesz do czego służy w kontekście z plikami, to najpierw się z nim zapoznaj.
Przeanalizujmy taką sytuację:
1. git checkout feature
2. git checkout master -- dir/
Jesteśmy na branchu feature i zrobiliśmy zmiany w plikach w katalogu dir. Jednak chcemy przywrócić katalog dir do stanu w jakim był zanim zaczęliśmy tam cokolwiek zmieniać. Dokonamy tego właśnie poleceniem nr 2, ale…
Co się stanie z nowymi plikami w katalogu, które powstały dopiero na branchu feature?
Nic, one zostaną nie zmienione. Z mastera zostaną tak jakby skopiowane wszystkie pliki znajdujące się w katalogu dir, ale nic stamtąd innego nie zostanie usunięte. Takie jest domyślne zachowanie.
W nowej wersji doszła opcja --no-overlay
. Czyli nasze polecenie będzie wyglądało tak:
git checkout --no-overlay master -- dir
Po jego wykonaniu zawartość katalogu dir będzie wyglądał dokładnie tak samo jak na branchu master. Pliki z mastera zostaną dodane, a te których tam nie ma usunięte.
Podsumowanie
W tym poście opisałem 3 nowości – moim zdaniem najciekawsze – które pojawiły się w najnowszej wersji Gita oznaczonej numerem 2.22. Jeśli chcesz wiedzieć co więcej zmieniło się w nowej wersji to zajrzyj na blog GitHuba, link jest poniżej.
Zródła:
https://git-scm.com/docs/git-rebase
https://github.blog/2019-06-07-highlights-from-git-2-22
3 Komentarze
marbel82 · 24 czerwca 2019 o 9 h 59 min
Dzięki, przyjemnie się czytało 🙂
Pytanko, czy w poleceniu git branch my-new-feature feature…master kolejność branchy jest istotna?
Masz jakiś sposób na zapamiętanie, w jakiej kolejności wpisuje się branche w poleceniach, w których można określić zakres, z dwiema kropkami .. i z trzema … – log, diff, merge-base, rev-list?
Tomasz Prasołek · 24 czerwca 2019 o 10 h 30 min
W tym przypadku kolejność branchy nie ma znaczenia.
Co do kolejności wpisywania branchy w poleceniach z dwoma lub trzema kropkami to nie mam sposobu na zapamiętanie tego, bo nie korzystam z takich poleceń ☺ Może kiedyś raz z tego skorzystałem jak się o tym dowiedziałem ☺
Tomasz Prasołek · 24 czerwca 2019 o 10 h 39 min
Chociaż przypomniało mi się, że jak pisałem tego posta to widziałem fajne rysunki pokazujące działanie tych poleceń z kropkami, tutaj np.: https://stackoverflow.com/questions/462974/what-are-the-differences-between-double-dot-and-triple-dot-in-git-com