Git Workflow
Branching strategy, commit conventions, and automated hooks
Plainform uses Husky for Git hooks and Commitlint for enforcing conventional commit messages. This ensures code quality and consistent commit history.
Commit Message Format
All commits must follow the Conventional Commits specification:
<type>(<scope>): <subject>
[optional body]
[optional footer]Commit Types
| Type | Description | Example |
|---|---|---|
feat | New feature | feat(auth): add OAuth login |
fix | Bug fix | fix(stripe): handle webhook timeout |
docs | Documentation changes | docs(readme): update setup guide |
style | Code style changes (formatting) | style: fix indentation |
refactor | Code refactoring | refactor(api): simplify error handling |
perf | Performance improvements | perf(db): optimize query |
test | Adding or updating tests | test(auth): add login tests |
build | Build system changes | build: update dependencies |
ci | CI/CD changes | ci: add deployment workflow |
chore | Maintenance tasks | chore: update gitignore |
revert | Revert previous commit | revert: undo feature X |
security | Security fixes | security: patch XSS vulnerability |
The scope is optional but recommended for clarity (e.g., auth, stripe, db, ui).
Commit Rules
Header (first line):
- Maximum 100 characters
- Lowercase type and scope
- No period at the end
- Use imperative mood: "add" not "added" or "adds"
Body (optional):
- Blank line after header
- Maximum 100 characters per line
- Explain what and why, not how
Footer (optional):
- Blank line after body
- Reference issues:
Closes #123orFixes #456 - Breaking changes:
BREAKING CHANGE: description
Examples
Simple commit:
git commit -m "feat(pricing): add annual subscription option"Commit with body:
git commit -m "fix(webhook): handle duplicate events" -m "Stripe can send duplicate webhook events during retries. Added idempotency check using event ID to prevent duplicate processing."Breaking change:
git commit -m "feat(api): change authentication endpoint" -m "BREAKING CHANGE: /api/auth endpoint moved to /api/v2/auth. Update all client applications to use new endpoint."Git Hooks
Plainform uses Husky to run automated checks before commits and pushes.
Pre-Commit Hook
Runs before every commit to ensure code quality:
npm run lintWhat it does:
- Runs ESLint on all files
- Checks for syntax errors
- Enforces code style rules
If it fails:
- Fix linting errors:
npm run lint:fix - Review and fix remaining issues manually
- Commit again
Commits are blocked if linting fails. This prevents broken code from entering the repository.
Commit-Msg Hook
Validates commit message format:
npx --no -- commitlint --editWhat it does:
- Checks commit message follows Conventional Commits
- Validates type, scope, and subject format
- Enforces character limits
If it fails:
- Review error message for specific issue
- Amend commit message:
git commit --amend - Follow the format rules above
Pre-Push Hook
Runs before pushing to remote:
npm run buildWhat it does:
- Runs full production build
- Catches build errors before pushing
- Ensures code compiles successfully
If it fails:
- Fix build errors shown in output
- Test locally:
npm run build - Push again after fixing
Pre-push hook can take 30-60 seconds. This prevents pushing broken code to the repository.
Branching Strategy
Branch Naming
Use descriptive branch names with prefixes:
<type>/<short-description>Examples:
feat/oauth-loginfix/stripe-webhook-timeoutdocs/update-readmerefactor/api-error-handling
Recommended Workflow
Create Feature Branch
git checkout -b feat/new-featureWork on your feature in isolation from main branch.
Make Changes and Commit
git add .
git commit -m "feat(scope): add new feature"Hooks run automatically to validate your commit.
Keep Branch Updated
git checkout main
git pull origin main
git checkout feat/new-feature
git rebase mainRebase regularly to avoid merge conflicts.
Push to Remote
git push origin feat/new-featurePre-push hook runs build to catch errors.
Create Pull Request
Open PR on GitHub/GitLab for code review.
Merge and Clean Up
git checkout main
git pull origin main
git branch -d feat/new-featureDelete local branch after merging.
Bypassing Hooks
Not recommended, but sometimes necessary:
# Skip pre-commit hook
git commit --no-verify -m "fix: emergency hotfix"
# Skip pre-push hook
git push --no-verifyOnly bypass hooks for emergency fixes. Always fix issues properly afterward.
Troubleshooting
Configuration Files
Commitlint Config
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'build', 'chore', 'ci', 'docs', 'feat',
'fix', 'perf', 'refactor', 'revert',
'style', 'test', 'security'
],
],
'header-max-length': [2, 'always', 100],
'body-max-line-length': [2, 'always', 100],
},
};Husky Setup
{
"scripts": {
"prepare": "husky"
}
}The prepare script runs automatically after npm install to set up Git hooks.
Best Practices
Commit Often:
- Small, focused commits are easier to review
- Each commit should represent one logical change
- Makes debugging and reverting easier
Write Clear Messages:
- Explain what and why, not how
- Future you will thank present you
- Helps team understand changes
Keep Branches Short-Lived:
- Merge feature branches within 1-2 days
- Reduces merge conflicts
- Faster feedback from team
Review Before Pushing:
- Run
npm run buildlocally - Test your changes
- Review diff:
git diff
Use .gitignore:
- Never commit
.envfiles - Exclude
node_modules/,.next/, build artifacts - Keep repository clean
Next Steps
- Build & Deploy - Production deployment guide
- Troubleshooting - Common issues and solutions
- Pull Updates - Sync with upstream changes
How is this guide ?
Last updated on