There are disasters that build character. For me, it was that Friday evening in 2023: a colleague pushes directly to main without a branch, without a PR, without a review. 300 lines of production code overwritten. The site inaccessible for 2 hours. Clients calling. The CEO texting.
That evening, I wrote our team's Git conventions. I've never regretted them.
Gitflow vs Trunk-Based Development: Which Model to Choose?
Gitflow (long-lived branches)
main— production onlydevelop— continuous integrationfeature/*— new featuresrelease/*— deployment preparationhotfix/*— urgent production fixes
Best for: Projects with formal release cycles, large teams, explicit product versioning.
Trunk-Based Development (short-lived branches)
main— always deployable- Small feature branches living 1-3 days maximum
- Frequent integration to avoid conflicts
Best for: Small teams, startups, projects with frequent deployments.
Branch Naming: A Strict Convention
# Format
{type}/{ticket}-{short-description}
# Examples
feature/DEZ-142-authentication-api
fix/DEZ-234-login-session-expire
refactor/DEZ-301-extract-order-service
hotfix/DEZ-520-payment-gateway-timeout
# Allowed types
feature → new functionality
fix → bug fix
hotfix → urgent production fix
refactor → refactoring without behavior change
chore → maintenance, dependencies, CI
docs → documentation
test → adding/modifying tests
Conventional Commits: Readable History
# Format
{type}({scope}): {description}
# Good commit examples
feat(auth): add JWT token refresh endpoint
fix(blog): correct N+1 query in PostController::index
refactor(user): extract UserService from UserController
test(order): add unit tests for OrderService::createOrder
chore(deps): update laravel/sanctum to v3.3
# BAD commits (to ban)
fix bug
wip
test
correction
Pull Request Template
## Description
<!-- Describe the changes made -->
## Type of change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation
## How to test
1. ...
2. ...
## Checklist
- [ ] Code follows project conventions
- [ ] Tests added for my changes
- [ ] Existing tests pass
- [ ] Documentation updated if needed
Git Hooks: Automate Checks
# .git/hooks/pre-commit
#!/bin/sh
./vendor/bin/php-cs-fixer fix --dry-run --diff
if [ $? -ne 0 ]; then
echo "❌ PHP style errors detected. Run php-cs-fixer fix"
exit 1
fi
php artisan test --testsuite=Unit
if [ $? -ne 0 ]; then
echo "❌ Unit tests failing. Fix before committing."
exit 1
fi
echo "✅ Pre-commit checks passed!"
The Golden Rules That Save Nights
- Never push directly to main. No exceptions. Not even for "a small typo fix."
- At least one review before merging. The eyes that wrote the code don't see its mistakes.
- Atomic commits. One commit = one logical change. Not "fix everything."
- Rebase before merging. Keep a linear, readable history.
- Tag your deployments.
git tag v1.2.3 -m "Release 1.2.3"enables precise rollbacks.
Conclusion
A good Git workflow isn't built in a day. It evolves with the team, needs, and incidents. But start with these foundations: naming conventions, structured commits, systematic pull requests, and verification hooks.
Your future self, at 11pm on a production-fire Friday, will thank you.