Git to system kontroli wersji, z którego korzysta 97% programistów na świecie. Ale Git to nie tylko narzędzie dla developerów — administratorzy IT, DevOps, copywriterzy, a nawet prawnicy używają go do śledzenia zmian w plikach. W tym kompletnym poradniku, przygotowanym przez nasz zespół we Wrocławiu, przeprowadzimy Cię od pierwszego git init do zaawansowanych technik takich jak rebase, cherry-pick i bisect.

Część 1: Jak zacząć z Git — podstawy

Czym jest Git i dlaczego go potrzebujesz?

Git to rozproszony system kontroli wersji (DVCS) stworzony w 2005 roku przez Linusa Torvaldsa (twórcę Linuxa). W praktyce Git pozwala:

  • Śledzić każdą zmianę — kto, co, kiedy i dlaczego zmienił w pliku
  • Cofać zmiany — wracać do dowolnego punktu w historii projektu
  • Pracować równolegle — wiele osób edytuje te same pliki bez nadpisywania sobie nawzajem
  • Tworzyć gałęzie (branches) — eksperymentować z nowymi funkcjami bez ryzyka zepsucia kodu produkcyjnego
  • Tworzyć kopie zapasowe — każdy klon repozytorium to pełna kopia całej historii

Instalacja Git

System Komenda / Metoda
Linux (Ubuntu/Debian) sudo apt install git
Linux (Fedora/RHEL) sudo dnf install git
macOS brew install git lub Xcode Command Line Tools
Windows Git for Windows (git-scm.com) lub winget install Git.Git

Po instalacji skonfiguruj swoją tożsamość:

git config --global user.name "Jan Kowalski"
git config --global user.email "jan@example.com"
git config --global init.defaultBranch main

Tworzenie repozytorium — pierwsze kroki

Nowy projekt od zera

# Utwórz katalog projektu
mkdir moj-projekt
cd moj-projekt

# Zainicjalizuj repozytorium Git
git init

# Utwórz pierwszy plik
echo "# Mój Projekt" > README.md

# Sprawdź status — Git widzi nowy plik
git status

# Dodaj plik do staging area (przygotuj do commita)
git add README.md

# Zapisz zmianę (commit)
git commit -m "Pierwszy commit — dodanie README"

Klonowanie istniejącego projektu

# Sklonuj repozytorium z GitHuba
git clone https://github.com/user/repo.git

# Sklonuj do wybranego katalogu
git clone https://github.com/user/repo.git moj-katalog

Podstawowy cykl pracy z Git

Każda zmiana w Git przechodzi przez 3 stany:

  1. Working directory — edytujesz pliki na dysku (zmiany niezapisane w Git)
  2. Staging area (index) — wybierasz, które zmiany wejdą do następnego commita (git add)
  3. Repository (.git) — zmiany są trwale zapisane w historii (git commit)
# Sprawdź co się zmieniło
git status                    # Lista zmienionych plików
git diff                      # Dokładne zmiany (linia po linii)

# Dodaj zmiany do staging area
git add plik.txt              # Dodaj konkretny plik
git add src/                  # Dodaj cały katalog
git add -A                    # Dodaj wszystkie zmiany

# Zapisz zmiany (commit)
git commit -m "Dodanie walidacji formularza kontaktowego"

# Wyślij zmiany na serwer (remote)
git push origin main

Najważniejsze komendy — ściągawka

Komenda Opis
git init Utwórz nowe repozytorium
git clone <url> Sklonuj zdalne repozytorium
git status Pokaż status zmian
git diff Pokaż różnice w plikach
git add <plik> Dodaj plik do staging area
git commit -m "msg" Zapisz zmiany z opisem
git log --oneline Historia commitów (skrócona)
git push Wyślij commity na serwer
git pull Pobierz i scal zmiany z serwera
git branch Lista gałęzi
git checkout -b <branch> Utwórz i przełącz na nową gałąź
git merge <branch> Scal gałąź z bieżącą
git stash Odłóż zmiany na bok (tymczasowo)

Plik .gitignore — co NIE powinno trafić do repozytorium

Utwórz plik .gitignore w katalogu głównym projektu. Git zignoruje wymienione pliki i katalogi:

# Pliki systemowe
.DS_Store
Thumbs.db

# Zależności (instalowane automatycznie)
node_modules/
vendor/
__pycache__/

# Pliki konfiguracyjne z hasłami
.env
.env.local
credentials.json

