# Writing Good Commit Messages A good commit message explains **what** the change does and **why** it matters. Your future self (and your teammates) will thank you. ## The Golden Rule: Write the Intent Write your message as a command - what will this commit **do** when applied? **Good (imperative, present tense):** ``` Add login button to navbar Fix crash when username is empty Remove unused database connection ``` **Avoid (past tense, describing what you did):** ``` Added login button to navbar Fixed crash when username is empty Removed unused database connection ``` **Why?** Think of it as completing this sentence: > "If applied, this commit will... **add login button to navbar**" ## Use Prefixes to Categorize Start your message with a prefix that tells readers what kind of change this is: | Prefix | Use For | Example | |--------|---------|---------| | `feat:` | New features | `feat: add password reset flow` | | `fix:` | Bug fixes | `fix: prevent duplicate form submission` | | `docs:` | Documentation only | `docs: add API examples to README` | | `style:` | Formatting, no code change | `style: fix indentation in auth module` | | `refactor:` | Code change that doesn't fix or add | `refactor: extract validation logic` | | `test:` | Adding or fixing tests | `test: add unit tests for login` | | `chore:` | Maintenance, dependencies | `chore: update pytest to 8.0` | ## Keep It Short The first line should be **50 characters or less**. This ensures it displays properly in: - Git log output - GitHub/Azure DevOps commit lists - Email notifications ``` fix: resolve memory leak in image processing │ │ └──────────── 45 characters ─────────────────┘ ``` ## Add Details When Needed For complex changes, add a blank line and then more context: ``` fix: prevent crash when user uploads empty file The application crashed because we tried to read the first byte of an empty file. Now we check file size before processing. Closes #142 ``` Use the body to explain: - **Why** this change was necessary - **What** was the problem or context - **How** does this approach solve it (if not obvious) ## Examples **Simple bug fix:** ``` fix: correct tax calculation for EU customers ``` **New feature:** ``` feat: add dark mode toggle to settings ``` **With context:** ``` refactor: split user service into smaller modules The user service had grown to 800 lines and was handling authentication, profile management, and notifications. Split into three focused modules for maintainability. ``` **Documentation:** ``` docs: add setup instructions for Windows ``` ## Quick Reference ``` : [optional body: why and how] [optional footer: references issues] ``` **Checklist:** - [ ] Starts with a prefix (`feat:`, `fix:`, etc.) - [ ] Uses imperative mood ("add" not "added") - [ ] First line under 50 characters - [ ] Explains why, not just what (for complex changes) ## Common Mistakes | Instead of... | Write... | |---------------|----------| | `fixed bug` | `fix: prevent null pointer in search` | | `updates` | `feat: add email notifications` | | `WIP` | `feat: add basic form validation` | | `stuff` | `chore: clean up unused imports` | | `fix: fix the bug` | `fix: handle empty input in calculator` | Your commit history tells the story of your project. Make it a story worth reading.