Commit Conventions¶
Overview¶
Consistent commit messages improve readability, enable automation, and make git history useful.
We follow Conventional Commits with audio-specific extensions.
Format¶
Type (Required)¶
feat: New featurefix: Bug fixperf: Performance improvementrefactor: Code restructuring without behavior changetest: Adding or updating testsdocs: Documentation onlybuild: Build system, dependencies, cmakeci: CI/CD configurationstyle: Formatting, whitespace (not CSS)chore: Maintenance tasks
Scope (Optional but Recommended)¶
Indicates what part of codebase is affected:
By module:
- core: Core abstractions
- dsp: DSP utilities
- buffer: Buffer management
- math: Math primitives
- param: Parameter system
- rt: Real-time utilities
- platform: Platform abstraction
- serial: Serialization
- lifecycle: Plugin lifecycle
- event: Event system
By area:
- api: Public API changes
- internal: Internal implementation
- tests: Test infrastructure
- examples: Example code
- docs: Documentation
Subject (Required)¶
- Use imperative mood ("add" not "added" or "adds")
- Don't capitalize first letter
- No period at the end
- Limit to 50 characters
- Be specific and descriptive
Body (Optional)¶
- Explain why, not what (code shows what)
- Wrap at 72 characters
- Separate from subject with blank line
Footer (Optional)¶
- Reference issues:
Fixes #123,Closes #456 - Breaking changes:
BREAKING CHANGE: description - Related PRs:
Related to #789
Examples¶
Simple Feature¶
Bug Fix with Issue Reference¶
fix(dsp): resolve phase cancellation in stereo processing
The stereo width calculation was inverting the phase incorrectly.
Changed to use proper mid/side encoding.
Fixes #42
Performance Improvement¶
perf(math): use SIMD for fast exp approximation
Replaced scalar loop with SSE intrinsics.
Benchmark shows 4x speedup on typical inputs.
Breaking Change¶
feat(api): change parameter range from 0-1 to -1 to 1
BREAKING CHANGE: All parameters now use bipolar range.
Migration guide in docs/migration/v2.md.
Multiple Related Changes¶
refactor(core): reorganize observer pattern implementation
- Move Subject/Observer to core_interfaces
- Add thread-safe notification queue
- Update docs with usage examples
Related to #15, #23
Build System¶
Documentation¶
Test Addition¶
Audio-Specific Guidelines¶
RT Safety Changes¶
feat(param): add lock-free parameter update queue
Enables RT-safe parameter changes from UI thread.
No allocations or locks in audio callback.
DSP Algorithms¶
feat(dsp): implement state variable filter
Based on Hal Chamberlin's design.
Includes LP, HP, BP, Notch modes.
Platform-Specific Fixes¶
fix(platform): correct CPU feature detection on ARM
NEON detection was failing on M1 Macs.
Now uses proper sysctl query.
Anti-Patterns¶
❌ Too Vague¶
❌ Too Detailed (Put in Body)¶
❌ Multiple Unrelated Changes¶
Should be 3 separate commits.❌ Wrong Mood¶
feat: added feature // ❌ past tense
feat: adds feature // ❌ present tense
feat: add feature // ✅ imperative
Tips¶
Commit Often¶
# Good: Small, focused commits
git commit -m "feat(buffer): add capacity check"
git commit -m "test(buffer): add capacity tests"
git commit -m "docs(buffer): document capacity behavior"
# Bad: One giant commit
git commit -m "feat(buffer): complete implementation"
Use git commit -v¶
Shows diff while writing message - helps write better descriptions.
Check Before Pushing¶
# Review commit history
git log --oneline -5
# Amend last commit if needed
git commit --amend
# Interactive rebase to clean up
git rebase -i HEAD~3
Automation¶
Generate Changelog¶
# All features since last tag
git log --oneline --grep="^feat"
# All fixes
git log --oneline --grep="^fix"
Lint Commits¶
# commitlint config (optional)
npm install --save-dev @commitlint/{cli,config-conventional}
echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js
Git Hooks¶
# .git/hooks/commit-msg
#!/bin/bash
if ! grep -qE "^(feat|fix|perf|refactor|test|docs|build|ci|style|chore)(\(.+\))?: .+" "$1"; then
echo "ERROR: Commit message doesn't follow conventional commits"
exit 1
fi
Squashing Commits¶
When merging PRs, decide:
Keep all commits when: - Each commit is valuable history - Commits are well-formed - Incremental changes matter
Squash commits when: - Many "fix typo" commits - Work-in-progress commits - Easier to review as single change
Template¶
Save as .gitmessage:
# <type>(<scope>): <subject>
#
# [optional body]
#
# [optional footer]
#
# Type: feat, fix, perf, refactor, test, docs, build, ci, style, chore
# Scope: module or area affected
# Subject: imperative mood, lowercase, no period, <50 chars
# Body: wrap at 72 chars, explain why not what
# Footer: Fixes #issue, BREAKING CHANGE, etc.
Use it: