Skip to content

Clarify where the breaking change marker belongs in a WIP commit #74

Description

@javier-godoy

Summary

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.

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:

  • 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions