| name | git-history-discipline |
| description | Keep a project's git history enterprise-grade and audit-ready. Use on EVERY commit, branch, and PR: Conventional Commits, atomic changes, green-before-push, no secret ever committed, no rewriting published history, main/master stays deployable. |
| domain | engineering |
| subdomain | source-control |
| tags | ["git","conventional-commits","history","code-review","supply-chain"] |
| nist_csf | ["PR.IP-01","ID.SC-04"] |
| version | 1.0 |
| license | Apache-2.0 |
Git History Discipline
When to Use
Every commit, branch, and PR — especially on a system running in production or
handling real user/tenant data, where a bad commit is a potential incident, not a
cosmetic blemish. Treat the history as a permanent, reviewed artifact, doubly so if
a public mirror or open-source copy of the repo exists.
Workflow
- Conventional Commits.
type(scope): imperative subject (≤72 chars). Types:
feat, fix, chore, docs, test, refactor, build, ci, perf,
revert. Scope = a real package/area in the repo. Body explains why, not
just what; wrap ~72 chars; reference the relevant ticket/milestone where useful.
- Atomic commits. One logical change per commit; it builds and passes locally
on its own. No "wip", no mixed concerns, no giant dumps. History should read as a
clear story.
- Feature branches. Work on
feat/<slug> (or fix/…, chore/…), never
directly on the main branch. Open a PR with the change's acceptance checklist in
the body.
- Green before push — this is the real gate. Run the full local verification
(typecheck/build/test, and any deploy dry-run for touched services) and see it
pass before pushing. If CI is flaky, unavailable, or blocked for reasons
unrelated to code (billing, infra outage), the local green run is the authority —
don't chase a red CI badge that isn't actually reporting on your code, and don't
trust a watch command's exit code over the run's real recorded conclusion.
- No secret, ever. Real secrets — API keys, service credentials, connection
strings, signing keys — live in a secret manager (env-injected at runtime or a
dedicated secrets store), never in a tracked file, commit message, or log.
Local secret files (
.env, .dev.vars, etc.) are git-ignored. If you almost
typed a key into a tracked file, stop. Scrub logs to refs + hashes, never raw
payloads or tokens.
- Never rewrite published history. No force-push to the main branch or any
pushed shared branch; no history-altering rebase of merged work. Reverts go
forward (
git revert). This is doubly true if a public mirror exists.
- Main/master stays green and deployable. Every merge keeps the project
building and, where applicable, the live deployment working. Merge with
--no-ff so each integration point is visible in history; keep in-branch
commits clean before merging.
Verification
git log --oneline reads as a coherent, intentional story; each commit is atomic
and builds on its own.
- Every commit message has a real subject + a "why" body where non-trivial; scope
is a real area of the repo.
- No secret-shaped string in any diff; no real credential or connection string
appears in any tracked file.
- The full local verification gate was green before push — not just a green CI
badge.
- No force-push / history rewrite on the main branch; merges are
--no-ff.