How to write good commit messages and pull requests: a team guide
Commit messages and pull requests that teams love
- Conventional commits format
- Writing descriptive commit bodies linking commits to issues
- Squash vs merge commit strategies
- Crafting PR descriptions with context, screenshots, testing notes
- Review checklist making PRs easier to review
- Real examples
Conventional commits format
- Purpose: standardize how you describe changes so tooling and humans can quickly understand history.
- Structure: type(scope?): subject
- Types you’ll use most:
- feat: a new feature
- fix: a bug fix
- docs: documentation only changes
- style: formatting, missing semicolons, etc. No code logic
- refactor: code changes that neither fix a bug nor add a feature
- test: adding or updating tests
- chore: maintenance, build tooling, or dependencies
- Example: feat(auth): add login with OAuth2 flow
- Commit bodies: explain what and why, not just what changed
- Use three sections: Problem, Solution, Next steps
- Include any important decisions, trade-offs, and side effects
- Linking issues: reference issues with #NUMBER and, where supported, close them with keywords like “Closes #123” in the body
Descriptive commit bodies and linking to issues
- Why: you’ll thank the future you when tracing why a change happened.
- Anatomy:
- Short, imperative subject line (max ~50 characters)
- Blank line
- Body: motivation, approach, alternatives considered, and impact
- Footer: references to issues or breaking changes
- Example:
- Subject: fix(auth): gracefully handle missing refresh token
- Body:
- When the refresh token is missing, the user would see a 500 error.
- Now we return a 401 with a clear error message and log the incident.
- Previously we attempted a token refresh which caused obscure failures.
- Footer: Closes #245, Refs #310
Squash vs merge commit strategies
- Squash and merge
- Pros: a clean, linear history; single commit per PR
- Cons: loses individual commit history; harder to see incremental work
- Best for: small, cohesive PRs; teams wanting readable main branch history
- Merge commit (no-fast-forward)
- Pros: preserves complete history; context from each commit, useful for debugging
- Cons: history can become noisy with many small commits
- Best for: large PRs with meaningful, incremental changes
- Rebase and merge
- Pros: linear history with individual commits reapplied on top
- Cons: rewriting history; potential conflicts if branches diverge
- Best for: teams that prefer a clean, linear history but want to preserve original commits
- Practical guidance
- For feature work: use squash and merge to keep main concise.
- For long-running features or fixes requiring detailed history: use merge commits or rebase and merge.
- Align with your repo’s policy and tooling (e.g., CI, changelog generators).
Crafting PR descriptions with context, screenshots, testing notes
- Purpose: give reviewers enough context to understand the change without digging through code.
- Structure:
- Title: summarize the change (imperative, present tense)
- Why this change? (motivation and problem)
- What changed? (high-level overview, not line-by-line)
- How to test
- Screenshots or recordings (if UI)
- Known issues and limitations
- Related issues (IDs)
- Impact and rollout plan
- Testing notes
- Prerequisites: environment, data, feature flags
- Steps to reproduce: exact actions, expected vs actual results
- Automated tests: what tests passed/failed, any new tests added
- Manual testing checklist: smoketests, edge cases
- Screenshots
- Include before/after visuals if UI changes
- Annotate with arrows or captions for clarity
- Example PR description
- Title: feat(dashboard): add KPI widgets and drill-down capabilities
- Why: provide at-a-glance metrics to users
- What: adds three KPI widgets, drill-down on click to detailed view, responsive layout
- How to test:
- Open dashboard, ensure KPI cards render
- Click KPI to see detail pane
- Resize to mobile and verify layout
- Screenshots: [Attach before/after images]
- Tests: unit tests for widget data bindings; integration test for drill-down
- Related issues: Closes #1024
Review checklist to speed up PRs
- For authors
- [ ] Title is concise and imperative
- [ ] Description includes why, what, and testing steps
- [ ] Screenshots or videos included for UI changes
- [ ] Linked to related issues and breaking changes, if any
- [ ] Code changes follow conventions and have clear commit messages
- [ ] Tests updated or added; CI passing
- For reviewers
- [ ] Verify the problem statement matches the change
- [ ] Confirm tests cover critical paths
- [ ] Check for potential edge cases and performance implications
- [ ] Ensure no sensitive data is exposed in diffs or logs
- [ ] Provide actionable feedback with references to lines or components
Real-world example set
- Commit example 1
- Type: fix
- Scope: notification
- Subject: fix(notification): avoid null pointer when user unsubscribes
- Body:
- Problem: unsubscribing with active notification preferences could trigger a NPE.
- Solution: guard null fields and return a safe default.
- Impact: this won’t affect normal flows; reduces crash reports.
- Footer: Closes #512
- Commit example 2
- Type: feat
- Scope: analytics
- Subject: feat(analytics): add weekly digest email
- Body:
- Introduces a new digest endpoint that aggregates weekly activity and sends email.
- Uses existing email template and scheduling system.
- Footer: Related to #789
Putting it into practice: a mini workflow
- Before you start a PR
- Create a focused branch named feature/short-descr
- Write a clear, conventional-commit-friendly history locally
- Run tests and ensure green
- When opening a PR
- Use a concise title, reference related issues
- Add a descriptive body with testing steps and visuals
- Attach screenshots if UI changes
- Choose squash and merge or merge commit based on policy
- During review
- Respond with direct references to reviewer comments
- Update the PR description if you adjust scope or tests
- Re-run CI and attach results if changes were made
Would you like me to tailor this into a ready-to-publish guide for your team, including a customizable PR template and a small example repository snippet? If yes, tell me your repo’s preferred commit types and your squash/merge policy.
-
Rizwan Saleem | https://rizwansaleem.co
Top comments (0)