以井号(#)开头的Git提交消息

386
Git在提交时将以#(井号、数字符号、八角符号、磅号)开头的行视为注释行。这在与票务跟踪系统一起工作并尝试在行首写入票号时非常令人恼火,例如:
#123 salt hashed passwords

Git会简单地从提交消息中删除该行。有没有办法转义哈希符号?我尝试了\和!,但都不起作用。空格在#之前被保留,所以这也不是解决问题的方法。

10
@AlexBudovski 之所以重视简洁,是因为简洁具有价值。 - Xavi
11
自 Git 1.8.2(2013年2月)以来,git config core.commentchar 允许配置注释字符。请参见下面的我的答案 - VonC
5
自Git v2.0.0(2014.05.21)以来,git commit --cleanup=scissors更加灵活。详细信息请参见我的回答 - Sungam
5
我必须说,当GitHub决定用哈希标记问题编号时,他们没有考虑到这个问题,这让我感到惊讶! - Michael Scheper
2
@Michael 说实话,这个约定已经被Mantis、Trac、Redmine等其他软件使用了。我想GitHub只是决定遵循它而不是重复造轮子。请参见https://dev59.com/DnVD5IYBdhLWcg3wQJOT - kelvin
显示剩余4条评论
10个回答

308

这种行为是 git commit 默认的“清理”行为之一。如果要保留以 # 开头的行,可以使用替代的清理模式。

例如:

git commit --cleanup=whitespace

如果你这样做,你必须小心地删除所有你不想在提交中出现的 # 行。


3
下一个问题是:我在哪里可以编辑git引入的以#开头的提交消息注释? - Alex
4
@Alex:这由commit.template Git配置变量控制。 - CB Bailey
38
这对于修改现有提交也非常有效。例如:git commit --amend --cleanup=whitespace - James Andres
2
--cleanup=verbatim 也是非常有用的。 - Petr Felzmann
1
由于现在已经是2020年了,每个人都只想要--cleanup=scissors[commit] cleanup = scissors。这两个选项可以做到--cleanup=whitespace的所有功能,并自动剥离每个提交消息后缀中的注释变更。 - Cecil Curry
显示剩余4条评论

169
请注意,自git1.8.2 (2013年2月)以来,您可以在提交消息中使用不同于'#'的字符进行注释。
这使您可以使用'#'来引用您的错误编号。
Git在要求用户在编辑器中编辑消息时给出的各种“提示”行默认情况下都用'#'注释掉了。
可以使用core.commentChar配置变量将此'#'自定义为其他字符。
理论上,你可以输入一个core.commentChar单词(多个字符),但git 2.0.x / 2.1将更加严格(Q3 2014)。
请参见提交50b54fdNguyễn Thái Ngọc Duy (pclouds)

配置:严格限制核心评论字符

我们目前不支持注释字符串(至少目前还不支持)。而且多字节字符编码也可能会被解析错误。由于这个原因,使用两个逗号的测试已经被更新了。它是在 introduces core.commentChar in eff80a9(允许自定义“注释字符”- 2013-01-16)的补丁中添加的。我不清楚为什么需要这种行为。

git 2.0.x/2.1(2014年第三季度)将为core.commentChar添加自动选择功能:
请参见提交 84c9dc2

core.commentChar为“auto”时,注释字符以默认情况下的“#”开头,但如果它已经在准备好的消息中,则在一个小的子集中查找另一个字符。这应该可以防止因为git意外地剥离了一些行而导致的惊喜。

请注意,git不足够聪明,无法识别自定义模板中的“#”作为注释字符,并在最终注释字符不同时进行转换。
它认为自定义模板中的“#”行是提交消息的一部分。因此,请勿在自定义模板中使用此功能。

“auto”候选字符列表如下:

# ; @ ! $ % ^ & | :

这意味着像 git commit -m '#1 fixed issue' 这样的命令将自动将 commentChar 切换为 ';', 因为提交消息中使用了 '#'。

查看 "在Git提交信息中使用#s",作者为Tom Wright

我在上面链接的Stackoverflow答案中提到了Git的一个功能,它会根据您在提交消息中使用的字符自动选择注释字符。
git config --global core.commentChar auto
听起来很不错,对吧?但是,它只会根据您打开它后进行的提交更改注释字符;它不会使用您的提交历史记录来确定选择。
在我看来,这是一个由于执行不佳而被削弱的伟大功能。如果默认情况下启用该功能,它似乎只有在这种情况下才有效:
- 一组人将简单地避免在提交中使用哈希标记,因为他们熟悉其后果。 - 其他人(像我们一样)只有在需要重新设置基线时才意识到需要更改注释字符。在这种情况下,添加新的提交以触发所需行为是没有意义的。 - 第三组人会自觉地早期接受他们需要更改默认注释字符,并会选择其他替代方案。
换句话说,将此功能作为非默认选项可帮助几乎没有人。由于默认情况下启用它不会对任何用户造成伤害,并且会为某些用户消除痛点,我无法理解为什么不是这种情况。Git并不以其易用性而闻名,但是有一个可用的修复程序而不打开它似乎是对用户不友好的。

注意:Git 2.41(2023年第2季度)增加了:

请参见提交 d3b3419(2023年3月27日),作者为Kristoffer Haugsbakk(LemmingAvalanche
(由Junio C Hamano -- gitster --合并于提交 5c93cfd,2023年3月31日)

config: 告诉用户我们期望一个ASCII字符

签名者:Kristoffer Haugsbakk

提交 50b54fd(“config: 对core.commentChar进行严格检查”,2014-05-17, Git v2.1.0-rc0 -- merge列在batch #2)记录了“多字节字符编码也可能被错误地解释”,实际上,多字节代码点(非ASCII)不被接受为有效的core.commentChar
现在的消息是:
core.commentChar should only be one ASCII character
                                    ^^^^^

1
要修复此后的语法高亮,请参见此相关问题:https://dev59.com/OWQo5IYBdhLWcg3wUN3Y - Alois Mahdal
1
@newbyca,你在交互式变基期间看到不支持哪个版本的git? - VonC
3
为了设置这个,你可以执行以下命令,例如:$ git config --global core.commentchar ';'。该命令会将Git的注释符号设置为分号(;)。 - davetapley
9
我喜欢这个答案。新的建议解决方案一句话总结:git config --global core.commentChar auto - aross
3
为什么"auto"不是默认值呢?感谢您的回答。 - Rich
显示剩余5条评论

129
这里的答案都很好,也很详细,但对于像我这样的 Git 新手来说,自定义 Git 配置选项并不那么明显。下面是一个示例,将注释字符从 # 改为 ;
git config core.commentChar ";"

这就是你需要做的全部。

8
当使用git commit打开配置的编辑器来编辑提交消息时,这也会更改Git添加到提交消息中的默认注释文本! - Michahell
13
对于单次修正,请使用以下命令:git -c core.commentChar="|" commit --amend(将 | 替换为您想要的任何字符)。 - yurisich

64
你可以使用命令行选项-m
git commit -m "#123 fixed"

43
这是一个糟糕的提交信息,请确保包含错误的内容以及修复方式。 - Good Person
5
只要提交记录中包含 bug 编号,就可以了。 - Trident D'Gao
11
如果缺陷跟踪系统突然损坏并且你没有备份,那可就糟了!:) - caveman_dick
1
如果你的公司从Jira迁移到其他跟踪器,也不是很好。 - Craigory Coppola
1
你可以像这样执行:git commit -m "#123 fixed" -m "Long commit",它也适用于 --amend。 - Ulrik McArdle
当您想要提交--amend以修复错误的问题编号时,这会造成问题。修订未被接受,因为它看起来像是一行注释。 - Matt Warren

63
如果你正在进行交互式变基,那么当你保存一个没有内容的提交消息(因为开头的#将其变成了注释,因此被忽略了)时,git会告诉你该怎么做:
Aborting commit due to empty commit message.
Could not amend commit after successfully picking 5e9159d9ce3a5c3c87a4fb7932fda4e53c7891db... 123 salt hashed passwords
This is most likely due to an empty commit message, or the pre-commit hook
failed. If the pre-commit hook failed, you may need to resolve the issue before
you are able to reword the commit.
You can amend the commit now, with

        git commit --amend

Once you are satisfied with your changes, run

        git rebase --continue

所以,只需修改信息即可:
git commit --amend -m "#123 salt hashed passwords"

继续变基:
git rebase --continue

1
这对于已经提交了代码但想要更改提交信息的人来说是正确的。 - 0xh8h
如果您在编辑器中输入一条以哈希符号开头的消息,则它也适用于新的提交。 - Owain Williams
这正是我想要的。在注释开头加上#符号比在结尾更易读。谢谢。 - le hien

48

应该使用 git commit --cleanup=scissors。它被添加到Git v2.0.0 中,在2014年5月21日。

来自git commit --help

--cleanup=<mode>
  scissors
    Same as whitespace, except that everything from (and including) the line
    "# ------------------------ >8 ------------------------" is truncated if the message
    is to be edited. "#" can be customized with core.commentChar.

1
我不明白这种方法比使用 commit.cleanup = whitespace 并手动删除 # … 注释更好,正如 @CharlesBailey 已经建议的那样。scissors 模式只是额外清理了 git format-patch/mailinfo/am 使用的剪刀语法;它在添加提交消息注释时不会使用 …-- >8 --… 语法。 - Slipp D. Thompson
1
  1. 我认为这样做更好,因为我不需要费力地“手动删除#...注释”。
  2. 我对你评论的第二部分不太确定,“剪刀”模式肯定在git commit --help中。你使用的是哪个版本的git?@SlippD.Thompson
- Sungam
什么?whitespace模式提供了以下功能:1. 去除前导和尾随空行,2. 去除尾随空格,3. 折叠连续的空行。scissors模式提供了以下功能:1. 去除前导和尾随空行,2. 去除尾随空格,3. 折叠连续的空行,4. 从(包括)行 # -…- >8 -…- 开始的所有内容。然而,只有在使用 git-format-patch/mailinfo/am 时才会插入剪刀线(# -…- >8 -…-)。因此,在正常的 git-commit/merge/rebase/cherry-pick 工作流中,scissors剥离模式与whitespace模式相比没有任何优势。v2.11.0 - Slipp D. Thompson
@SlippD.Thompson 你使用的是哪个版本的git?我正在使用2.8.3,git commit --cleanup=scissors确实会在git status信息之前添加# ------------------------ >8 ------------------------行。就像下面这样:# ------------------------ >8 ------------------------ # 不要触碰上面的行。 # 下面的所有内容都将被删除。 # 在主分支上 # # 初始提交 # # 要提交的更改: # 新文件: .gitignore - Sungam
2
我相信我已经找到了问题的根源。当使用“剪刀”时,Git确实会在状态文本“It looks like you may be…”之前插入# ------------------------ >8 ------------------------;但是,在# Conflicts:…文本之后插入剪刀线。我在.gitconfig中设置了commit.status = false,因此我没有看到任何状态文本,只有冲突文本。我改变立场,点赞。 - Slipp D. Thompson
显示剩余2条评论

9

只需在提交信息前加上一个空格字符 ,即在#字符之前开始提交消息即可。

这样,git就会停止将该行视为注释,并且github可以无任何问题地使用哈希的票据编号。

vim的默认语法高亮甚至通过将颜色从“注释”更改为“内容”来建议此功能。

enter image description here


5
在提交信息中,前导空格会被包括还是会被去除?我不希望提交消息以不可见字符开头。这将在未来引起问题。 - knittl
@knittl:前导空格不会被剥离。这正是其整个目的——否则该行将被视为注释。您能详细说明一下这种做法可能导致的问题吗?到目前为止,我还没有遇到过任何问题。 - helvete
2
我能想到几个问题和问题:1)它的缩进不一致,2)提取票号的(太)简单脚本可能会在前导空格上失败。3)为什么要在每个提交消息中存储一个额外的空格字符?4)太容易忘记 [5)最后:它实际上并没有以哈希字符而是以空格开始提交消息 ;) ] - knittl
2
@knittl:是的,你不能既拥有蛋糕又吃掉它。我提到这种方法是因为在我看来,它是最简单的方法,同时允许使用哈希符号(不计空格)开头的消息,并保留基于哈希的注释功能。只有第二点是一种问题,但在我看来更多是一种假设性的问题。无论如何,感谢你的讨论;-) - helvete
嗯,是的,你不能既拥有蛋糕又吃掉它。- 你可以。看看其他的答案。 - undefined

