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. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *