Wow I can’t believe I’ve never heard of git trailers. This is so much better than conventional commits but you can still keep the same automation workflow you have with those. So grateful for the writeup.
You can do both (and we do in my team). Trailers are just another form of convention for in-band metadata. It’s put into the commit message body, so it’s not like it’s special to the commit object at all.
Recording statistics in tag trailers seems weird - can’t you calculate them live after all? I suppose that assumes there’s a unique previous tag to compare to.
It’s interesting, and a little bit sad, that we have trailers rather than using the git commit object headers.
A commit object starts with a sequence of key value pairs describing the author, commit date, and a couple more pieces of metadata. Both the format and the git implementation allow additional headers to be stuffed in the same place.
On the one hand, it’s undeniably useful. Along with the associated trailer.config options, it’s a way to impose a little bit of structure on the raw strings you append to the commit message.
But it seems like there’s no support for using these kinds of flags to append data to git-notes, which seems like an oversight. All that “append if exists” logic would be useful there, too.
It would be great if trailers could be attached to a commit without modifying its commit message, thus preserving its commit ID. In this way you could take a signed commit (or a signed tag) and add your “Reviewed-By:” trailer without making the new history incompatible with the original one.
git show and git log could show these new trailers objects after the commit text, as if they were part of the original commit message.
I’ll echo the sibling comments about git notes, and shout out to Gerrit where review information is tucked under refs/notes/review. Once notes.displayRef is rigged correctly, UI-wise notes and trailers become mostly indistinguishable.
(One of the things I miss since moving to GitLab… Need to teach forge to add MR metadata to magit-revision-sections-hook someday)
magit/forge is a Magit extension that integrates issues & pull-requests in the UI. Brought it up because Magit presents Gerrit review notes like @gioele suggests…
… i.e. adding review context right after the author’s commit message.
(Sorry for the lack of context; self-conscious about Emacs proselytism. Was hoping the magit name-drop would clarify that forge is “an Emacs thing”)
Since the mask is off, and to get back to trailers proper, might as well mention: Magit has dedicated commands for inserting trailers, with completion on known authors; figure it’s worth mentioning since the manual doesn’t call them such.
I’ve used the Co-Authored-By one a couple of times; wondering how handy the others are though, considering projects where (a) reviewers send their acknowledgements over email (b) committers scrap them with b4 trailers.
We ended up using Git trailers at GitLab for generating changelogs, and I later built a standalone tool basically doing the same thing. It works quite well, and feels much more natural compared to the metadata tags e.g. conventional commit wants you to use. You also don’t have to try and cram all the data onto a single subject line.
I’m not sure why trailers never really caught on beyond Signed-off-by. What probably doesn’t help is that they are a bit of a pain to parse reliably, such that you basically end up having to use the git CLI to ensure proper parsing.
I’m not sure why trailers never really caught on beyond Signed-off-by.
I use Git for at least 11 years now and this is the first time I hear about them, might be one reason that is shared by many. 😁
I absolutely will start using them, as of today.
EDIT: Oh, and I absolutely will inspect your tool (I see it’s based on make which is understandable but a tad disappointing as well) and see if I can apply it to my work.
The tool isn’t based on Make at all, there’s just a Makefile for running some release related tasks (e.g. tagging a new release). clogs only needs Git at runtime.
Serves me right for not looking deeper, thanks. I vaguely remember reading about Inko some months ago and liked but never tried it. Are you happy with it, by the way?
It really comes down to tooling showing you I guess. E.g. Gerrit puts a bunch of them in, and thus in such code bases people also start to use it for other variations, and spread it elsewhere.
What’s the etymology behind “trailers” ? I assume it comes from “Data we add which trails behind the commit message”, but where’d that come from and when?
It is a bit odd because I think these would typically be called “footers”. Head/foot vs. head/tail vs. header/trailer…seems like somebody got their metaphors mixed up.
In RFC 2068 chunked transfer encoding it was called a “footer”, but in RFC 2616 it was renamed to “trailer” and a Trailer: header was added so you could predeclare in your Trailer: header which headers will appear in your trailer. (Yes I know nowadays HTTP bods prefer to call them “fields” but I prefer the original name.) The httpwg archives suggest “footer” was given the boot in 1997 about half a year after RFC 2068 was published.
Same as e-mail headers and trailers, and HTTP headers and trailers. In fact it’s literally the same format: note the two spaces line continuation format.
It would be nice if GitHub gave you a way to add these when you, for example, squash and merge a PR (which generates a new commit). Even if the default behavior was to maybe take the union of the trailers for all component commits, it wouldn’t be perfect but it would make this feasible for squash-based workflows.
If anyone is wondering whether GitHub recognizes any trailers (e.g., to reference/close an issue), it appears it does not but has its own ad hoc “phrases” (references: one, two).
Upvoting if only b/c I’d love for this approach to win out over the unpleasant line noise that is Conventional Commits
Wow I can’t believe I’ve never heard of git trailers. This is so much better than conventional commits but you can still keep the same automation workflow you have with those. So grateful for the writeup.
You can do both (and we do in my team). Trailers are just another form of convention for in-band metadata. It’s put into the commit message body, so it’s not like it’s special to the commit object at all.
Recording statistics in tag trailers seems weird - can’t you calculate them live after all? I suppose that assumes there’s a unique previous tag to compare to.
It’s interesting, and a little bit sad, that we have trailers rather than using the git commit object headers.
A commit object starts with a sequence of key value pairs describing the author, commit date, and a couple more pieces of metadata. Both the format and the git implementation allow additional headers to be stuffed in the same place.
This is one of those Git features where unfortunately some commands do the same thing in orthogonal ways:
git commit -saddsSigned-off-by: $name <$email>git cherry-pick -xadds(cherry picked from commit $hash)Would be great if they’d chosen
Cherry-picked-from: $hashinstead! I wonder which came first.Agreed.
On the one hand, it’s undeniably useful. Along with the associated
trailer.config options, it’s a way to impose a little bit of structure on the raw strings you append to the commit message.But it seems like there’s no support for using these kinds of flags to append data to
git-notes, which seems like an oversight. All that “append if exists” logic would be useful there, too.SoB probably came first, as it resulted from the SCO lawsuit.
It would be great if trailers could be attached to a commit without modifying its commit message, thus preserving its commit ID. In this way you could take a signed commit (or a signed tag) and add your “Reviewed-By:” trailer without making the new history incompatible with the original one.
git showandgit logcould show these new trailers objects after the commit text, as if they were part of the original commit message.I think what you’re looking for are git notes?
I’ll echo the sibling comments about git notes, and shout out to Gerrit where review information is tucked under
refs/notes/review. Oncenotes.displayRefis rigged correctly, UI-wise notes and trailers become mostly indistinguishable.(One of the things I miss since moving to GitLab… Need to teach
forgeto add MR metadata tomagit-revision-sections-hooksomeday)what’s forge? it’s hard to search for
magit/forgeis a Magit extension that integrates issues & pull-requests in the UI. Brought it up because Magit presents Gerrit review notes like @gioele suggests…… i.e. adding review context right after the author’s commit message.
(Sorry for the lack of context; self-conscious about Emacs proselytism. Was hoping the
magitname-drop would clarify that forge is “an Emacs thing”)Since the mask is off, and to get back to trailers proper, might as well mention: Magit has dedicated commands for inserting trailers, with completion on known authors; figure it’s worth mentioning since the manual doesn’t call them such.
I’ve used the
Co-Authored-Byone a couple of times; wondering how handy the others are though, considering projects where (a) reviewers send their acknowledgements over email (b) committers scrap them withb4 trailers.That’s roughly how git notes work https://git-scm.com/docs/git-notes
We ended up using Git trailers at GitLab for generating changelogs, and I later built a standalone tool basically doing the same thing. It works quite well, and feels much more natural compared to the metadata tags e.g. conventional commit wants you to use. You also don’t have to try and cram all the data onto a single subject line.
I’m not sure why trailers never really caught on beyond
Signed-off-by. What probably doesn’t help is that they are a bit of a pain to parse reliably, such that you basically end up having to use thegitCLI to ensure proper parsing.I use Git for at least 11 years now and this is the first time I hear about them, might be one reason that is shared by many. 😁
I absolutely will start using them, as of today.
EDIT: Oh, and I absolutely will inspect your tool (I see it’s based on make which is understandable but a tad disappointing as well) and see if I can apply it to my work.
The tool isn’t based on Make at all, there’s just a Makefile for running some release related tasks (e.g. tagging a new release). clogs only needs Git at runtime.
Serves me right for not looking deeper, thanks. I vaguely remember reading about Inko some months ago and liked but never tried it. Are you happy with it, by the way?
There’s a lot that still needs to be built and improved upon, but yes I’m happy with how it’s shaping up thus far :)
It really comes down to tooling showing you I guess. E.g. Gerrit puts a bunch of them in, and thus in such code bases people also start to use it for other variations, and spread it elsewhere.
FreeBSD uses these to a large degree, they also had it in svn, but they have moved over to git as well.
A example from a recent commit:
There is also a commit message hook with the full list of trailers they use: https://github.com/freebsd/freebsd-src/blob/main/tools/tools/git/hooks/prepare-commit-msg
(edit: For reference because I had to look it up:
)
This is a similar scheme, but note it’s not one compatible with git trailers (meaning you can’t automatically parse them with the same tools):
vs
This is an important distinction if you’re building tooling which uses git trailers.
Oh that is interesting, so the reason it fails is because there is space inside of the key and maybe the alignment on the right of the
:?I guess it does not really make sense for FreeBSD to change it since they have used the same format since before git was a thing: https://github.com/freebsd/freebsd-src/commit/8351d04f344964137ea1481bd1c1d1ac2070f81c
Slight tangent but… Differential Revision? Does FreeBSD use Phabricator? Or is there another Differential?
Well if you follow the link you end up on their Phabricator instance so I think they do: https://reviews.freebsd.org/D48505
Though I think they are also experimenting with using GitHub’s pull requests to make it easier to get into.
What’s the etymology behind “trailers” ? I assume it comes from “Data we add which trails behind the commit message”, but where’d that come from and when?
It is a bit odd because I think these would typically be called “footers”. Head/foot vs. head/tail vs. header/trailer…seems like somebody got their metaphors mixed up.
In RFC 2068 chunked transfer encoding it was called a “footer”, but in RFC 2616 it was renamed to “trailer” and a
Trailer:header was added so you could predeclare in yourTrailer:header which headers will appear in your trailer. (Yes I know nowadays HTTP bods prefer to call them “fields” but I prefer the original name.) The httpwg archives suggest “footer” was given the boot in 1997 about half a year after RFC 2068 was published.Now if we could just figure out where the other ‘r’ in
Referer:got to…Neat, thanks this is exactly what I was after.
Same as e-mail headers and trailers, and HTTP headers and trailers. In fact it’s literally the same format: note the two spaces line continuation format.
Email doesn’t have trailers. (You can have data outside a MIME part, but that’s ignored and unstructured.)
It would be nice if GitHub gave you a way to add these when you, for example, squash and merge a PR (which generates a new commit). Even if the default behavior was to maybe take the union of the trailers for all component commits, it wouldn’t be perfect but it would make this feasible for squash-based workflows.
GitHub has an interest in having proprietary solutions for e.g. code review, it keeps the platform lock in going. They’re more incentivized elsewhere.
If anyone is wondering whether GitHub recognizes any trailers (e.g., to reference/close an issue), it appears it does not but has its own ad hoc “phrases” (references: one, two).