PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Kurs Gita #6 – hooki i automatyzacja: pre-commit, PHPStan, commit-msg, DDEV

by Henryk Tews / sobota, 16 maja 2026 / Opublikowano w Git

Git hooks to skrypty uruchamiane automatycznie przy operacjach Gita. Pre-commit hook uruchomiony przed każdym commitem eliminuje klasę błędów zanim trafią do historii. Commit-msg wymusza konwencję wiadomości. Pre-push chroni zdalny branch przed broken code. Pokażę jak to skonfigurować w projekcie Magento 2 z DDEV.

Rodzaje hooków

Hook Kiedy Typowe użycie
pre-commit Przed zapisem commita phpcs, phpstan, sprawdzenie debuggerów
commit-msg Po wpisaniu wiadomości Walidacja formatu Conventional Commits
pre-push Przed wysłaniem na remote Pełne testy jednostkowe
post-merge Po merge/pull composer install, cache flush

pre-commit – phpcs i phpstan

#!/bin/bash
# .git/hooks/pre-commit
set -e

echo "Running PHP CS Fixer..."
files=$(git diff --cached --name-only --diff-filter=ACMR | grep \.php$)
if [ -n "$files" ]; then
    vendor/bin/phpcs --standard=PSR12 $files
fi

echo "Running PHPStan..."
if [ -n "$files" ]; then
    vendor/bin/phpstan analyse $files --level=8 --no-progress
fi

# Sprawdz czy nie ma var_dump lub dd()
if git diff --cached | grep -E "^\+.*var_dump|^\+.*dd\("; then
    echo "ERROR: var_dump() or dd() found in staged files"
    exit 1
fi

echo "Pre-commit checks passed!"

commit-msg – walidacja formatu

#!/bin/bash
# .git/hooks/commit-msg
COMMIT_MSG=$(cat "$1")
PATTERN="^(feat|fix|refactor|docs|test|chore|perf)(\([a-z-]+\))?: .{10,72}"

if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
    echo "ERROR: Commit message format invalid."
    echo "Required: type(scope): description (10-72 chars)"
    echo "Example: feat(catalog): add product export service"
    exit 1
fi

pre-push – testy przed wysłaniem

#!/bin/bash
# .git/hooks/pre-push
BRANCH=$(git symbolic-ref HEAD | sed 's/refs\/heads\///')

# Tylko dla main i develop
if [[ "$BRANCH" == "main" || "$BRANCH" == "develop" ]]; then
    echo "Running full test suite before push to $BRANCH..."
    vendor/bin/phpunit --testsuite=Unit
fi

Udostępnianie hooków w projekcie

Katalog .git/hooks/ nie jest wersjonowany. Najlepsza praktyka: przechowuj hooki w .githooks/ i konfiguruj ścieżkę.

# Skonfiguruj katalog hooków dla całego projektu
git config core.hooksPath .githooks

# Lub dodaj do composer.json post-install-cmd:
# "git config core.hooksPath .githooks"
# "chmod +x .githooks/*"

Integracja z DDEV

#!/bin/bash
# .githooks/pre-commit - wersja dla DDEV
set -e

files=$(git diff --cached --name-only --diff-filter=ACMR | grep \.php$)
[ -z "$files" ] && exit 0

# Uruchom phpcs i phpstan wewnątrz kontenera DDEV
ddev exec vendor/bin/phpcs --standard=PSR12 $files
ddev exec vendor/bin/phpstan analyse $files --level=8 --no-progress

echo "All checks passed!"

pre-commit jako narzędzie

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/digitalpulp/pre-commit-php
    rev: 1.4.0
    hooks:
      - id: php-lint
      - id: php-cs
        args: [--standard=PSR12]
      - id: php-stan
        args: [--level=8]
pip install pre-commit
pre-commit install
# Teraz hooki uruchamiają się automatycznie przy każdym git commit

Podsumowanie

Hooki Gita to pierwsza linia obrony przed błędami w historii. Pre-commit z phpcs i phpstan eliminuje problemy jakości kodu zanim trafią do repo. Commit-msg wymusza czytelne wiadomości. Przechowywanie hooków w .githooks/ i konfiguracja przez git config core.hooksPath udostępnia je całemu zespołowi. Następny wpis: debugging i ratowanie – bisect, reflog, reset vs revert.

About Henryk Tews

Co możesz przeczytać następne

Kurs Gita #2 – commity i historia: rebase -i, cherry-pick, bisect
Kurs Gita #1 – model danych: blobs, trees, commity, refs
Kurs Gita #5 – workflow zespolowy: Git Flow, trunk-based, PR, code review
  • Publikacje
  • O autorze
  • Kontakt

© 2026 Created by

GÓRA
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Zawsze aktywne
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Zarządzaj opcjami
  • Zarządzaj serwisami
  • Zarządzaj {vendor_count} dostawcami
  • Przeczytaj więcej o tych celach
Zobacz preferencje
  • {title}
  • {title}
  • {title}