# Pliki budowania
dist/
build/
*.log

# IDE
.idea/
.vscode/
*.swp

Zasada: commituj kod źródłowy i konfigurację. Nie commituj: zależności (npm, composer), plików z hasłami, plików tymczasowych, artefaktów budowania.

Część 2: Git w pracy — workflow zespołowy

GitHub, GitLab czy Bitbucket?

Platforma Darmowy plan CI/CD Najlepsze dla
GitHub Unlimited repos, 2000 min CI/mies. GitHub Actions Open source, startupy, społeczność
GitLab Unlimited repos, 400 min CI/mies. GitLab CI/CD (wbudowane) Enterprise, DevOps, self-hosted
Bitbucket 5 użytkowników, 50 min CI/mies. Bitbucket Pipelines Zespoły z Jira/Confluence (Atlassian)

Branching — strategia gałęzi

Gałęzie (branches) to fundament pracy zespołowej z Git. Pozwalają pracować nad nowymi funkcjami bez ryzyka zepsucia kodu na produkcji.

Git Flow — klasyczny model

# Gałęzie stałe:
main          # Kod produkcyjny (to, co działa na serwerze)
develop       # Gałąź integracyjna (tu scalamy nowe funkcje)

# Gałęzie tymczasowe:
feature/login-page    # Nowa funkcja
bugfix/fix-email      # Naprawa błędu
hotfix/security-patch # Pilna poprawka na produkcji
release/v2.1          # Przygotowanie wydania

GitHub Flow — prostszy model

# Tylko main + feature branches
main                          # Produkcja
feature/add-contact-form      # Nowa funkcja

# Workflow:
1. Utwórz branch z main
2. Commituj zmiany
3. Otwórz Pull Request
4. Code review + dyskusja
5. Merge do main
6. Deploy automatycznie

Trunk-based development — dla doświadczonych zespołów

# Jeden branch (main), krótkotrwałe feature branches (max 1-2 dni)
# Feature flags zamiast długich gałęzi
# Ciągła integracja — merge kilka razy dziennie

Pull Request (PR) — serce pracy zespołowej

Pull Request to propozycja zmian, którą inni członkowie zespołu przeglądają przed scaleniem do głównej gałęzi.

# 1. Utwórz nową gałąź
git checkout -b feature/formularz-kontaktowy

# 2. Wprowadź zmiany i commituj
git add pages/contact.php
git commit -m "Dodanie walidacji formularza kontaktowego po stronie serwera"

# 3. Wypchnij gałąź na serwer
git push -u origin feature/formularz-kontaktowy

# 4. Otwórz Pull Request na GitHub/GitLab (przez GUI lub CLI)
gh pr create --title "Walidacja formularza kontaktowego" --body "Dodaje walidację email, telefonu i wymaganego pola wiadomości"

Dobry Pull Request zawiera:

  • Tytuł — krótki opis co zmienia (max 70 znaków)
  • Opis — dlaczego ta zmiana, co robi, jak testować
  • Mały zakres — 200–400 linii kodu max. Duży PR = pobieżne review = błędy
  • Testy — automatyczne testy potwierdzające, że zmiana działa
  • Screenshots — jeśli zmiana wizualna, pokaż przed/po

Code Review — jak przeglądać kod

  • Sprawdź logikę — czy rozwiązanie ma sens? Czy są edge case'y?
  • Bezpieczeństwo — SQL injection, XSS, hardcoded secrets, brak walidacji inputu
  • Czytelność — czy za miesiąc zrozumiesz ten kod? Czy nazwy zmiennych są opisowe?
  • Testy — czy nowy kod jest przetestowany? Czy testy pokrywają edge case'y?
  • Bądź konstruktywny — „Rozważ użycie X, ponieważ Y" zamiast „To jest źle"

Rozwiązywanie konfliktów merge

Konflikty występują, gdy dwie osoby zmieniły tę samą linię w pliku. Git nie wie, którą wersję wybrać:

# Po git merge lub git pull pojawi się:
CONFLICT (content): Merge conflict in pages/home.php
Automatic merge failed; fix conflicts and then commit the result.

# Otwórz plik — Git oznaczył konflikt:
<<<<<<< HEAD

Witaj na naszej stronie

=======

Profesjonalne usługi IT

>>>>>>> feature/nowy-naglowek # Zdecyduj, którą wersję zachować (lub połącz obie):

