Centralized workflow
Moim zdaniem jest to zaprzeczenie idei, jaka kryje się za Gitem, a jednak jeśli chcemy, możemy w ten sposób pracować. Działa to na podobnej zasadzie jak system SVN, czyli mamy pojedynczy punkt synchronizacji, wspólny dla wszystkich. Niech to będzie nasz branch main (w SVN jest to trunk). Co ważne, nie tworzymy i nie używamy żadnego innego brancha. Czyli każdy z nas ma lokalnego maina i wszystkie zmiany wrzuca do zewnętrznego maina. Proste.
Przy kilku osobach stworzy to trochę problemów, a przy większym projekcie to zwyczajnie wybuchnie. Nie polecam w ten sposób pracować. Można ewentualnie tak robić przy indywidualnej nauce, ale jakikolwiek komercyjny projekt, nawet pisany samodzielnie, powinien posiadać bardziej cywilizowany workflow.
Feature Branch workflow
Tutaj wreszcie możemy wykorzystać jeden z głównych atutów Gita, a więc jego “lekkość” i łatwość przełączania pomiędzy branchami oraz ich synchronizacji. Cała idea polega na tym, że każdy feature posiada własny, dedykowany branch. Dopiero gotowe i działające rozwiązanie zostanie dołączone do głównej gałęzi. A więc nasz main zawsze posiada najbardziej aktualną i działającą (przynajmniej teoretycznie) wersję kodu. Zaletą korzystania z osobnych gałęzi, które w pewnym momencie musimy ze sobą połączyć, jest możliwość tworzenia tzw. Pull Requestów. Często marginalizowane przez programistów mają ogromne znaczenie dla jakości naszego kodu, ilości błędów czy poprawności tworzonych rozwiązań.
Na poniższym obrazku mamy przedstawiony przykładowy schemat takiego workflow. Gałęzie origin/main oraz origin/feature oznaczają tzw. remote branches, czyli te, które znajdują się w zewnętrznym repozytorium. Z kolei feature jest tylko naszym lokalnym tworem, które reprezentuje zewnętrzny origin/feature na naszym komputerze.

Dzięki takiemu podejściu nasz lokalny branch musi się synchronizować tylko z odpowiadającym mu branchem dla danej funkcjonalności. Oczywiście tylko do pewnego momentu, ponieważ w końcu będziemy chcieli te zmiany dołączyć do main, ale to będzie dopiero ostatni krok, do tego poprzedzony wspominanym Pull Requestem. Taki workflow pozwala nam skupić się na poszczególnych funkcjonalnościach, a więc to wymagania biznesowe decydują o istniejących rozgałęzieniach.
Gitflow
Aż chciałoby się zacząć od anglosaskiego “the one and only”. Jest to ewolucja powyższego, też bazująca na poszczególnych feature-branchach, jednak dająca dużo więcej. W zasadzie jest to obecny standard pracy z systemem Git i wiedza o tym, jak działa, powinna być znana wszystkich programistom.
A co takiego rozwija to podejście w stosunku do poprzedniego? No cóż, trochę tego jest:
- main — główna gałąź projektu, to tutaj znajduje się nasz kod produkcyjny
- develop — tutaj znajduje się tzw. kod rozwojowy, który docelowo zostanie zintegrowany z main. To miejsce synchronizacji poszczególnych feature-branchów.
- release — osobna gałąź powstała z develop, nazywana też czasem release-candidate. Nie dodajemy tutaj nowych funkcjonalności, tylko stabilizujemy wersję, dodajemy ewentualnie poprawki błędów i przygotowujemy kod do wdrożenia.
- feature — dedykowana gałąź dla danej funkcjonalności, często zawiera w nazwie numer zadania z naszego systemu zarządzania projektem, np. Jira czy Trello. Ważne, żeby każdy poszczególny feature-branch integrował się tylko z develop, a nie release czy main
- hotfix — specjalna gałąź dedykowana dla błędów w kodzie produkcyjnym. Tworzymy rozgałęzienie bezpośrednio z main i również z nim się integrujemy po naprawie błędu. Taki krok nie uwzględnia żadnych zmian, które znajdują się na gałęziach develop czy release. Oczywiście po zakończeniu pracy nad hotfixem musimy taką zmianą propagować też “w dół”, tak żeby pozostałe branche również wiedziały o wprowadzonej poprawce.
Dzięki takiemu podziałowi i “specjalizacji” poszczególnych gałęzi możemy łatwo kontrolować stan projektu, zarządzań wdrożeniami oraz poprawnie implementować rozwiązania CI/CD w naszych projektach. W tak uporządkowanym repozytorium łatwo też wykorzystywać tagi dla poszczególnych wersji, co może okazać się przydatne.

Grafika inspirowana schematem ze strony: https://www.atlassian.com/pl/git/tutorials/comparing-workflows/gitflow-workflow
Narzędzia do pracy z Gitflow
Na koniec wspomnę jeszcze o tym, że Gitflow jest dostępny jako konkretna komenda Gita. Oczywiście współczesne IDE również wspierają ten standard pracy, ale jeśli korzystamy tylko z konsoli, to również możemy łatwo kontrolować i stosować nasz workflow.
Polecenie git flow init inicjalizuje oczekiwane flow, co pozwala nam łatwo zarządzać i sterować przepływem pracy za pomocą gotowych metod. Możemy oczywiście wybrać, jaki typ gałęzi chcemy obecnie tworzyć (np. feature lub hotfix), czy chcemy rozpocząć, czy zakończyć pracę (start lub finish) oraz oczywiście podać naszą nazwę dla danej gałęzi. Wszystko jest łatwe w nauce i zrozumieniu, więc nie powinniśmy mieć problemu z wykorzystaniem tego narzędzia.
Przykładowe polecenia mogą wyglądać tak:
- git flow feature start feature1234
- git flow feature finish feature1234
- git flow hotfix start important-fix
W IntelliJ wygląda to równie prosto, najpierw musimy zainicjalizować nasze flow:

A następnie wybieramy, jakie polecenia chcemy wykonać:

Podsumowując, Git to świetne narzędzie, nie bez powodu zdobył swoją popularność. Jego atutem jest jego elastyczność. Umożliwia nam wiele, ale nie narzuca tego, jak z niego skorzystamy.
Z drugiej jednak strony zachęca i udostępnia możliwość pracy zgodnie z tzw. Gitflow, które ma wiele korzyści i obecnie jest standardem pracy z tym narzędziem. Dzięki temu możemy pracować efektywniej, szybciej i cały czas mieć kontrolę nad rozwojem i postępem naszego projektu. A z perspektywy programisty jest to po prostu wygodne.