提交消息中的 Git 魔术关键字(签名人、共同作者、修复...)

Posted

技术标签:

【中文标题】提交消息中的 Git 魔术关键字(签名人、共同作者、修复...)【英文标题】:Git magic keywords in commit messages (Signed-off-by, Co-authored-by, Fixes, ...) 【发布时间】:2020-02-19 21:02:51 【问题描述】:

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

GitHub adds Co-authored-by: 行,然后在 UI 中将提交者和被引用的人显示为提交作者。

此外,GitHub 和 GitLab 各自识别一组关键字以在合并提交时关闭问题。

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

【问题讨论】:

参见***.com/questions/54076863/…,了解如何避免暴露电子邮件地址。 自 Git 232(2021 年第二季度)以来,您可以使用 git commit --trailer "xxx Person's name <persons@email>" 添加任何预告片。见my answer below 【参考方案1】:

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

编辑:here 是有关不同工具使用的一些附加预告片的一些信息。

编辑 (2):Git 本身对“Signed-off-by:”拖车行和“(cherry pick from commit”拖车行有一些内置支持。参见git_generated_prefixes in trailer.c 和@ 987654324@.

【讨论】:

【参考方案2】:

来自 OP:

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

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

"git commit"(man) 学习了--trailer <key>[=<value>] 选项;与解释拖车命令一起,这将更容易支持自定义拖车。

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

commit:添加 --trailer 选项

签字人:胡哲宁

从历史上看,Git 在命令行中使用“--signoff”和“-s”选项支持“Signed-off-by”提交预告片。 但用户可能需要从命令行提供其他预告片信息,例如“Helped-by”、“Reported-by”、“Mentored-by”、

现在实现一个新的--trailer <token>[(=|:)<value>] 选项以将其他预告片传递给interpret-trailers 并将它们插入到提交消息中。

git commit 现在包含在其man page 中:

--trailer <token>[(=|:)<value>]

指定一个 (<token>, <value>) 对,应该作为 拖车。

例如:

git commit --trailer "Signed-off-by:C O Mitter <committer@example.com>" \
           --trailer "Helped-by:C O Mitter <committer@example.com>"

这将在提交消息中添加“Signed-off-by”预告片Helped-by”预告片。

trailer.* 配置变量 (git interpret-trailers) 可用于定义是否 省略了重复的预告片,其中在预告片的运行中 每个预告片都会出现,以及其他细节。


关于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

如果您通过添加 same Reported-by 对其进行修改,trailer.ifexists="replace" 配置将保持消息不变:

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.&lt;token&gt;.command 配置变量指定的命令行接收最终用户提供的值的方式既容易出错又容易误导。 添加了以更安全和更直观的方式实现相同目标的替代方法,作为 trailer.&lt;token&gt;.cmd 配置变量,以替换它。

参见ZheNing Hu (adlternative)commit c364b7e、commit 57dcb65(2021 年 5 月 3 日)。(由 Junio C Hamano -- gitster -- 合并于 commit 2cd6ce2,2021 年 5 月 11 日)

trailer:添加新的 .cmd 配置选项

协助人:Junio C Hamano协助人:Christian Couder签字人:胡哲宁

trailer.&lt;token&gt;.command 配置变量指定一个命令(通过 shell 运行,因此它不必是命令的单个名称或路径,但可以是 shell 脚本),以及第一次出现的子字符串 @987654381 @ 替换为在 '--trailer &lt;token&gt;=&lt;value&gt;' 参数中为令牌提供给 interpret-trailer 命令的值。

这有三个缺点:

在机制中使用$ARG会误导用户 该值在 shell 变量中传递,并诱使他们多次使用$ARG,但这不起作用,因为第二个和后续的$ARG 不会被替换。 因为$ARG 在文本上被替换而不考虑 shell 语言语法,甚至 '$ARG'(在单引号对内),用户希望保持原样,都会被替换,更糟糕的是,如果值有一个不匹配的单引号(想象一个像 "O 'Connor",替换为 NAME='$ARG' 以使其成为 NAME='O'Connor'),这将导致语法不正确(或更糟)的损坏命令。 第一次出现的子字符串$ARG将被替换为空字符串,在第一次调用命令时添加带有指定&lt;token&gt;的预告片。 这是一个糟糕的设计,自动执行的性质导致它添加了我们没想到的预告片。

引入一个新的trailer.&lt;token&gt;.cmd 配置,该配置具有更高的优先级以弃用并最终删除trailer.&lt;token&gt;.command,它将值作为参数传递给命令。 除了“$ARG”,用户可以在他们的脚本中将该值称为位置参数 $1。 同时为了让git interpret-trailers(man)更好的模拟git命令-s的行为,'trailer.&lt;token&gt;.cmd'不会自动执行。

git interpret-trailers 现在包含在其man page 中:

此选项的行为方式与“trailer.&lt;token&gt;.cmd”相同,除了 它不会将任何东西作为参数传递给指定的命令。 相反,第一次出现的子字符串 $ARG 被替换为 将作为参数传递的值。

'trailer.&lt;token&gt;.command' 选项已被弃用,取而代之的是 'trailer.&lt;token&gt;.cmd' 因为用户命令中的$ARG 是 只替换了一次,原来替换$ARG的方式不安全。

同时给出“trailer.&lt;token&gt;.cmd”和“trailer.&lt;token&gt;.command”时 对于相同的&lt;token&gt;,使用“trailer.&lt;token&gt;.cmd”并且 'trailer.&lt;token&gt;.command' 被忽略。

trailer.&lt;token&gt;.cmd

git interpret-trailers 现在包含在其man page 中:

这些参数中的任何一个,如果有的话,将作为它的传递给命令 第一个参数。 这样命令可以产生一个计算 来自 &lt;value&gt; 传入的 '--trailer &lt;token&gt;=&lt;value&gt;' 参数。

git interpret-trailers 现在包含在其man page 中:

使用脚本 glog-find-author 使用 cmd 配置“帮助”预告片 从 git 存储库中的 git log 搜索指定的作者身份 并展示它是如何工作的:
$ 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>
使用脚本glog-grep 使用 cmd 配置“参考”预告片 从 git 存储库中的 git log grep 上次相关提交 并展示它是如何工作的:
$ 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)

【讨论】:

嗯“查理-奥斯卡米特”? “夏洛特-奥利维亚·米特”?我必须知道。

以上是关于提交消息中的 Git 魔术关键字(签名人、共同作者、修复...)的主要内容,如果未能解决你的问题,请参考以下文章

git修改提交作者和邮箱

如何在 git 分支中获取给定作者的提交消息历史记录? [复制]

Git教程

Git的常用命令

git rebase需要每个提交的签名

在git中实施提交消息格式