Profesjonalne usługi IT

# Zapisz plik, dodaj i commituj: git add pages/home.php git commit -m "Rozwiązanie konfliktu — nowy nagłówek strony głównej"

Commit messages — jak pisać dobre opisy commitów

Dobry opis commita to inwestycja — za 6 miesięcy git log powie Ci dlaczego zmiana została wprowadzona.

Conventional Commits — standard branżowy

# Format: typ(zakres): opis
feat(auth): dodanie logowania przez Google OAuth
fix(contact): naprawienie walidacji numeru telefonu
docs(README): aktualizacja instrukcji instalacji
style(css): poprawienie wyrównania na mobile
refactor(api): wydzielenie logiki walidacji do osobnego modułu
test(auth): dodanie testów dla resetowania hasła
chore(deps): aktualizacja zależności npm

Zasady dobrego opisu

  • Tryb rozkazujący — „Dodaj walidację" (nie „Dodano walidację" ani „Dodaje walidację")
  • Max 72 znaki w pierwszej linii — zwięźle, konkretnie
  • Dlaczego, nie co — Git diff pokaże CO się zmieniło. Commit message powinien mówić DLACZEGO
  • Odniesienie do ticketa — „fix(auth): naprawienie tokenu sesji (JIRA-1234)"

Część 3: Zaawansowane techniki Git

Git rebase — czysta historia commitów

Rebase przenosi Twoje commity „na szczyt" innej gałęzi, tworząc liniową historię (bez merge commitów).

# Zamiast git merge main (tworzy merge commit):
git checkout feature/moja-funkcja
git rebase main

# Teraz Twoje commity są "na szczycie" main
# Historia jest czysta i liniowa

# Interactive rebase — edycja, łączenie, zmiana kolejności commitów:
git rebase -i HEAD~5    # Edytuj ostatnie 5 commitów

# W edytorze zobaczysz:
pick abc1234 Dodanie modelu User
pick def5678 WIP: praca w toku
pick ghi9012 Poprawka literówki
pick jkl3456 Dodanie walidacji email
pick mno7890 Dokończenie walidacji

# Możesz:
# pick   — zachowaj commit
# squash — połącz z poprzednim
# reword — zmień opis
# drop   — usuń commit
# edit   — zatrzymaj i pozwól edytować

Złota zasada: NIGDY nie rebasuj commitów, które już wypchnąłeś na serwer i ktoś inny na nich pracuje. Rebase zmienia historię — to OK lokalnie, ale destrukcyjne dla współpracowników.

Git cherry-pick — wybieranie pojedynczych commitów

Kopiuje wybrany commit z jednej gałęzi do drugiej:

# Znajdź hash commita, który chcesz przenieść
git log --oneline feature/stara-galaz

# Przełącz na gałąź docelową
git checkout main

# Skopiuj konkretny commit
git cherry-pick abc1234

# Cherry-pick kilku commitów:
git cherry-pick abc1234 def5678 ghi9012

# Cherry-pick bez automatycznego commita (tylko zmiany):
git cherry-pick --no-commit abc1234

Kiedy używać: hotfix z gałęzi develop na main, przenoszenie jednej poprawki bez całego feature brancha, backport do starszej wersji.

Git bisect — znajdowanie commita, który zepsuł kod

Bisect używa wyszukiwania binarnego do znalezienia commita, który wprowadził buga — nawet w historii z tysiącami commitów:

# Rozpocznij bisect
git bisect start

# Oznacz bieżący commit jako "zły" (bug istnieje)
git bisect bad

# Oznacz stary commit, gdzie bug nie istniał, jako "dobry"
git bisect good v2.0    # lub git bisect good abc1234

# Git przełączy Cię na commit w połowie zakresu
# Sprawdź czy bug istnieje i oznacz:
git bisect good         # Bug nie istnieje w tym commicie
# lub
git bisect bad          # Bug istnieje

# Git zawęzi zakres i przełączy na następny commit
# Powtarzaj aż Git znajdzie winny commit:
# abc1234 is the first bad commit

# Zakończ bisect
git bisect reset

# Automatyczny bisect (jeśli masz test):
git bisect start HEAD v2.0
git bisect run ./test-czy-bug-istnieje.sh

Przykład: 1000 commitów, wyszukiwanie binarne = max 10 kroków do znalezienia problematycznego commita.

Git stash — odkładanie zmian na bok

