Rozdział 5 z 5

Kurs Git: Gitflow czy trunk-based, wybór modelu gałęzi

zweryfikowano 7 września 2026 · 7 min

Szybka odpowiedź

Trunk-based development utrzymuje jedną stałą gałąź i gałęzie żyjące po kilka godzin: to model domyślny dla aplikacji webowej wdrażanej często. Gitflow dodaje gałąź develop i gałęzie wersji: pozostaje sensowny przy oprogramowaniu wydawanym w numerowanych wersjach lub utrzymywanym w kilku wersjach naraz. Sam jego autor od 2020 roku odradza narzucanie go zespołowi pracującemu w continuous delivery.

Git nie narzuca żadnej organizacji pracy. Daje ci gałęzie opisane w poprzednim rozdziale, a ty decydujesz, które z nich istnieją, kto je tworzy i kiedy się scalają. Ten wybór nazywa się modelem gałęzi i dzielą między siebie ten teren dwie duże rodziny: Gitflow i trunk-based development. Ten rozdział pokazuje oba, z prawdziwymi komendami, i wyjaśnia, w jakim kontekście każdy z nich ma sens.

Czym stał się Gitflow

Gitflow opisał Vincent Driessen w styczniu 2010 roku, w artykule zatytułowanym A successful Git branching model. Model przyjął się na tyle szeroko, że dla całego pokolenia programistów stał się domyślnym odruchem.

5 marca 2020 roku autor dopisał sprostowanie na początku własnego artykułu. Warto je przeczytać, zanim sięgniesz po ten model: zespołowi, który wydaje w trybie continuous delivery, Driessen wprost zaleca coś znacznie prostszego, w stylu GitHub Flow, zamiast wciskania Gitflow na siłę. Zaznacza przy tym, że Gitflow zachowuje pełny sens przy oprogramowaniu wydawanym w numerowanych wersjach albo takim, w którym kilka wersji musi być utrzymywanych na produkcji jednocześnie.

Inaczej mówiąc, pytanie nie brzmi „czy Gitflow jest dobry, czy zły”, tylko „co wydaję i w jakim rytmie”.

Trunk-based development

Zasada mieści się w jednym zdaniu: jedna długo żyjąca gałąź, main, do której wszyscy bardzo często wrzucają swoją pracę, przez gałęzie o bardzo krótkim czasie życia.

Gałąź żyje kilka godzin, jeden dzień, rzadko dłużej. Scalasz ją, gdy tylko praca jest spójna, nawet jeśli funkcjonalność nie jest skończona: to, czego użytkownicy nie powinni jeszcze widzieć, chowasz za flagą funkcjonalności (feature flag), zamiast przetrzymywać na gałęzi. main jest stale gotowy do wdrożenia, a gwarantem tej właściwości jest continuous integration.

bash
# 1. start z najnowszej wersji main
git switch main
git pull --rebase

# 2. krótka gałąź, na jedną rzecz
git switch -c fix/calcul-prix

# 3. praca, commit
git commit -am "Corrige le calcul du prix TTC"

# 4. publikacja i otwarcie pull requesta
git push -u origin fix/calcul-prix

# 5. po review i zielonym CI scalenie do main
git switch main
git merge --no-ff -m "Fusionne fix/calcul-prix" fix/calcul-prix
git branch -d fix/calcul-prix
Sortie réelle · merge --no-ff puis git log --graph
Merge made by the 'ort' strategy.
 app.js | 1 +
 1 file changed, 1 insertion(+)
Deleted branch fix/calcul-prix (was 711bcbc).

*   d7cdba6 Fusionne fix/calcul-prix
|  
| * 711bcbc Corrige le calcul du prix TTC
|/  
* 5b45117 Ajoute app.js
* 38b7dc5 Ajoute la doc

Opcja --no-ff wymusza commit scalenia nawet wtedy, gdy wystarczyłoby zwykłe przewinięcie. Historia pokazuje wtedy jawnie, że gałąź istniała i co zawierała. Bez -m Git otwiera edytor skonfigurowany w rozdziale 1 z gotowym komunikatem. W praktyce tę pracę wykonują za Ciebie przyciski Merge pull request w GitHubie i Merge request w GitLabie.

Wersje oznaczasz tagami na main, bez osobnej gałęzi:

bash
git tag -a v1.0.0 -m "Première version publique"
git push origin v1.0.0
Sortie réelle · git show v1.0.0
tag v1.0.0
Tagger: Damien Flandrin <dam@example.com>
Date:   Wed Sep 2 10:00:00 2026 +0000

