You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The convention requires the subject of a WIP: commit to begin with the type of the
in-progress commit, but it does not say where the breaking change marker ! belongs when that
in-progress commit is a breaking change. Three forms are possible and the document endorses
none of them.
What the document says
§1 defines the header as <type>[optional scope][!]: <subject>, so ! follows the type
(and scope, if present).
§1 also states that a breaking change "can be part of commits of any type, except deprecate:, test:, ci:, style: and docs:". WIP is not in that list, so WIP!:
is permitted by omission rather than by design.
§WIP commits requires the subject to begin with the type of the in-progress commit,
followed by its subject. Commit Header Length Exception for Reverts #61 phrases the parallel revert: rule as "followed by the full
header of the original commit", which would carry the ! into the embedded header.
The string WIP! does not appear anywhere in the document.
The three forms
Form
Marker position
WIP: feat!: foo
Embedded header only
WIP!: feat!: foo
Both positions
WIP!: feat: foo
Prefix only
The prior question: which position carries the meaning?
The marker can be written on the WIP: prefix, on the embedded type, or on both, and §1 does
not say which position is authoritative for a WIP commit. That has to be settled first,
because the valid forms follow from it.
Reading A — the embedded header is authoritative. The subject of a WIP commit is the full
header of the commit it will become, so the ! belongs there, exactly as it will read after
squashing. The type of the WIP commit is WIP, which is not itself a breaking change.
Arguments: squashing reduces to deleting the WIP: prefix, which is the property the
requirement exists to preserve; any other form has to be edited at squash time. And the WIP
commit itself will never appear in the permanent history, so marking its prefix asserts
something about a commit that will not exist.
Valid form: WIP: feat!: foo. A ! on the prefix is redundant, and WIP!: feat: foo is
contradictory.
Reading B — the prefix is authoritative. §1 defines the marker as following the type, and
the type of the commit is WIP. A ! sitting inside the subject is not in the position §1
gives it meaning, so under a strict reading WIP: feat!: foo is a non-breaking WIP commit
whose subject happens to contain an exclamation mark.
Arguments: it is what §1 says, read literally; and the breaking change is visible in the
type position of the header without parsing the subject.
Valid form: WIP!: feat: foo, or WIP!: feat!: foo if the embedded header is to read
exactly as it will after squashing.
The two readings disagree about WIP!: feat: foo — contradictory under A, correct under B —
which is why the reading has to be stated rather than assumed.
Should both spellings be allowed?
Only Reading A leaves room for the question, since it is the reading under which a prefix
marker is optional rather than meaningful. There, allowing both means WIP: feat!: foo and WIP!: feat!: foo are equally valid, differing only in whether the breaking change is stated
once or twice.
For: nothing depends on the duplication, since the embedded header is authoritative, so
there is little to gain by legislating it; and a reader skimming git log --oneline sees the
flag in the type position without parsing the subject.
Against: it produces two valid spellings of one fact, which is the kind of variation a
convention exists to remove.
Note on the header budget
WIP!: costs six characters rather than five. #73 proposes an allowance of 77 characters
(72 + 5), which covers WIP: only, and it does not discuss WIP!: . So if WIP!: turns out
to be a valid form here, #73 needs a companion number of 78 — or a wording that measures the
header with the prefix removed, whatever its length.
This issue takes the convention as written, which requires the subject of a WIP commit to
begin with the type of the in-progress commit. #72 asks whether that requirement should be
kept, made optional, or removed, and the outcome there changes the wording needed here:
if the type stays required, the resolution is a choice between Reading A and Reading B,
plus the optionality question if A is chosen;
if the type becomes optional, the rule must also say what WIP!: means when no type is
present — presumably the only remaining way to mark a work-in-progress breaking change;
if the type is forbidden, WIP!: becomes the only place the marker can appear, and
forbidding it too would make breaking changes inexpressible until the commit is squashed.
The substance of the question is unaffected either way: a breaking in-progress commit needs a
defined place for its marker.
Summary
The convention requires the subject of a
WIP:commit to begin with the type of thein-progress commit, but it does not say where the breaking change marker
!belongs when thatin-progress commit is a breaking change. Three forms are possible and the document endorses
none of them.
What the document says
<type>[optional scope][!]: <subject>, so!follows the type(and scope, if present).
deprecate:,test:,ci:,style:anddocs:".WIPis not in that list, soWIP!:is permitted by omission rather than by design.
followed by its subject. Commit Header Length Exception for Reverts #61 phrases the parallel
revert:rule as "followed by the fullheader of the original commit", which would carry the
!into the embedded header.WIP!does not appear anywhere in the document.The three forms
WIP: feat!: fooWIP!: feat!: fooWIP!: feat: fooThe prior question: which position carries the meaning?
The marker can be written on the
WIP:prefix, on the embedded type, or on both, and §1 doesnot say which position is authoritative for a WIP commit. That has to be settled first,
because the valid forms follow from it.
Reading A — the embedded header is authoritative. The subject of a WIP commit is the full
header of the commit it will become, so the
!belongs there, exactly as it will read aftersquashing. The type of the WIP commit is
WIP, which is not itself a breaking change.WIP:prefix, which is the property therequirement exists to preserve; any other form has to be edited at squash time. And the WIP
commit itself will never appear in the permanent history, so marking its prefix asserts
something about a commit that will not exist.
WIP: feat!: foo. A!on the prefix is redundant, andWIP!: feat: fooiscontradictory.
Reading B — the prefix is authoritative. §1 defines the marker as following the type, and
the type of the commit is
WIP. A!sitting inside the subject is not in the position §1gives it meaning, so under a strict reading
WIP: feat!: foois a non-breaking WIP commitwhose subject happens to contain an exclamation mark.
type position of the header without parsing the subject.
WIP!: feat: foo, orWIP!: feat!: fooif the embedded header is to readexactly as it will after squashing.
The two readings disagree about
WIP!: feat: foo— contradictory under A, correct under B —which is why the reading has to be stated rather than assumed.
Should both spellings be allowed?
Only Reading A leaves room for the question, since it is the reading under which a prefix
marker is optional rather than meaningful. There, allowing both means
WIP: feat!: fooandWIP!: feat!: fooare equally valid, differing only in whether the breaking change is statedonce or twice.
there is little to gain by legislating it; and a reader skimming
git log --onelinesees theflag in the type position without parsing the subject.
convention exists to remove.
Note on the header budget
WIP!:costs six characters rather than five. #73 proposes an allowance of 77 characters(72 + 5), which covers
WIP:only, and it does not discussWIP!:. So ifWIP!:turns outto be a valid form here, #73 needs a companion number of 78 — or a wording that measures the
header with the prefix removed, whatever its length.
Relationship with #72
This issue takes the convention as written, which requires the subject of a WIP commit to
begin with the type of the in-progress commit. #72 asks whether that requirement should be
kept, made optional, or removed, and the outcome there changes the wording needed here:
plus the optionality question if A is chosen;
WIP!:means when no type ispresent — presumably the only remaining way to mark a work-in-progress breaking change;
WIP!:becomes the only place the marker can appear, andforbidding it too would make breaking changes inexpressible until the commit is squashed.
The substance of the question is unaffected either way: a breaking in-progress commit needs a
defined place for its marker.