conventionalcommits.org
conventionalcommits.org copied to clipboard
After v1: About footer(s), git trailers and "multiple footers"
The 3rd bullet in this list https://github.com/conventional-commits/conventionalcommits.org/pull/175#issuecomment-536398716 and the following comments after it.
I don't see any difference with git trailers, as @bcoe said in one of the comments. Each token/value pair is a trailer. What's the difference between "multiple footers" and "git trailers"? In abstract world, they are children of the footer.
CommitMessage
/ | \
/ | \
Header Body Footer
/ | \ | |
type scope subject paragraphs trailers
* "subject" is officially called description
I see and always have seen it that way. Associations are a good thing. Such little details make difference. For the same reason I like more feat!(cli): foo
instead of feat(cli)!: foo
- it might be a bit easier to parse, it's more consitent when there is no scope (feat!: foo
), and feels similar to function invocation of some languages. But that's a different topic.
Example commit message:
feat: meow meow, yawn
foo qux
bar
var
zero barry
deal
Reviewed-by: Zzz oops
Some-thing: Multiline important
trailer woohoo
meow meow
Why not?
yup!
Signed-off-by: Foo <[email protected]>
It could get parsed to the following object:
const commit = {
header: {
type: 'feat',
scope: null,
subject: 'meow meow, yawn'
},
body: 'foo qux\n\nbar\nvar\n\nzero barry\ndeal',
footer: {
trailers: [
'Reviewed-by: Zzz oops',
'Some-thing: Multiline important\n\ntrailer woohoo\nmeow meow\n\nWhy not?\nyup!',
'Signed-off-by: Foo <[email protected]>'
],
trailer: {
'Reviewed-by': 'Zzz ooops',
'Some-thing': 'Multiline important\n\ntrailer woohoo\nmeow meow\n\nWhy not?\nyup!',
'Signed-off-by': 'Foo <[email protected]>',
},
raw: `Reviewed-by: Zzz oops
Some-thing: Multiline important
trailer woohoo
meow meow
Why not?
yup!
Signed-off-by: Foo <[email protected]>`,
},
};
In the commit.footer
object, some more advanced parser, could add more things such as mentions
, references (based on trailers), and etc.
The two differences are:
- Only
:<space>
and<space>#
are supported as separators - No spacing is required before a line belonging to a trailer that is not on the same line as the trailer key
That, and the fact that a footer doesn’t really exist in the sense that there can only be trailers in a footer, nothing else, is why I suggested the new wording.
Having said that, I don’t have too strong an opinion on this, using existing terminology is definitely a goal worth perusing, as long as it doesn’t cause too much confusion when the implementation itself deviates too much from what people expect to see when they read that terminology.
@JeanMertz @tunnckoCore we've been working to formalize the Conventional Commit grammar:
https://github.com/conventional-commits/parser#the-grammar
Perhaps we could move this conversation there? my hope is that we can formally define the grammar, with a reference implementation, and then map this back into v2.0.0
of the spec.
I think human terminology should come before formal grammar. Specification should specify all details sufficiently for implementation. At the current state Conventional Commit specification doesn't exhibit this property.
As a result, tools like commitlint
have to invent their own terminology. Here is how commitlint
parses a message.
{
type: null,
scope: null,
subject: null,
merge: null,
header: 'BREAKING CHANGE: this one',
body: null,
footer: null,
notes: [],
references: [],
mentions: [],
revert: null,
raw: 'BREAKING CHANGE: this one'
}
Here at least subject
and header
are critical for parsers, but are not defined in the spec. It is also not clear how breaking !
is named and where it belongs.