Première version publique

Zawsze wybieraj tag adnotowany (-a z komunikatem) zamiast lekkiego: zapisuje autora, datę i komentarz. I nie zapominaj o komunikacie: bez -m Git otwiera edytor, a w środowisku automatycznym komenda kończy się błędem.

Sortie réelle · git tag -a sans message, sans éditeur disponible
error: there was a problem with the editor 'false'
Please supply the message using either -m or -F option.

Gitflow

Gitflow dodaje drugą stałą gałąź i trzy rodziny gałęzi tymczasowych.

Schemat modelu Gitflow: gałąź master niesie wersje v0.1, v0.2 i v1.0, gałąź hotfix poprawia produkcję, gałąź develop przyjmuje gałęzie feature, a gałąź release przygotowuje wydanie.
Model opisany przez Vincenta Driessena w 2010 roku, z nazwą master używaną wtedy dla gałęzi produkcyjnej.
Gałąź Czas życia Rola
main stała to, co jest na produkcji, jeden tag na wersję
develop stała integracja bieżących prac
feature/* tymczasowa jedna funkcjonalność, wychodzi z develop i tam wraca
release/* tymczasowa stabilizacja wersji, wychodzi z develop, trafia do main i develop
hotfix/* tymczasowa pilna poprawka, wychodzi z main, trafia do main i develop

Zwróć uwagę, że w artykule z 2010 roku gałąź produkcyjna nazywała się master. Ponieważ dzisiejsze hostingi zakładają repozytoria na main, tutaj używana jest ta nazwa.

Gitflow ręcznie

Żadne narzędzie nie jest potrzebne, ten model to wyłącznie dyscyplina w prowadzeniu gałęzi.

bash
# utworzenie gałęzi integracyjnej, raz na zawsze
git switch -c develop
git push -u origin develop

# jedna funkcjonalność
git switch -c feature/livraison develop
git commit -am "Ajoute le calcul des frais de livraison"
git switch develop
git merge --no-ff -m "Fusionne feature/livraison" feature/livraison
git branch -d feature/livraison

# jedna wersja
git switch main
git merge --no-ff -m "Version 1.2.0" develop
git tag -a v1.2.0 -m "Version 1.2.0"
Sortie réelle · git log --oneline --graph après la version
*   876ffba Version 1.2.0
|  
| * 269874d Fusionne feature/livraison
|/| 
| * afcc714 Ajoute la livraison
|/  
*   d7cdba6 Fusionne correctif/prix
|  
| * 711bcbc Corrige le calcul du prix
|/  
* 5b45117 Ajoute app.js

Gitflow z narzędziem git-flow

Istnieje zestaw komend, który automatyzuje te sekwencje. Oryginalny projekt nie jest już utrzymywany, utrzymywana jest edycja AVH, dostępna w większości menedżerów pakietów pod nazwą git-flow.

bash
git flow init -d       # -d akceptuje wszystkie domyślne nazwy
Sortie réelle · git flow init -d
Using default branch names.

Which branch should be used for bringing forth production releases?
   - main
Branch name for production releases: [main] 
Branch name for "next release" development: [develop] 

How to name your supporting branch prefixes?
Feature branches? [feature/] 
Bugfix branches? [bugfix/] 
Release branches? [release/] 
Hotfix branches? [hotfix/] 
Support branches? [support/] 
Version tag prefix? [] 
Hooks and filters directory? [/root/a8/.git/hooks] 

Cykl jednej funkcjonalności sprowadza się potem do dwóch komend:

bash
git flow feature start facturation
# … pracujesz i commitujesz …
git flow feature finish facturation
Sortie réelle · git flow feature finish
Switched to branch 'develop'
Updating 5b45117..61c7618
Fast-forward
 facture.php | 1 +
 1 file changed, 1 insertion(+)
Deleted branch feature/facturation (was 61c7618).

Summary of actions:
- The feature branch 'feature/facturation' was merged into 'develop'
- Feature branch 'feature/facturation' has been locally deleted
- You are now on branch 'develop'

Cykl wersji również do dwóch. git flow release finish scala do main, zakłada tag, a potem przenosi całość do develop:

bash
git flow release start 1.1.0
# … aktualizacja numeru wersji, ostatnie poprawki …
git flow release finish -m "Version 1.1.0" 1.1.0
Sortie réelle · git log --oneline --graph --all après la version
*   1b1a31d Merge tag '1.1.0' into develop
|  
| *   48f5649 Merge branch 'release/1.1.0'
| |  
| | * eb133dd Prepare la version 1.1.0
| |/  
|/|   
* | 61c7618 Ajoute la facturation
|/  
* 5b45117 Ajoute app.js

Ten graf dobrze pokazuje zarzut stawiany modelowi: trzy commity scalające dla wersji, która zawierała jedną funkcjonalność.

Który wybrać

Trunk-based Gitflow
Gałęzie stałe main main i develop
Czas życia gałęzi godziny lub dni do następnej wersji
Rytm wydawania ciągły, kilka razy dziennie datowanymi wersjami
Historia prosta rozgałęziona
Konflikty rzadkie i małe rzadkie, ale obszerne
Wymagania wstępne solidne testy automatyczne, feature flagi dyscyplina nazewnictwa, faza testów akceptacyjnych
Koszt wejścia niski w komendach, wysoki w narzędziach wysoki w komendach, niski w narzędziach

Wybierz trunk-based development, jeśli wydajesz aplikację webową lub usługę, którą często wdrażasz, jeśli na produkcji stoi naraz jedna wersja, jeśli zespół jest mały i jeśli masz testy automatyczne z prawdziwego zdarzenia. Tak wygląda zdecydowana większość dzisiejszych projektów webowych i to jest model, po który sięgasz domyślnie.

Wybierz Gitflow, jeśli publikujesz numerowane wersje, które użytkownicy sami instalują, jeśli musisz utrzymywać kilka wersji równolegle, jeśli formalna faza testów akceptacyjnych oddziela koniec prac od wdrożenia albo jeśli pracujesz pod wymogiem regulacyjnym narzucającym śledzenie zmian wersja po wersji. Biblioteki, aplikacje desktopowe, oprogramowanie wbudowane, instalacje on-premise u klientów: tam model zachowuje pełną wartość.

Jeśli zaczynasz sam, ani jeden, ani drugi. Pracuj na main, zakładaj gałąź, gdy próbujesz czegoś niepewnego, i zakładaj tag, gdy jesteś zadowolony z wyniku. Po model sięgniesz w dniu, w którym będzie was kilkoro, a wtedy trunk-based wdraża się najprościej.

Ostatnia rada: nie przyjmuj modelu dlatego, że uchodzi za poważny. Gitflow stosowany przez dwuosobowy zespół, który wdraża codziennie, produkuje puste gałęzie release i zbędne scalenia. Dobry model to ten, który odpowiada twojemu sposobowi wydawania.

Co dalej

Masz już podstawy Gita. Dalej warto pójść w trzech kierunkach.

Najpierw continuous integration, nieodzowne uzupełnienie trunk-based development: automatyczne uruchamianie testów przy każdym pushu. GitHub Actions i GitLab CI są wbudowane w te platformy i konfiguruje się je zwykłym plikiem YAML w repozytorium.

Potem prośby o scalenie: pull requests na GitHubie, merge requests na GitLabie. To one organizują code review w zespole i w obu przedstawionych tu modelach są prawdziwą bramą do main.

Na koniec komendy ratunkowe: git bisect, żeby przez połowienie znaleźć commit, który wprowadził błąd, git cherry-pick, żeby przenieść konkretny commit z innej gałęzi, i git worktree, żeby trzymać kilka gałęzi otwartych naraz w kilku katalogach.

Pełny spis treści pozostaje dostępny z kursu Nauka Gita, a pozostałe tutoriale ścieżki znajdziesz w hubie Programowanie webowe.

Częste błędy

git tag -a bez komunikatu Git otwiera edytor, a w środowisku automatycznym komenda kończy się błędem. Zawsze podawaj -m.
Tag lekki zamiast adnotowanego git tag v1.0 nie zapisuje ani autora, ani daty, ani komentarza. Do opublikowanej wersji używaj git tag -a.
Tag nie pojawia się na serwerze git push nie wysyła tagów. Wypchnij je jawnie przez git push origin v1.0.0.
Gitflow przyjęty odruchowo Trzy commity scalające dla wersji zawierającej jedną funkcjonalność to znak, że model jest za ciężki dla twojego zespołu.
Newsletter

Nowe testy, poradniki i projekty — e-mailem.

Powtarzalne testy, wersjonowany kod, datowane wyniki. Nigdy spamu.