Git Workflow Best Practices for Small Teams
The Recommended Workflow: Trunk-Based with Short-Lived Branches
Why Not GitFlow?
GitFlow (develop, release, hotfix branches) adds complexity that small teams do not need. It was designed for large teams shipping packaged software on fixed release cycles. Modern web applications deploy continuously, making GitFlow overhead unjustified.
The Simple Version
mainis always deployable- Create short-lived feature branches from
main - Open a PR when ready for review
- Merge to
mainafter approval - Deploy automatically from
main
Branch Naming Convention
feature/add-user-auth
fix/login-timeout-error
chore/update-dependencies
docs/api-endpoint-reference
For more on this topic, see our guide on API Rate Limiting: Implementation Strategies and Best Practices.
Prefix with the type of change, followed by a brief description in kebab-case.
Conventional Commits
feat: add user authentication endpoint
fix: resolve timeout on login page
chore: update axios to 1.6.0
docs: add API reference for /users endpoint
refactor: extract validation logic to middleware
test: add integration tests for auth flow
The prefix enables automated changelog generation and semantic versioning.
For more on this topic, see our guide on AI Code Generation Security: Best Practices Every Developer Needs.
Pull Request Best Practices
Keep PRs Small
Aim for under 400 lines of changed code. Large PRs get superficial reviews because reviewers lose focus after ~400 lines. If a feature requires more, break it into sequential PRs.
Write a Description
Every PR should answer: What does this change? Why is it needed? How was it tested? Are there any risks?
One Concern Per PR
A PR should do one thing. Do not mix a bug fix with a refactor with a feature. Each should be a separate PR with a clear purpose.
Pre-Commit Hooks
Automate quality checks before code reaches the remote:
# .husky/pre-commit
npm run lint
npm run test -- --changed
npm run type-check
Protecting Main
- Require at least 1 approval before merging
- Require CI to pass before merging
- Use squash merges for clean history
- Delete branches after merging