1

我所有的提交都以#issueNumber开头,因此我将这个模板放在了vim .git/hooks/commit-msg中:

NAME=$(git branch | grep '*' | sed 's/* //') 
echo "$NAME"' '$(cat "$1") > "$1"

假设我们有一个分支#15,并且我们进行了提交信息add new awesome feature。使用这种方法,最终的提交信息将是#15 add new awesome feature

1

使用不同的前缀来表示票号。或者在票号前添加一个单词,比如“Bug #42”。或者在行首添加一个空格字符;如果你想要删除这个空白字符,可以为此添加一个提交钩子。

我个人不太希望通过钩子进行这种提交消息的操作,因为当你不想触发它时,它可能会非常烦人。最简单的解决方案可能是重新思考这个问题。


3
不同的措辞只是解决问题的权宜之计。如果项目指南规定提交信息必须以票号开头,那么这种做法行不通。使用 post-commit 钩子也非常不美观。我认为应该向 Git 开发人员报告这个“错误”。 - knittl
1
不要费心了,那样是错误的。不要要求git开发人员按照您的指南工作。您不会要求Dennis Ritchie更改C语言以支持以井号字符开头的变量名称约定,对吧?这里也适用。如果提交消息允许注释,则可以支持有趣的事情,例如使用添加并注释的差异打开提交编辑器,因此您无需记住确切的更改。保留前导空格字符有什么问题? - wilhelmtell
2
支持在 Git 的提交信息中使用转义字符并不是什么大问题。 - knittl
6
这是一个完全合理的功能请求。尤其是考虑到Trac并没有将提交信息与缺陷单相关联,如果提交信息不以缺陷单号码(以#号开头)开始,那么这不仅仅是某个人的标准,而且是工具所要求的语法。让Git开发人员决定是否值得实现。(是的,Trac也可以解决这个问题。请求Git也做一些它能做的事情没有错。) - Luke Maurer
尤其是考虑到Trac似乎不会将提交与错误单关联起来,如果提交消息不以单号开头,则以哈希符号开头。在我有限的Trac使用经验中,提交消息中出现的类似#xxx的内容将链接到问题。它不必在提交的开头。也许这是在过去五年中发生了变化的事情? - Guildenstern
我们在 GitHub 的拉取请求模板中使用 ### markdown,由于 GitHub 将单次提交的提交消息作为 PR 描述,因此拥有与 PR 模板相同的提交模板非常方便。这样,您可以一次处理提交消息和 PR 描述。但是,这种 git 行为会破坏 ### 标题 markdown。 - David Mann

0

!是历史展开这就是为什么它没有工作。

历史扩展是通过历史扩展字符的出现引入的,默认情况下是 !

您可以使用带单个 ' 引号的 $在 Bash 中转义单引号字符串中的单引号):

$ git commit -m $'#228 update to a new version! margin of error is 33% | 33^*0.22;'
# commit message: #228 update to a new version! margin of error is 33% | 33^*0.22;

$ git commit -m $'docs!: new API reference for GPS horse navigation'
# commit message: docs!: new API reference for GPS horse navigation

如果在不使用 $' 的情况下,使用 "

$ git commit -m "docs!: new API reference for GPS horse navigation"
bash:  : unrecognized history modifier

如果与"一起使用并转义\\仍将存在,或者我做错了什么):

$ git commit -m "docs\!: new API reference for GPS horse navigation"
# commit message: docs\!: new API reference for GPS horse navigation

1
这个回答如何解决在提交信息中以#作为第一个字符的问题?除了注释之外,这个回答甚至没有包含# - knittl
@knittl的回答(使用$')意味着转义任何字符,包括#。我已经更新了答案。 - Dmitriy Zub
但这并不是必需的,只需使用单引号和 git commit -m '...'。在过去的12年中,这已经成为所有答案的一部分。我没有看到这个答案添加了哪些新信息,除了解释与问题无关的shell引用规则。在您的任何命令中都不需要 $(并且仅适用于bash)。 - knittl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接