# Masz niezacommitowane zmiany, ale musisz pilnie przełączyć branch:
git stash                          # Odłóż zmiany na stos
git stash save "WIP: formularz"    # Z opisem

# Przełącz branch, zrób co trzeba:
git checkout main
git pull
# ... naprawa buga ...
git checkout feature/moja-funkcja

# Przywróć odłożone zmiany:
git stash pop                      # Przywróć i usuń ze stosu
git stash apply                    # Przywróć, ale zachowaj na stosie

# Lista odłożonych zmian:
git stash list

# Przywróć konkretny stash:
git stash apply stash@{2}

# Usuń stash:
git stash drop stash@{0}
git stash clear                    # Usuń wszystkie

Git reflog — ratowanie „utraconych" commitów

Reflog to historia WSZYSTKICH zmian HEAD — nawet tych, które „usunąłeś" przez reset, rebase czy amend:

# Pokaż historię reflog:
git reflog

# Przykład wyniku:
abc1234 HEAD@{0}: reset: moving to HEAD~3
def5678 HEAD@{1}: commit: Ważna zmiana
ghi9012 HEAD@{2}: commit: Bardzo ważna zmiana

# Przywróć "utracony" commit:
git checkout def5678
# lub
git reset --hard def5678
# lub (bezpieczniej) utwórz nową gałąź:
git branch odzyskane def5678

Reflog zachowuje dane przez 90 dni. Jeśli zrobiłeś git reset --hard i straciłeś zmiany — reflog jest Twoim ratunkiem.

Git worktree — wiele gałęzi jednocześnie

# Problem: chcesz pracować na dwóch gałęziach bez ciągłego przełączania

# Utwórz dodatkowy worktree (osobny katalog z inną gałęzią):
git worktree add ../hotfix-branch hotfix/pilna-poprawka

# Teraz masz:
# /moj-projekt          → branch main
# /hotfix-branch        → branch hotfix/pilna-poprawka

# Pracuj w obu katalogach jednocześnie!

# Lista worktree:
git worktree list

# Usuń worktree po zakończeniu:
git worktree remove ../hotfix-branch

Git hooks — automatyzacja przed/po commitach

Hooki to skrypty uruchamiane automatycznie przy określonych akcjach Git:

Hook Kiedy Zastosowanie
pre-commit Przed każdym commitem Linting, formatowanie, sprawdzenie sekretów
commit-msg Po napisaniu opisu Walidacja formatu (Conventional Commits)
pre-push Przed pushem Uruchomienie testów, blokowanie push do main
post-merge Po merge/pull Instalacja zależności (npm install)

Narzędzia do zarządzania hookami: Husky (Node.js), pre-commit (Python), lefthook (Go).

Git aliases — skróty dla częstych komend

# Dodaj aliasy do ~/.gitconfig:
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.last "log -1 HEAD"
git config --global alias.unstage "reset HEAD --"
git config --global alias.amend "commit --amend --no-edit"

# Teraz zamiast:
git checkout -b feature/nowa
# Piszesz:
git co -b feature/nowa

# Piękny log z grafem:
git lg

Zaawansowane operacje na historii

git reset — cofanie commitów

# Soft reset — cofnij commit, zachowaj zmiany w staging area:
git reset --soft HEAD~1

# Mixed reset (domyślny) — cofnij commit, zachowaj zmiany w working dir:
git reset HEAD~1

# Hard reset — cofnij commit i USUŃ zmiany (niebezpieczne!):
git reset --hard HEAD~1

git revert — bezpieczne cofanie

# Utwórz NOWY commit, który odwraca zmiany z poprzedniego:
git revert abc1234

# Bezpieczne — nie zmienia historii, działa dobrze we współpracy
# Używaj zamiast reset gdy commity są już na serwerze

git blame — kto napisał tę linię?

# Pokaż autora każdej linii w pliku:
git blame pages/home.php

# Z zakresem linii:
git blame -L 10,20 pages/home.php

# Ignoruj whitespace changes:
git blame -w pages/home.php

Git w zastosowaniach niestandardowych

Git dla administratorów IT

  • Konfiguracja serwerów — wersjonowanie /etc/ (etckeeper) — kto zmienił konfigurację Apache o 3 w nocy?
  • Infrastructure as Code — Terraform, Ansible playbooki w Git = pełna audytowalność zmian infrastruktury
  • Disaster recovery — konfiguracje w Git = odtworzenie serwera w minuty zamiast godzin
  • Compliance — historia zmian w Git = dowód audytowy (ISO 27001, SOC 2)

