Git 提交消息中的魔法关键字(签名者、合着者、修复者……)

Git magic keywords in commit messages (Signed-off-by, Co-authored-by, Fixes, ...)

Git 命令本身 supports Signed-off-by: Person's name <persons@email> 行。

GitHub adds Co-authored-by: 行,然后在 UI.

中将提交者和被引用的人显示为提交作者

此外,GitHub and GitLab 每个人都会识别一组关键字以在合并提交时关闭问题。

上面的 Git 个魔术关键字列表是否完整?是否有用于添加这些行和关键字的标准化流程?这些是否定义为不区分大小写?

这些称为预告片,几乎可以是任何键值对。没有标准化过程,拖车线的解释取决于平台(例如 GitHub、GitLab)。另见 documentation for git-interpret-trailers.

编辑:here 是关于不同工具使用的一些额外预告片的一些信息。

编辑 (2):Git 本身对 "Signed-off-by: " 尾行以及“(cherry picked from commit”尾行有一些内置支持。参见 git_generated_prefixes in trailer.c as well as the constants in sequencer.c.

来自 OP:

The git command itself supports the Signed-off-by: Person's name <persons@email> line.

从 Git 2.32(2021 年第 2 季度)开始,git 命令本身支持......任何你想要的预告片!

"git commit"(man) 学到了 --trailer <key>[=<value>] 选项;连同 interpret-trailers 命令,这将使支持自定义预告片变得更容易。

参见 commit 2daae3d (23 Mar 2021) by ZheNing Hu (adlternative)
(由 Junio C Hamano -- gitster -- in commit 68e15e0 合并,2021 年 4 月 7 日)

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 现在包含在其 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.


关于 trailer.xxx 配置,考虑要修改的初始提交附加 预告片:

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" 配置会,如果您通过添加 same Reported-by 来修改它,保持消息不变:

git -c trailer.ifexists="replace" \
    commit   --trailer "Mentored-by: C4 E4" \
             --trailer "Helped-by: C3 E3" \
             --amend

但是如果你用 trailer.ifexists="add" 修改同一个提交将意味着:

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

并使用 trailer.ifexists="addIfDifferent"

git -c trailer.ifexists="addIfDifferent" \
    commit  --trailer "Reported-by: C3 E3" \
            --trailer "Mentored-by: C5 E5" \
            --amend

你得到:

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

而且,仍然使用 Git 2.32(2021 年第二季度),trailer.<token>.command 配置变量指定的命令行接收最终用户提供的值的方式既容易出错又容易产生误导。
添加了以更安全、更直观的方式实现相同目标的替代方法,作为 trailer.<token>.cmd 配置变量来替换它。

参见 commit c364b7e, commit 57dcb65 (03 May 2021) by ZheNing Hu (adlternative)
(由 Junio C Hamano -- gitster -- in commit 2cd6ce2 合并,2021 年 5 月 11 日)

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, , 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 现在包含在其 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 现在包含在其 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 现在包含在其 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 "" && git log --author="" --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 "" && git log --grep "" --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)