Git: przedzieram się przez gałęzie

System kontroli wersji Git był tematem dwóch niedawnych wpisów na moim blogu: No i Git! Kontrola wersji służy nie tylko programistom oraz Git w Eclipse. W tym odcinku chcę na jakiś czas zamknąć temat. Skoncentruję się na kwestii odgałęzień w kodzie (branches).

Git pozwala na przyjemną i efektywną pracę z branchami. Łatwo je tworzyć, scalać i usuwać. Wczoraj zabrałam się za tworzenie szkieletu mojej konkursowej aplikacji Szafbook i wykorzystałam to jako pretekst do poeksperymentowania z odgałęzieniami.

Ogólny zarys moich działań
  1. Utworzenie nowego brancha w konsoli.
  2. W ramach brancha: przygotowanie szkieletu aplikacji Spring Boot za pomocą serwisu https://start.spring.io/.
  3. Wcielenie zmian z nowego brancha do głównej linii kodu (konsola).
  4. Utworzenie brancha przez interfejs Eclipse.
  5. W ramach brancha: prace mające doprowadzić kod do stanu, w którym się kompiluje.
  6. Wcielenie zmian z nowego brancha do głównej linii kodu (Eclipse).
  7. Ustalenie, dlaczego nie było mi potrzebne słowo rebase.
Konsola

W oparciu o informacje w odpowiednim rozdziale podręcznika, tworzę nową gałąź (o nazwie bootinit):

Powyższe polecenie jest skrótem dla dwóch innych, z których pierwsze tworzy brancha, a drugie mnie do niego przenosi:

Następnie wprowadzam swoje zmiany. W tym wypadku to wrzucenie szkieletu aplikacji webowej do katalogu projektowego oraz usunięcie niepotrzebnych mi już plików.

Po wprowadzeniu zmian polecenie git status zwraca następującą informację):

5
Wynik wywołania polecenie git status w nowej gałęzi po wprowadzeniu zmian

Chcę śledzić wszystkie te zmiany i chcę je uwzględnić w kolejnym commicie, dlatego dodaję wszystko:

Alternatywnie mogłabym zaznaczyć poszczególne zmienione i dodane pliki poleceniem git add <plik>, a usunięte pliki poleceniem git rm <plik>.

Na tym etapie postanawiam wysłać swoje zmiany do repozytorium:

Załóżmy, że moje prace w gałęzi bootinit osiągnęły taki poziom dojrzałości, że chcę scalić je z główną gałęzią kodu (master).

W tym celu muszę przejść do gałęzi, do której mam wrzucić zmiany i tam wywołać polecenie merge.

8
Merge. Kolory bardzo przyjemne

Jeśli gałąź nie będzie mi już potrzebna, mogę ją usunąć:

I już.

Eclipse

Teraz przerzucam się na pracę w środowisku Eclipse. Na początku importuję istniejący projekt z repozytorium Git.

W Eclipse narzędzia związane z kontrolą wersji znajdują się w menu kontekstowym projektu, w zakładce Team.

Kontrola wersji w Eclipse
Kontrola wersji w Eclipse

Tworzę nową gałąź korzystając z opcji wyświetlonej na powyższym obrazku: Team->Switch To->New Branch

Nazwa aktualnej gałęzi jest wyświetlana przy nazwie projektu.

Nazwa aktualnej gałęzi jest wyświetlana przy nazwie projektu.
Wersja projektu w gałęzi eclipsebranchtest

Dalej wprowadzam swoje zmiany. Przed wszystkim chcę doprowadzić aplikację do stanu, w którym kompiluje się bez błędów (za pomocą Mavena) i zawiera chociaż jeden (bezsensowny na razie) test jednostkowy.

Jedna ze zmian to oznaczenie części plików w katalogu projektu jako ignorowanych – mam na myśli pliki stanowiące wynik kompilacji. W systemie kontroli wersji chcę trzymać tylko źródła.  W menu mamy odpowiednią opcję Ignore, która jest powiązana ze zrozumiałym dla Gita plikiem .gitignore.

Praca w ramach jednej gałęzi została już umówiona w poprzednim wpisie. Załóżmy teraz, że wszystkie zmiany zostały wysłane do repozytorium, a prace w ramach nowej gałęzi eclipsebranchtest zostały zakończone.

Podobnie jak w przypadku pracy w konsoli, najpierw muszę przejść do gałęzi, do której chcę wcielić zmiany (w tym wypadku to master). Tam z menu Team wybieram opcję Merge. Pojawi się okienko przedstawione na poniższym obrazku.

Wybór gałęzi do scalenia
Wybór gałęzi do scalenia. Wybieram eclipsebranchtest

No i to by było na tyle! Mogę jeszcze usunąć niepotrzebną już gałąź w Team->Advanced->Delete Branch.

Rebase

Spodziewałam się, że podczas zabawy z branchami dotrę do momentu, w którym potrzebne stanie się słówko rebase, ale tak się nie stało. Nie pozostało mi nic innego jak RTFM. Oto, co ustaliłam (w wielkim skrócie):

Scalać można albo przy użyciu merge, albo rebase.  W zależności od dokonanego wyboru, inaczej będzie wyglądała historia zmian w projekcie. Po merge historia będzie dokładnie odwzorowywała to, co się działo – wszystkie rozgałęzienia i powroty. Dla odmiany rebase pozwala nieco przepisać historię, w taki sposób, że – mimo pracy w odgałęzieniach – wygląda ona na liniową. Nie jest to prawda historyczna, ale ta forma może okazać się znacznie bardziej czytelna.

[edit: popełniłam jeszcze jeden wpis na temat rebase]

PS.

Wrócę z tematem Gita, jak dorobię się pierwszego poważnego konfliktu w kodzie.

Komentarze

6 myśli nt. „Git: przedzieram się przez gałęzie”

  1. Faktycznie, fajne wprowadzenie. Jedna uwaga: rebase przydaje się też do innych rzeczy. Na przykład: błędną commit message (i nie tylko) można poprawić przez git commit –amend, ale co, jak pomyliliśmy się pięć commitów temu? Albo chcemy zamienić dwa commity kolejnością? Albo “scalić” kilka commitów w jeden? Może i to są nieco bardziej zaawansowane rzeczy, ale może warto wspomnieć, że rebase to wszystko umie. (Oczywiście, o ile nie było wcześniej push do zdalnego repozytorium, bo wtedy będzie sieczka!)

  2. Używanie rebase dużo ułatwia w przypadku pracy w zespołach. Zmiany w repo stają się czytelniejsze. Łatwiej jest pracować na gałęziach przez dłuższy okres czasu. Przy mergach trzeba mocno się napracować, żeby aktualizować gałęzie do mastera.

    Warto zainteresować się rebase [-i | –interactive], super funkcjonalność, ale nie należy też przesadzać z łączeniem commitów.

    No ale jak pracujesz samodzielnie na repo to nie znajdziesz aż tylu plusów.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *