✅ Git Commit Best Practices (with Conventional Commits)
Conventional Commits provide a structured format for commit messages to improve:
- Automation (changelogs, releases)
- Consistency in teams
- Readability of Git history
🧩 Commit Format
<type>[optional scope]: <description> [optional body] [optional footer(s)]
📌 Common Types
| Type | Meaning | Example |
|---|---|---|
| A new feature | |
| A bug fix | |
| Documentation only | |
| Code style (formatting, missing semi-colons) | |
| Refactoring code, no feature/bug change | |
| Performance improvement | |
| Adding or fixing tests | |
| Other tasks (build, config, deps) | |
| CI/CD related changes | |
| Changes that affect the build system | |
✅ Examples
feat(auth): add JWT-based login fix(api): handle null user object in response docs: add usage examples to README refactor(user): split validation into utils chore(deps): update react to v18.2.0
🔁 Best Practices with Conventional Commits
- Keep subject line ≤ 50 characters
- Add an empty line before body/footers
- Body (optional): explain why and what was changed, if needed
- Footer (optional): references like or issue IDs
BREAKING CHANGE
Example with Body and Footer:
feat(payment): add Razorpay integration Allows users to pay using Razorpay as a new method. We needed this for the upcoming UPI launch in India. BREAKING CHANGE: payment module API has changed Fixes #123
🎯 Benefits of Adopting Conventional Commits
- Can auto-generate changelogs using standard-version
- Enables semantic versioning workflows
- Helps new developers understand commit purpose quickly
🧠 Tip: Set a Commit Template (.gitmessage
)
.gitmessageCreate a file like
~/.gitmessage.txt<type>(<scope>): <subject> <body> <footer>
Then run:
git config --global commit.template ~/.gitmessage.txt
📝 Blog Post Naming — Recap
- Use kebab-case
- Keep slugs short, descriptive, human-readable
- No need for dates in URLs unless you’re running a news-style blog
Example File Name:
2025-06-16-git-commit-best-practices-with-conventional-commits.md
Example Slug:
/blog/git-commit-best-practices-conventional
🔥 Extended Guide to Git Commit Best Practices
(incl. Conventional Commits,
!BREAKING CHANGE🧠 1. How Focused Should a Commit Be?
- One logical change per commit.
- ✅
fix: correct login redirect - ✅
refactor: move auth logic to middleware - ❌
fix login + added new navbar + bumped package.json
- ✅
- Group related changes:
- ✅ You updated both code and related test: okay
- ❌ You added a feature and updated docs for an unrelated one: split it
📦 2. How Many Commits Per Pull Request?
✅ Good Practices:
- 3–10 commits is a good average
- Small PRs (up to 400 LOC change) are ideal
- Commit logically, but squash before merge unless you’re on a trunk-based or linear history strategy
🏷️ 3. Conventional Commits – Advanced Usage
❗ Use of !
to Mark Breaking Changes
!Add a
!feat!: drop support for Node 14 refactor(core)!: remove deprecated user props
Or in the footer:
feat(api): update auth token format BREAKING CHANGE: auth tokens now use JWT instead of session IDs
🚨 Always explain what breaks and how to fix it in the body or footer.
✅ Examples with Symbols
feat!: remove deprecated `authUser` method docs(readme): update usage for new API ⚠️ fix(api): handle 500 error on missing header refactor(utils): rename `is_valid` → `isValid`
Emoji is optional, but some teams use them in the subject line as visual markers (e.g.,
,🎨,🧪).🐛
🔄 4. Pull Request Best Practices
✅ Structure of a Good PR
| Item | Description |
|---|---|
| ✅ Title | Match main commit or feature name |
| ✅ Description | What changed, why, and any side-effects |
| ✅ Linked issues | |
| ✅ Checklist | Tests added, docs updated, self-reviewed |
| ✅ Screenshots | For UI changes |
👀 Reviewing & Merging PRs
⛔ Avoid:
- Merging without review (unless small & trusted)
- Large PRs with 1000+ lines unless discussed first
✅ Prefer:
- if your team values clean history
Squash and merge - Regular rebasing (not merging) to keep feature branch up to date
- Resolve conflicts before review
🔒 PR Hygiene
- Avoid WIP commits in PR unless you’re pairing live
❌
WIP: testing something
✅ Squash or reword before merge - Never push secrets, , or big binaries
.env
Add
,.gitignore, and setup pre-commit linting/hooks.gitattributes
🛠️ Bonus: Tools You Can Use
| Tool | Use Case |
|---|---|
| Enforce Conventional Commits locally |
| Add Git hooks to run linters/formatters |
| Auto-generate changelogs from commits |
| GitHub Actions / GitLab CI | Auto-run tests & enforce linting |
🧪 Sample PR Template (for GitHub)
Create
.github/PULL_REQUEST_TEMPLATE.md## What changed? - Added new payment integration - Refactored old checkout logic ## Why? Fixes #123 — We need UPI support for Indian users. ## Checklist - [ ] Tests added - [ ] Docs updated - [x] Lint passed - [ ] No secrets committed
💡 Summary TL;DR
- One purpose per commit
- Follow Conventional Commit format, use for breaking
! - Pull requests should be small, focused, and reviewed
- Use tools to enforce style & history discipline
- Document everything that isn’t obvious
