Git Standards & Commit Conventions¶
Status: 🟢 Active | Owner: Engineering Enablement | Last Reviewed: 2025-Q4
Overview¶
Consistent git hygiene is the foundation of a navigable project history. Good commit messages make it possible to understand why a change was made months later, to generate meaningful changelogs, and to efficiently bisect bugs. These standards apply to every repository in the organisation.
Required Git Configuration¶
All engineers must configure git with their full name and organisational email address. These are verified by the pre-commit hook framework.
git config --global user.name "Your Full Name"
git config --global user.email "[email protected]"
git config --global core.autocrlf false # Never convert line endings
git config --global core.eol lf # Always use LF
git config --global pull.rebase true # Rebase on pull, never merge
git config --global push.default current # Push current branch by default
git config --global init.defaultBranch main
Commit Message Format: Conventional Commits¶
All commits must follow the Conventional Commits specification. This format is enforced by a commitlint pre-commit hook.
Format¶
Rules¶
- Subject line: Maximum 72 characters. Imperative mood ("add feature", not "added feature" or "adds feature"). No period at the end.
- Body: Optional. Wrap at 72 characters. Explain what and why, not how.
- Footer: Used for breaking change notices and issue references.
Allowed Types¶
| Type | When to Use |
|---|---|
feat | A new feature (triggers MINOR version bump) |
fix | A bug fix (triggers PATCH version bump) |
docs | Documentation changes only |
style | Formatting, whitespace — no logic change |
refactor | Code restructuring without feature change or bug fix |
perf | Performance improvement |
test | Adding or updating tests |
chore | Build process, dependency updates, CI configuration |
ci | CI/CD configuration changes |
revert | Reverts a previous commit |
Breaking Changes¶
Breaking changes are indicated by: 1. BREAKING CHANGE: in the footer, OR 2. ! after the type/scope: feat(api)!: remove deprecated v1 endpoints
Both trigger a MAJOR version bump in automated release tooling.
Examples¶
feat(orders): add discount code validation
Validate discount codes against the promotions service before applying
them to an order. Invalid or expired codes now return a 422 with a
descriptive error message.
Closes PROJ-1234
---
fix(payments): prevent double-charge on network timeout
When the payment provider returns a timeout, we were retrying without
checking for idempotency, causing duplicate charges. Added idempotency
key to all payment requests.
Fixes PROJ-5678
---
feat(api)!: remove deprecated v1 order endpoints
The /api/v1/orders endpoints deprecated in v2.3.0 have been removed.
All consumers must migrate to /api/v2/orders before upgrading.
BREAKING CHANGE: /api/v1/orders/* endpoints removed. Migrate to /api/v2/orders/*.
---
chore: upgrade Spring Boot to 3.2.4
Includes security fixes for CVE-2024-XXXXX.
Commit Discipline¶
Atomic Commits¶
Each commit represents a single, complete, logical change. A commit should be deployable on its own — it should not leave the system in a partially broken state.
- ✅ Good: "fix: correct VAT calculation for EU orders"
- ❌ Bad: "WIP", "temp", "fix tests", "misc changes"
What Not to Commit¶
- Secrets: API keys, passwords, tokens — use the secrets manager. Gitleaks pre-commit hook blocks secret commits.
- Build artefacts:
.jar,.class,.pyc,node_modules/,dist/— add to.gitignore. - IDE configuration:
.idea/,.vscode/(with exceptions for shared workspace settings) — add to.gitignore. - OS files:
.DS_Store,Thumbs.db— add to global.gitignore. - Commented-out code: Delete it. The history has it.
Commit Size¶
Keep commits small and focused. A commit that changes 20 files across 5 different concerns will be impossible to review or revert cleanly. If you find yourself writing "and" in a commit message, consider splitting the commit.
Signed Commits¶
All commits to main (and all PR commits) must be GPG or SSH signed. See Signed Commits Policy for setup instructions.
GitHub enforces this via branch protection rules — unsigned commits cannot be merged to protected branches.
Interactive Rebase Before PR¶
Before opening a pull request, clean up your commit history with interactive rebase: - Squash "fix tests" and "WIP" commits into the logical commits they belong to. - Ensure each commit in the PR is atomic and has a proper conventional commit message. - Rebase onto the latest main to avoid merge conflicts.
# Interactively rebase the last 4 commits
git rebase -i HEAD~4
# Rebase onto latest main
git fetch origin && git rebase origin/main
References¶
Last reviewed: 2025-Q4 | Owner: Engineering Enablement