conventionalcommits.org icon indicating copy to clipboard operation
conventionalcommits.org copied to clipboard

After v1: About footer(s), git trailers and "multiple footers"

Open tunnckoCore opened this issue 5 years ago • 3 comments

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.

tunnckoCore avatar Oct 01 '19 00:10 tunnckoCore

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 avatar Oct 01 '19 06:10 JeanMertz

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

bcoe avatar Dec 24 '20 21:12 bcoe

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.

abitrolly avatar Jan 05 '24 09:01 abitrolly