Git workflow для PHP-разработчиков: как перестать бояться конфликтов и полюбить код-ревью
Вы когда-нибудь тратили полдня на слияние веток, чтобы в итоге получить «фатальную ошибку» в production? А может, ваш коллега случайно запушил «сырой» код прямо в master, и вы узнали об этом, когда сайт лёг? Если да — добро пожаловать в клуб. Но хорошая новость в том, что 90% таких проблем решаются правильным Git workflow для PHP-разработчиков.
В этой статье мы не будем пересказывать документацию. Мы разберём реальные сценарии: как организовать ветки, когда использовать rebase, а когда merge, и как настроить процессы так, чтобы команда не путалась в коммитах. Поехали!
Почему «просто git add . && git push» — это зло
Многие PHP-разработчики, особенно на старте, используют Git как «облачную флешку». Они коммитят всё подряд, не пишут осмысленные сообщения и пушат напрямую в master. Это работает ровно до первого конфликта или до момента, когда нужно откатить изменение.
Правильный git workflow php должен решать три задачи:
- Изоляция изменений — чтобы фича или багфикс не ломали работающий код.
- Прозрачность — чтобы любой разработчик понимал, что происходит в проекте.
- Автоматизация — чтобы тесты и линтеры запускались до того, как код попадёт в production.
Давайте посмотрим, как это реализовать на практике.
Выбираем стратегию ветвления: Git Flow, GitHub Flow или что-то своё?
Для PHP-проектов нет единственно верного ответа. Всё зависит от размера команды и частоты релизов. Но есть две популярные модели.
Git Flow — классика для крупных проектов
Если вы работаете над монолитным приложением с чёткими версиями (например, релиз раз в месяц), Git Flow — ваш выбор. Основные ветки:
master— только стабильный код, соответствующий production.develop— интеграционная ветка для всех фич.feature/*— каждая новая фича.release/*— подготовка к релизу.hotfix/*— срочные исправления.
Пример для PHP-разработчика: вы пишете модуль оплаты. Создаёте ветку feature/payment-module от develop. После завершения — пул-реквест в develop. Когда накопилось достаточно фич — создаёте release/2.3.0, где только багфиксы. Затем сливаете в master и develop.
GitHub Flow — для быстрых итераций
Если у вас микросервисы или вы деплоите несколько раз в день, GitHub Flow проще:
main(илиmaster) — всегда готов к деплою.- Любая другая ветка — для фичи или багфикса.
- После пул-реквеста и проверки — сразу вливаем в
main.
Для PHP это особенно удобно, когда у вас настроен CI/CD: после мержа в main автоматически запускаются тесты и деплой на staging или production.
Пишем осмысленные коммиты: примеры на PHP
Коммит — это не просто «сохраниться». Это документ, по которому вы и коллеги будете восстанавливать историю. Используйте conventional commits:
feat: add payment processing via Stripe
fix: correct SQL query in user repository
refactor: extract validation logic to trait
А теперь представьте, что вы работаете над PHP-проектом с Laravel. Допустим, вы добавили новый Artisan-команду. Какой коммит будет полезным?
feat: add artisan command to sync expired subscriptions
- Created SyncExpiredSubscriptions command
- Added subscription:sync tag to schedule
- Updated Subscription model with scopeExpired
Через месяц вы сможете быстро найти, когда и зачем была добавлена эта команда. Без такого описания пришлось бы читать diff.
Работа с pull request: код-ревью без боли
Pull request (или Merge request в GitLab) — это не просто «смотри, я написал код». Это точка входа для код-ревью. Чтобы оно было эффективным, следуйте правилам:
- Маленькие PR — не более 200-300 строк изменений. Большой PR никто не будет ревьюить внимательно.
- Одна задача — один PR. Не мешайте багфикс с рефакторингом.
- Добавляйте описание — что сделано, как тестировать, на что обратить внимание.
Пример хорошего описания PR для PHP:
## Что сделано
- Реализована отправка email-уведомлений после регистрации.
- Добавлен новый Mail класс WelcomeMail.
- Написаны unit-тесты для MailController.
## Как тестировать
1. Зарегистрировать нового пользователя через /register.
2. Проверить лог почты в storage/logs/laravel.log.
3. Убедиться, что WelcomeMail содержит ссылку на подтверждение.
## Важно
- Используется очередь queue:work — убедитесь, что worker запущен.
- Не забудьте выполнить php artisan queue:table и миграцию.
Git rebase vs merge: что выбрать PHP-разработчику?
Вечный холивар. Если коротко: merge сохраняет историю такой, какая она есть (со всеми коммитами и слияниями). Rebase переписывает историю, делая её линейной.
Для PHP-проектов я советую:
- Использовать
merge --no-ffдля вливания фич в develop/main. Это создаёт явный коммит слияния, по которому видно, когда фича была добавлена. - Использовать
rebaseдля обновления своей feature-ветки от develop. Это позволяет избежать «соплей» из коммитов слияния в вашей ветке.
Пример рабочего процесса:
# Начинаем фичу
git checkout -b feature/email-notifications develop
# Работаем, коммитим
git add .
git commit -m "feat: add WelcomeMail class"
# Прошло время, develop ушёл вперёд — обновляемся
git fetch origin
git rebase origin/develop
# Если конфликты — разрешаем и продолжаем
git add .
git rebase --continue
# Когда фича готова — пушим и создаём PR
git push origin feature/email-notifications
Важно: никогда не делайте rebase для веток, которые уже в общем доступе (например, если ваш PR уже ревьюят). Это сломает историю для коллег.