mirror of
https://github.com/conventional-commits/conventionalcommits.org.git
synced 2026-03-23 06:01:43 -05:00
Proposal to resolve body/footer ambiguity and support Git trailers #74
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @JeanMertz on GitHub (Aug 17, 2019).
There is some ongoing confusion (and an ongoing discussion) about the spec when it comes to both the body of a commit message, and the footer.
Here is what the spec says:
I've highlighted the parts that I wanted to discuss in this issue, and hopefully find consensus on.
Reading the current spec, there are a few problems that arise from it:
BREAKING CHANGEcan be in multiple positions, which can cause confusion.Given the above points, I would like to propose to change the definition of the footer as follows:
<key><sep><value>.<key>MUST be eitherBREAKING CHANGE1 or be one or more words, grouped by hyphens (e.g.Co-Authored-By,fixes, etc.).<sep>MUST be one of:<space>or<space>#, supporting bothCo-Authored-By: Lisa Simpson <lisa@simpsons.com>andFixes #999.<value>MUST be present, and can contain any characters, either on a single line, split over multiple lines, or split over multiple paragraphs.1: This one is for backward compatibility with the current spec, or we could change it to be
breaking-change(case insensitive).I think the above description is preferred, because:
I hope this all makes sense. I like using conventional commits, first for its informative and readable nature, second for the possibilities it brings in terms of automating auxiliary tasks related to Git projects. I think this proposal improves both use-cases.
@JeanMertz commented on GitHub (Aug 19, 2019):
I made a proof of concept implementation of a parser for this change in the specification.
It supports a commit like this:
With
BREAKING CHANGE,Co-Authored-ByandCloseseach their own trailer.You can check out the example here:
https://docs.rs/conventional/0.4.1/conventional/#example
@bcoe commented on GitHub (Aug 20, 2019):
@JeanMertz this is great work, I was leaning towards git trailers as well (I didn't realize they had a name) I think this is a great way to eliminate ambiguity even though it adds a bit more complexity to the spec.
My only concern would be weird edge-cases where someone has a
:after the first word in a paragraph, e.g., perhaps they're listing something:features: apple, banana, orange.@blowmage commented on GitHub (Aug 20, 2019):
My concern here is that there are times when having more time to describe a change is incredibly useful. Now that the footer is defined as one or more trailers, why not parse out the trailers and leave what is left as the body? How would a footer use a non-trailer paragraph anyway?
@bcoe commented on GitHub (Aug 20, 2019):
@blowmage, @JeanMertz is listing:
as a shortcoming of the current specification, his proposal would allow for multi paragraph bodies, I think he basically describes exactly the format used by Node.js:
I think it's great that this addition to the conventional commit specification puts us in the position to support Node's commit format.
@blowmage commented on GitHub (Aug 20, 2019):
Ah, this is what tripped me up:
As long as the footer doesn't start at the first blank line, and instead of a collection of all trailers, then I think it is a good change.
@epage commented on GitHub (Aug 20, 2019):
Sounds like this is more strict than git's definition of a trailer. Do we need to be so strict that
BREAKING CHANGEis a special case?@JeanMertz commented on GitHub (Aug 20, 2019):
The reason for being a bit more strict is exactly to minimize the risk that @bcoe mentions in their comment:
By only supporting single words or words with hyphens or BREAKING CHANGE, followed by exactly “: “ or " #“, we minimize the number of false positives.
Also, looking at the Git wiki itself all of the trailers there would match the spec I defined. The contributions guide also talks about trailers only in their singular word or hyphenated words form.
Perhaps one of you can think of another way, or an additional way to make this less ambiguous?
@JeanMertz commented on GitHub (Aug 20, 2019):
My thinking was that requiring a blank line directly followed by a valid trailer does limit the chances of false positives even further. But indeed, it does not completely eliminate it.
Perhaps we want to require two blank lines before the footer? That would make it very unlikely to trigger this accidentally, at the cost of a bit more complexity.
Still though, I feel like that goes against what most people already do naturally by adding “Fixes #12” at the bottom of a message, which my proposal would pick up, but requiring two blank lines would probably mean most people forget and their trailers aren’t registered because of the missing extra blank line.
Thinking about this, I feel like what I proposed strikes the best balance between simplicity and accuracy, but I welcome any addition that increases the accuracy without decreasing the simplicity.
@epage commented on GitHub (Aug 21, 2019):
So in my mind, the inputs to this discussion are
Fixes #10)and I'm assuming defining traits we are aiming for include:
So from that, some questions about the spec and example
Note: I try to use "trailer" when talking about git conventions and "footer" when talking about Conventional to try to keep the different definitions straight.
Will git tools that parse trailers misidentify sections with
<space>#as not trailer? Should we instead require footers to at minimum have:which github at least seems to support (Fixes: #10works)This does not specify how multi-line footers are handled. Git says multi-line trailers have their 2+ lines indented. Do we need these to be recognized by git trailer tools? Should we conform to git's rules on multi-line trailers?
I am confused at the need for multi-paragraph footers. The intention of trailers is metadata and I assume the intention for footers is the same. What is the use case for multiple paragraphs? Can we simplify things by removing this? If we use git's rules for multi-line, can we even support this?
Related:
For this example, I'm assuming
BREAKING CHANGEis a footer? I'm assuming this works because you can have multiple footer sections? I didn't see this in the spec, is it just implied? Should we be more explicit?Do git trailer tools understand multiple trailer sections? Do we care?
@epage commented on GitHub (Aug 21, 2019):
If the goal is to be as restrictive as possible while still being compatible with most people, I think I prefer being a bit more consistent and adopting your recommendation for
Breaking-Changeinstead.Speaking of, case sensitivity, before we didn't have a way to identify keys from values. Currently, the
typeandscopeare case insensitive. Are footer keys? Do we need to include that?@tunnckoCore commented on GitHub (Aug 21, 2019):
Hm. Really like that one. But the text of the spec may be a bit more simpler and not confusing for beginners. As @blowmage said: parse out the trailers and leave what is left as the body. Everything before the first trailer is considered
body, everything after (including the first trailer) is consideredfooter. So, we never will have footer if there are no trailers. Which is a pretty clean thing.This easily can be handled as "most common case". The following still will be valid:
Otherwise, require 2 blank lines
Btw, the first line of commit message I like to call "header" and that's why in
parse-commit-messageabove in future can return something like thisWhere the
footer.trailerscan be array or object, still not sure, but would be cool to have all the trailers parsed too. Anyway, that's for the future.Overall, I like the idea and also with the
!for breaking change, the things get even prettier.edit: Kind of off-topic a bit. But, is it better the
!to be required to always be after the type, no matter there is scope or not.So
and
So...
<type>[optional breaking change][optional scope]: <description>I missed the discussion there and initially, I was against it but... I think this way it looks better and probably a bit easier to parse. Also, looks like Rust function call (and other languages?).
@JeanMertz commented on GitHub (Aug 22, 2019):
Git supports configuring the separator. I went with
:<space>and<space>#because it covers most common use-cases without over-generalising things.I don't think we should, because brain muscle has thought people to use
closes #xin their commit messages, and this fits with the fact that Git actually supports custom trailer separators.This is a valid point that I left out of my reasoning. Basically, I wanted to keep things a bit simpler. Git is a bit vague on their formatting, but from what I can tell, if you start the next line of a trailer with at least one space, it's part of the trailer.
Since that again is not how most people write their commit messages, I figured it would be best to also support multi-line trailers without the preceding whitespace. It basically trades correctness for convenience, which I thought was the correct trade-off in this case.
I think I've explained this before, but breaking changes very often require more than one paragraph. For example, I like to include specific code examples in my breaking change messages to let people know what they need to update in their code to make it work again. I do this by using markdown code block fences which requires separate paragraphs.
For me this is a big deal, without multi-paragraph trailer support, the support for properly parsing breaking changes falls flat.
I'm not quite sure what you mean. In the spec I wrote a footer isn't really a thing (we could even omit it from the spec wording). Whenever the first trailer is detected, anything below that is either 1) a paragraph part of the "active trailer" (the last trailer key+sep found), or the start of a new trailer.
So in the example,
BREAKING CHANGEis simply the first trailer the parser encounters, and any text/whitespace/... after that is part of that first trailer. until it finds the start of a second trailer.I don't have a strong opinion on that, I'm fine either way, but figured people are already using
BREAKING CHANGE, so there's little harm in keep support for that.We probably should mention it 👍 and they shouldn't be case sensitive, it's just a convention used by people using git trailers, so we could at least add it to the FAQ.
This is indeed exactly how the parser I wrote currently does this, and is how I intended to write the spec, but maybe my wording isn't clear enough?
Correct, and the parser currently takes that into account. So basically, after the header, there should be blank line, then EITHER the body, or the first trailer, if a body is present, then after that should be another blank line before the first trailer starts.
I'll take some time this weekend to create a PR with my proposal and the suggestions made in this issue, so we have something concrete to further discuss, and can use inline comments to the relevant sections, instead of having to quote everyone all the time while replying 😅.
@epage commented on GitHub (Aug 23, 2019):
I'm all for people writing commit bodies as naturally as possible. The part I'd question is how much of a habit people have formed for footers/trailers.
Does this belong in the trailer though or should this be in the body? In my mind, long descriptions belong in the body while trailers should be succinct metadata.
@bcoe commented on GitHub (Aug 26, 2019):
@tommywo convince you to chime in on this topic, promises to have a real influence on the future of the conventional commit parsers we've been working on.
@bcoe commented on GitHub (Sep 7, 2019):
addressed in https://github.com/conventional-commits/conventionalcommits.org/pull/185
@LemmingAvalanche commented on GitHub (Mar 20, 2024):
The current specification seems pretty compatible with trailers if you use the correct optional features. So here’s what I would have done (years back).
Use trailers syntax with mandatory
:<space>separator since that comes out of the box without configurationNow whatever implementation can be validated with
git interpret-trailersDemand (or recommend)
BREAKING-CHANGEvariant (hyphen) if used in trailers section becauseBREAKING CHANGE(space) forcesgit intepret-trailersto ignore the rest of the trailers (it’s no longer a trailers block)Allow multi-paragraph
BREAKING-CHANGE(since that is not supported by trailers) with the special rule that.on an empty line is the same as a blank line (paragraph break)This looks compatible with the current specification.
@LemmingAvalanche commented on GitHub (Dec 11, 2024):
This wouldn’t have worked. git(1) normalizes commit messages by default (default
commit.cleanupconfig) by (among other things) collapsing runs of blank lines to single blank lines.See git-stripspace(1).