From the OP:
The git
command itself supports the Signed-off-by: Person's name <persons@email>
line.
Starting with Git 2.32 (Q2 2021), the git
command itself supports... any trailer you want!
"git commit
"(man) learned --trailer <key>[=<value>]
option; together with the interpret-trailers command, this will make it easier to support custom trailers.
See commit 2daae3d (23 Mar 2021) by ZheNing Hu (adlternative
).
(Merged by Junio C Hamano -- gitster
-- in commit 68e15e0, 07 Apr 2021)
commit
: add --trailer option
Signed-off-by: ZheNing Hu
Historically, Git has supported the 'Signed-off-by
' commit trailer using the '--signoff
' and the '-s
' option from the command line.
But users may need to provide other trailer information from the command line such as "Helped-by
", "Reported-by
", "Mentored-by
",
Now implement a new --trailer <token>[(=|:)<value>]
option to pass other trailers to interpret-trailers
and insert them into commit messages.
git commit
now includes in its man page:
--trailer <token>[(=|:)<value>]
Specify a (<token>
, <value>
) pair that should be applied as a
trailer.
For instance:
git commit --trailer "Signed-off-by:C O Mitter <committer@example.com>" \
--trailer "Helped-by:C O Mitter <committer@example.com>"
That will add the "Signed-off-by
" trailer and the "Helped-by
" trailer to the commit message.
The trailer.*
configuration variables
(git interpret-trailers
) can be used to define if
a duplicated trailer is omitted, where in the run of trailers
each trailer would appear, and other details.
Regarding that trailer.xxx
configuration, consider an initial commit that you want to amend with additional trailers:
Signed-off-by: C O Mitter <committer@example.com>
Signed-off-by: C1 E1
Reported-by: C3 E3
Mentored-by: C4 E4
Helped-by: C3 E3
A trailer.ifexists="replace"
config would, if you amend it by adding the same Reported-by, keep the message unchanged:
git -c trailer.ifexists="replace" \
commit --trailer "Mentored-by: C4 E4" \
--trailer "Helped-by: C3 E3" \
--amend
But if you amend the same commit with trailer.ifexists="add"
would means:
Signed-off-by: C O Mitter <committer@example.com>
Signed-off-by: C1 E1
Helped-by: C2 E2
Reported-by: C3 E3
Mentored-by: C4 E4
Reported-by: C3 E3 <<<< added twice
Mentored-by: C4 E4 <<<< added twice
And using trailer.ifexists="addIfDifferent"
git -c trailer.ifexists="addIfDifferent" \
commit --trailer "Reported-by: C3 E3" \
--trailer "Mentored-by: C5 E5" \
--amend
And you get:
Signed-off-by: C O Mitter <committer@example.com>
Signed-off-by: C1 E1
Helped-by: C2 E2
Reported-by: C3 E3
Mentored-by: C4 E4
Mentored-by: C5 E5 <<<< Only C5 E5 is added
And, still With Git 2.32 (Q2 2021), the way the command line specified by the trailer.<token>.command
configuration variable receives the end-user supplied value was both error prone and misleading.
An alternative to achieve the same goal in a safer and more intuitive way has been added, as the trailer.<token>.cmd
configuration variable, to replace it.
See commit c364b7e, commit 57dcb65 (03 May 2021) by ZheNing Hu (adlternative
).
(Merged by Junio C Hamano -- gitster
-- in commit 2cd6ce2, 11 May 2021)
trailer
: add new .cmd config option
Helped-by: Junio C Hamano
Helped-by: Christian Couder
Signed-off-by: ZheNing Hu
The trailer.<token>.command
configuration variable specifies a command (run via the shell, so it does not have to be a single name or path to the command, but can be a shell script), and the first occurrence of substring $ARG
is replaced with the value given to the interpret-trailer
command for the token in a '--trailer <token>=<value>
' argument.
This has three downsides:
- The use of
$ARG
in the mechanism misleads the users that
the value is passed in the shell variable, and tempt them to use $ARG
more than once, but that would not work, as the second and subsequent $ARG
are not replaced.
- Because
$ARG
is textually replaced without regard to the
shell language syntax, even '$ARG
' (inside a single-quote pair), which a user would expect to stay intact, would be replaced, and worse, if the value had an unmatched single quote (imagine a name like "O'Connor", substituted into NAME='$ARG'
to make it NAME='O'Connor'
), it would result in a broken command that is not syntactically correct (or worse).
- The first occurrence of substring
$ARG
will be replaced with the empty string, in the command when the command is first called to add a trailer with the specified <token>
.
This is a bad design, the nature of automatic execution causes it to add a trailer that we don't expect.
Introduce a new trailer.<token>.cmd
configuration that takes higher precedence to deprecate and eventually remove trailer.<token>.command
, which passes the value as an argument to the command.
Instead of "$ARG
", users can refer to the value as positional argument, $1, in their scripts.
At the same time, in order to allow git interpret-trailers
(man) to better simulate the behavior of git command -s
, 'trailer.<token>.cmd
' will not automatically execute.
git interpret-trailers
now includes in its man page:
This option behaves in the same way as 'trailer.<token>.cmd
', except
that it doesn't pass anything as argument to the specified command.
Instead the first occurrence of substring $ARG
is replaced by the
value that would be passed as argument.
The 'trailer.<token>.command
' option has been deprecated in favor of
'trailer.<token>.cmd
' due to the fact that $ARG
in the user's command is
only replaced once and that the original way of replacing $ARG
is not safe.
When both 'trailer.<token>.cmd
' and 'trailer.<token>.command
' are given
for the same <token>
, 'trailer.<token>.cmd
' is used and
'trailer.<token>.command
' is ignored.
trailer.<token>.cmd
git interpret-trailers
now includes in its man page:
of these arguments, if any, will be passed to the command as its
first argument.
This way the command can produce a computed
from the <value>
passed in the '--trailer <token>=<value>
' argument.
git interpret-trailers
now includes in its man page:
- Configure a 'help' trailer with a cmd use a script
glog-find-author
which search specified author identity from git log in git repository
and show how it works:
$ cat ~/bin/glog-find-author
#!/bin/sh
test -n "$1" && git log --author="$1" --pretty="%an <%ae>" -1 || true
$ git config trailer.help.key "Helped-by: "
$ git config trailer.help.ifExists "addIfDifferentNeighbor"
$ git config trailer.help.cmd "~/bin/glog-find-author"
$ git interpret-trailers --trailer="help:Junio" --trailer="help:Couder" <<EOF
> subject
>
> message
>
> EOF
subject
message
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Christian Couder <christian.couder@gmail.com>
- Configure a 'ref' trailer with a cmd use a script
glog-grep
to grep last relevant commit from git log in the git repository
and show how it works:
$ cat ~/bin/glog-grep
#!/bin/sh
test -n "$1" && git log --grep "$1" --pretty=reference -1 || true
$ git config trailer.ref.key "Reference-to: "
$ git config trailer.ref.ifExists "replace"
$ git config trailer.ref.cmd "~/bin/glog-grep"
$ git interpret-trailers --trailer="ref:Add copyright notices." <<EOF
> subject
>
> message
>
> EOF
subject
message
Reference-to: 8bc9a0c769 (Add copyright notices., 2005-04-07)