Git dla DevOps — CI/CD

  • GitHub Actions / GitLab CI — automatyczne testy, build, deploy przy każdym pushu
  • GitOps — stan infrastruktury zdefiniowany w Git. Merge do main = automatyczny deploy (ArgoCD, Flux)
  • Semantic versioning — automatyczne tagowanie wersji na podstawie Conventional Commits
  • Protected branches — main wymaga PR, approved review i zielonych testów CI

Git dla dokumentacji i treści

  • Dokumentacja techniczna — Markdown w Git = wersjonowane docs (GitBook, MkDocs, Docusaurus)
  • Strony statyczne — treści blogowe w Git, deploy przez CI/CD (Hugo, Astro, Jekyll)
  • Współpraca nad umowami/regulaminami — prawnik widzi diff między wersjami umowy

Narzędzia GUI dla Git

Nie musisz żyć w terminalu — graficzne narzędzia Git są potężne:

Narzędzie Cena Platformy Najlepsze dla
VS Code (wbudowany) Darmowy Win / Mac / Linux Programiści (Git + edytor w jednym)
GitKraken Darmowy (public repos) Win / Mac / Linux Wizualizacja historii, merge conflicts
Fork $49.99 Win / Mac Szybki, lekki, interactive rebase
Sourcetree Darmowy Win / Mac Początkujący, integracja z Bitbucket
lazygit Darmowy (open source) Terminal (TUI) Zaawansowani, praca w terminalu

Najczęstsze błędy i jak ich unikać

  1. Commitowanie haseł i kluczy API — użyj .gitignore i narzędzi jak git-secrets lub trufflehog. Jeśli już commitnąłeś hasło — zmień je NATYCHMIAST (usunięcie z historii nie wystarczy, bo ktoś mógł sklonować)
  2. Jeden wielki commit „naprawiłem wszystko" — commituj atomowo: jedna zmiana = jeden commit. Łatwiej przeglądać, revertować, bisectować
  3. Praca bezpośrednio na main — zawsze twórz feature branch. Main powinien być „always deployable"
  4. Force push bez ostrzeżeniagit push --force nadpisuje historię na serwerze. Używaj --force-with-lease (bezpieczniejszy) i informuj zespół
  5. Ignorowanie konfliktów — „wezmę moją wersję" bez analizy = utrata cudzej pracy. Czytaj konflikty uważnie
  6. Brak .gitignore od początku — node_modules w repo = tysiące zbędnych plików, wolne klonowanie, bałagan
  7. Commitowanie plików tymczasowych — .DS_Store, .env.local, *.log — dodaj do .gitignore globalnego

Podsumowanie

Git to jedno z najważniejszych narzędzi w arsenale każdego specjalisty IT. Od prostego git init i git commit, przez branching i Pull Requesty w zespole, po zaawansowane techniki jak rebase, cherry-pick i bisect — Git daje pełną kontrolę nad historią projektu. Kluczem jest: zacząć od podstaw, pracować w branchach, pisać dobre opisy commitów i nigdy nie commitować haseł.

Najczęściej zadawane pytania (FAQ)

Czym różni się Git od GitHuba?

Git to narzędzie do kontroli wersji działające lokalnie na komputerze. GitHub to platforma webowa hostująca repozytoria Git z funkcjami zespołowymi jak Pull Requesty, Issues i CI/CD.

Czy Git jest tylko dla programistów?

Nie. Git jest dla każdego, kto pracuje z plikami tekstowymi: administratorzy IT (konfiguracje), pisarze, naukowcy, DevOps (Infrastructure as Code), prawnicy (wersje umów).

Jak cofnąć ostatni commit w Git?

Użyj git reset --soft HEAD~1 (zachowuje zmiany w staging area) lub git revert HEAD (tworzy nowy commit odwracający zmiany — bezpieczne gdy commit jest już na serwerze).

Potrzebujesz pomocy z Git i DevOps we Wrocławiu?

Wdrożymy Git, CI/CD i automatyzację deploymentu w Twojej firmie — od konfiguracji repozytorium, przez szkolenie zespołu, po pełny pipeline DevOps. Działamy na terenie Wrocławia i zdalnie.

Zamów konsultację DevOps
← Wróć do bloga