git log --oneline has to be readable a
year later by someone who was not there.
The format
type — one of:
feat and fix are the two that matter to an operator reading release notes.
If a change is neither, it is not a feat dressed up to look productive.
scope — the part of the system the change belongs to. Use the domain or
surface name in lower case:
tenancy, flow, messaging, contact, assistant, channels, media,
conversation, broadcasting, staff, webhook, builder, admin,
gateway, foundation, support, ci, deps, docker.
A change that spans two domains lists both, comma-separated and without a
space: feat(flow,contact): …. A change that spans more than two probably has
no single scope — leave it off rather than listing five.
subject — what the change does, in the imperative, lower case, no trailing
period, under 72 characters including the prefix. Read it as completing the
sentence “this commit will …”:
Breaking changes
A change that breaks an existing contract — a Flow node handler, the webhook payload, a configuration key, anything on the extension surface — carries! after the scope
and a BREAKING CHANGE: footer that says what an operator or extension author
has to do about it:
Body and footer
The body explains why, when the subject cannot. What the code does is visible in the diff; what the alternatives were and why this one was chosen is not. Wrap at 72 characters. Skip the body when the subject is the whole story — mostchore and docs commits need none.
The footer links the change to the world outside git:
Closes #n on the pull request closes the issue when it merges.
Commits on a branch versus the pull request title
Pull requests are squash-merged, so the commits on the branch are for the author and the reviewer, and the pull request title is what lands onmain. That has two consequences:
- Branch commits may be rough —
wip,fix test,address revieware fine there. Do not spend time rewriting branch history to look tidy. - The pull request title is held to the full format above, including
!and the scope, because it is the commit everyone will see. When the pull request has aBREAKING CHANGE:footer, put it in the description and it will be kept in the squash commit body.
Reverts
A revert is an ordinary pull request whose title isrevert: <original title>
and whose body names the commit being reverted and why. git revert produces
the right starting point; edit the message into the format rather than keeping
the default one.