git-commit
记录对仓库的更改
概要
git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]
[--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>]
[-F <file> | -m <msg>] [--reset-author] [--allow-empty]
[--allow-empty-message] [--no-verify] [-e] [--author=<author>]
[--date=<date>] [--cleanup=<mode>] [--[no-]status]
[-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]
[(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]
[--] [<pathspec>...]描述
创建一个新的提交,包含索引的当前内容和 描述更改的日志消息。新提交是 HEAD的直接子提交,通常是当前分支的顶端,并且 分支会更新以指向它(除非没有分支关联到 工作树,在这种情况下HEAD是"分离的",如 git-checkout(1)).
要提交的内容可以通过多种方式指定:
在使用
commit命令之前,使用 git-add(1) 逐步将更改"添加"到索引中(注意:即使是已修改的文件也必须被"添加");在使用
commit命令之前,使用 git-rm(1) 从工作树和索引中删除文件;将文件作为
commit命令的参数列出(不使用--interactive或--patch开关),此时提交将忽略索引中已暂存的更改,而是记录所列文件的当前内容(这些文件必须已被 Git 知晓);使用
-a开关与commit命令一起自动"添加"所有已知文件(即索引中已列出的所有文件)的更改,并自动"rm"已从工作树中删除的索引文件,然后执行实际提交;使用
--interactive或--patch开关与commit命令一起,在最终确定操作之前,逐一决定除索引中的内容外,哪些文件或差异块应成为提交的一部分。请参阅 git-add(1) 的"交互模式"章节以了解如何使用这些模式。
--dry-run 选项可用于通过提供相同的参数集(选项和路径)来获取下次提交将包含内容的摘要。
如果您提交后立即发现错误,可以使用 git reset 恢复。
:git-commit: 1
选项
-a
--all
自动暂存已修改和已删除的文件,但您未告知 Git 的新文件不受影响。
-p
--patch
使用交互式补丁选择接口来选择要提交的更改。详见 git-add(1)。
-U<n>
--unified=<n>
生成具有 <n> 行上下文的差异。上下文 行数默认为 diff.context,如果未设置配置变量 则为 3。
--inter-hunk-context=<n>
显示差异块之间的上下文,最多指定 <number> 行,从而融合彼此接近的块。 默认为 diff.interHunkContext,如果未设置配置选项 则为 0。
-C <commit>
--reuse-message=<commit>
获取一个已有的 <commit> 对象,并在创建新提交时重用其日志消息和作者信息(包括时间戳)。
-c <commit>
--reedit-message=<commit>
类似于 -C,但使用 -c 会调用编辑器,以便用户进一步编辑提交消息。
--fixup=[(amend|reword):]<commit>
创建一个新提交,用于在通过 git rebase --autosquash 应用时"修正" <commit>。 普通的 --fixup=<commit> 创建一个"fixup!"提交,更改 <commit> 的内容但保留其日志消息不变。 --fixup=amend:<commit> 类似,但创建一个"amend!"提交,同时用"amend!"提交的日志消息替换 <commit> 的日志消息。 --fixup=reword:<commit> 创建一个"amend!"提交,用其自身的日志消息替换 <commit> 的日志消息,但不对 <commit> 的内容做任何更改。 + 普通的 --fixup=<commit> 创建的提交标题由"fixup!"后跟 <commit> 的标题组成,并被 git rebase --autosquash 特别识别。 可以使用 -m 选项来补充所创建提交的日志消息,但一旦"fixup!"提交通过 git rebase --autosquash 压缩进 <commit>,附加的评论将被丢弃。 + --fixup=amend:<commit> 创建的提交类似,但其标题前缀为"amend!"。<commit> 的日志消息被复制到"amend!"提交的日志消息中,并在编辑器中打开以便完善。 当 git rebase --autosquash 将"amend!"提交压缩进 <commit> 时,<commit> 的日志消息将被"amend!"提交中完善后的日志消息替换。 除非使用了 --allow-empty-message,否则"amend!"提交的日志消息为空将报错。 + --fixup=reword:<commit> 是 --fixup=amend:<commit> --only 的简写。它创建一个仅包含日志消息的"amend!"提交(忽略索引中已暂存的任何更改)。 当被 git rebase --autosquash 压缩时,它将替换 <commit> 的日志消息而不做任何其他更改。 + "fixup!"和"amend!"提交在被 git rebase --autosquash 应用时都不会更改 <commit> 的作者信息。 详见 git-rebase(1)。
--squash=<commit>
构造一个提交消息以配合 git rebase --autosquash 使用。 提交消息标题取自指定的提交,并加上"squash! "前缀。 可与额外的提交消息选项(-m/-c/-C/-F)一起使用。 详见 git-rebase(1)。
--reset-author
当与 -C/-c/--amend 选项一起使用时,或在冲突的 cherry-pick 之后提交时, 声明所产生提交的作者身份现在属于提交者。这也会刷新作者时间戳。
--short
在进行试运行时,以简短格式输出。详见 git-status(1)。 隐含 --dry-run。
--branch
即使在简短格式下也显示分支和跟踪信息。 详见 git-status(1)。
--porcelain
在进行试运行时,以 porcelain 友好格式输出。 详见 git-status(1)。隐含 --dry-run。
--long
在进行试运行时,以详细格式输出。 这是 git-status(1) 的默认输出。隐含 --dry-run。
-z
--null
当显示 short 或 porcelain 格式的 git-status(1) 输出时, 原样打印文件名并以 NUL 而非 LF 终止条目。 如果未指定格式,则隐含 --porcelain 输出格式。 不使用 -z 选项时,包含"异常"字符的文件名将 按照配置变量 core.quotePath 的说明进行引用 (参见 git-config(1))。
-F <file>
--file=<file>
从 <file> 获取提交消息。使用 '-' 从标准输入读取消息。
--author=<author>
覆盖提交作者。使用标准的 A U Thor <author@example.com> 格式指定显式作者。 否则 <author> 被视为模式,用于搜索该作者的已有提交 (即 git rev-list --all -i --author=<author>); 然后从找到的第一个此类提交中复制提交作者。
--date=<date>
覆盖提交中使用的作者日期。
-m <msg>
--message=<msg>
使用 <msg> 作为提交消息。 如果给出多个 -m 选项,它们的值将作为独立段落连接。 + -m 选项与 -c、-C 和 -F 互斥。
-t <file>
--template=<file>
在编辑提交消息时,使用 <file> 中的内容启动编辑器。 template 配置变量通常用于隐式地向命令提供此选项。 希望引导参与者按照一定顺序和提示编写提交消息的项目可以使用此机制。 如果用户退出编辑器时未编辑消息,则提交将被中止。 当通过其他方式(如 -m 或 -F 选项)提供消息时,此选项无效。
ifdef::git-commit[]
-s
endif::git-commit[]
--signoff
--no-signoff
在提交日志消息末尾添加由提交者签署的 Signed-off-by 尾部。 签署的含义取决于您所提交的项目。例如,它可能证明提交者有权在项目许可下提交作品, 或同意某些贡献者声明,如开发者原产地证书。 (参见 https://developercertificate.org,Linux 内核和 Git 项目使用的版本。) 请查阅您所贡献项目的文档或负责人以了解签署在该项目中的使用方式。 + --no-signoff 选项可用于撤销命令行中先前的 --signoff 选项。 + Git 没有(也不会)配置变量来默认启用 --signoff 命令行选项; 详见 gitfaq(7) 中的 signoff 条目。
--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(1)) 可用于定义是否省略重复的尾部、每个尾部在尾部序列中的位置以及其他细节。
-n
--verify
--no-verify
绕过 pre-commit 和 commit-msg 钩子。 另请参阅 githooks(5)。
--allow-empty
通常记录一个与其唯一父提交具有完全相同树的提交是一个错误,命令会阻止您进行此类提交。 此选项绕过安全检查,主要用于外部 SCM 接口脚本。
--allow-empty-message
创建一个空提交消息的提交,无需使用底层命令如 git-commit-tree(1)。 与 --allow-empty 类似,此命令主要用于外部 SCM 接口脚本。
--cleanup=<mode>
确定在提交前如何清理提供的提交消息。 <mode> 可以是 strip、whitespace、verbatim、scissors 或 default。
示例
记录您自己的工作时,工作树中已修改文件的内容会通过 git add 暂时存储到名为"索引"的暂存区中。 文件可以仅在索引中(而非工作树中)恢复到上次提交的状态,使用 git restore --staged <file>, 这实际上撤销了 git add 并阻止该文件的更改参与下次提交的内容。 在使用这些命令逐步构建要提交的状态后, 使用 git commit(不带任何路径名参数)来记录目前为止已暂存的内容。 这是该命令最基本的形式。示例:
$ edit hello.c
$ git rm goodbye.c
$ git add hello.c+
[i18n]
否则为 whitespace。
默认值可通过 cleanup 配置变量更改(参见 git-config(1))。
-e:: --edit:: 允许用户进一步编辑通过 -F <file> 从文件、通过 -m <message> 从命令行、 或通过 -C <commit> 从提交中获取的消息。
--no-edit:: 使用选定的提交消息而不启动编辑器。 例如,git commit --amend --no-edit 会修改提交而不更改其提交消息。
--amend:: 通过创建一个新的提交来替换当前分支的顶端。 记录的树按常规方式准备(包括 -i 和 -o 选项以及显式路径规范的效果), 当命令行未通过 -m、-F、-c 等选项指定其他消息时, 原始提交的消息将用作起始点,而非空消息。 新提交与当前提交具有相同的父提交和作者(--reset-author 选项可覆盖此行为)。
但可用于修改合并提交。
如果您修改了已经发布的提交,应该了解重写历史的影响。 (参见 git-rebase(1) 中的"从上游变基中恢复"章节。)
--no-post-rewrite:: 绕过 post-rewrite 钩子。
-i:: --include:: 在将已暂存的内容提交之前, 也将命令行上给出的路径的内容暂存。 这通常不是您想要的,除非您正在完成一个有冲突的合并。
-o:: --only:: 通过获取命令行上指定路径的更新后的工作树内容来提交, 忽略已为其他路径暂存的任何内容。 如果在命令行上给出了任何路径,这是 git commit 的默认操作模式, 此时可以省略此选项。 如果此选项与 --amend 一起指定,则无需指定路径, 可用于在不提交已暂存更改的情况下修改上次提交。 如果与 --allow-empty 一起使用,同样无需指定路径,将创建一个空提交。
--pathspec-from-file=<file>:: 在文件 <file> 中传递路径规范,而非命令行参数。如果 <file> 恰好是 -,则使用标准输入。路径规范 元素由 LF 或 CR/LF 分隔。路径规范元素可以 按照配置变量 core.quotePath 的说明进行引用 (参见 git-config)。另请参阅 --pathspec-file-nul 和 全局 --literal-pathspecs。
--pathspec-file-nul:: 仅与 --pathspec-from-file 一起使用有意义。路径规范元素 由 NUL 字符分隔,所有其他字符按字面意思 处理(包括换行符和引号)。
-u[<mode>]:: --untracked-files[=<mode>]:: 显示未跟踪的文件。
配置变量文档参见 git-config(1)。
-v:: --verbose:: 在提交消息模板底部显示 HEAD 提交与将要提交内容之间的统一差异, 以帮助用户通过提醒提交包含的更改来描述提交。 请注意,此差异输出的行不会以 # 为前缀。此差异不会成为提交消息的一部分。 详见 git-config(1) 中的 verbose 配置变量。 + 如果指定两次,还会额外显示将要提交的内容与工作树文件之间的统一差异, 即已跟踪文件的未暂存更改。
-q:: --quiet:: 禁止显示提交摘要消息。
--dry-run:: 不创建提交,但显示将要提交的路径列表、 带有本地更改但将保持未提交状态的路径以及未跟踪的路径。
--status:: 在使用编辑器准备提交消息时, 在提交消息模板中包含 git-status(1) 的输出。 默认为开启,但可用于覆盖配置变量 status。
--no-status:: 在使用编辑器准备默认提交消息时, 不在提交消息模板中包含 git-status(1) 的输出。
-S[<key-id>]:: --gpg-sign[=<key-id>]:: --no-gpg-sign:: 对提交进行 GPG 签名。<key-id> 是可选的, 默认为提交者身份;如果指定,必须紧贴选项,不能有空格。 --no-gpg-sign 可用于覆盖 gpgSign 配置变量和先前的 --gpg-sign。
--:: 不再将后续参数解释为选项。
<pathspec>...:: 当在命令行上给出 <pathspec> 时,提交匹配路径规范的文件内容, 而不记录已添加到索引中的更改。这些文件的内容也会 在之前已暂存内容的基础上为下次提交暂存。 + 更多详情请参阅 gitglossary(7) 中的 'pathspec' 条目。
$ git commit
与记录您自己的更改一样,您可以使用 -a 选项来节省输入。 一个区别是在合并解决期间,您不能使用带路径名的 git commit 来更改提交的顺序, 因为合并应该作为单个提交记录。实际上,当给出路径名时命令会拒绝运行(但请参阅 -i 选项)。
$ git commit -a
git commit -a 命令首先查看您的工作树, 发现您已修改 hello.c 并删除 goodbye.c, 然后为您执行必要的 git add 和 git rm。
在对多个文件暂存更改后,您可以通过给 git commit 指定路径名来更改记录的顺序。 当给出路径名时,命令会创建一个仅记录对指定路径所做更改的提交:
$ edit hello.c hello.h
$ git add hello.c hello.h
$ edit Makefile
## $ git commit Makefile
这将创建一个记录对 `Makefile` 修改的提交。
为 `hello.c` 和 `hello.h` 暂存的更改不会包含在结果提交中。
但是,它们的更改并未丢失——它们仍然被暂存,只是被暂时保留。在上述序列之后,如果您执行:$ git add hello.c
解决冲突并暂存结果后,git ls-files -u 将不再提及冲突的路径。 完成后,运行 git commit 最终记录合并:
## 提交信息
作者和提交者信息取自以下环境变量(如果已设置):
* `GIT_AUTHOR_NAME`
* `GIT_AUTHOR_EMAIL`
* `GIT_AUTHOR_DATE`
* `GIT_COMMITTER_NAME`
* `GIT_COMMITTER_EMAIL`
* `GIT_COMMITTER_DATE`
(注意:`<`、`>` 和 `\n` 会被去除)
作者和提交者名称按惯例是某种形式的个人姓名(即其他人用来称呼您的名称),
尽管 Git 不强制或要求任何特定形式。可以使用任意 Unicode,但受上述约束限制。
此名称对身份验证没有影响;有关身份验证,请参阅 [git-config(1)](/commands/git-config) 中的 `credential.username` 变量。
如果这些环境变量(部分)未设置,则从配置项 `user.name` 和 `user.email` 获取信息,
或者如果也不存在,则从环境变量 `EMAIL` 获取,
如果仍未设置,则从系统用户名和用于外发邮件的主机名获取
(取自 `/etc/mailname`,如果该文件不存在则回退到完全限定主机名)。
`author.name` 和 `committer.name` 及其对应的 email 选项如果已设置则覆盖 `user.name` 和 `user.email`,
而它们本身又被环境变量覆盖。
典型用法是仅设置 `user.name` 和 `user.email` 变量;
其他选项是为更复杂的用例提供的。
:git-commit: 1
## 日期格式
`GIT_AUTHOR_DATE` 和 `GIT_COMMITTER_DATE` 环境变量支持以下日期格式:
Git internal format::
格式为 `<unix-timestamp> <time-zone-offset>`,其中
`<unix-timestamp>` 是自 UNIX 纪元以来的秒数。
`<time-zone-offset>` 是相对于 UTC 的正或负偏移量。
例如 CET(比 UTC 快 1 小时)为 `+0100`。
RFC 2822::
RFC 2822 描述的标准日期格式,例如
`Thu, 07 Apr 2005 22:13:13 +0200`。
ISO 8601::
ISO 8601 标准指定的时间和日期,例如
`2005-04-07T22:13:13`。解析器也接受用空格代替 `T` 字符。
秒的小数部分将被忽略,例如 `2005-04-07T22:13:13.019` 将被视为
`2005-04-07T22:13:13`。
+
::: tip
此外,日期部分还接受以下格式:
:::
`YYYY.MM.DD`、`MM/DD/YYYY` 和 `DD.MM.YYYY`。
ifdef::git-commit[]
除了识别上述所有日期格式外,`--date` 选项还会尝试理解其他更人性化的日期格式,
如相对日期"yesterday"或"last Friday at noon"。
endif::git-commit[]
## 讨论
虽然不是必需的,但建议以一行简短(不超过 50 个字符)的摘要开始提交消息,
然后空一行,再写更详细的描述。
提交消息中第一个空行之前的文本被视为提交标题,
该标题在整个 Git 中使用。例如,[git-format-patch(1)](/commands/git-format-patch) 将提交转换为电子邮件,
它在主题行使用标题,其余提交内容放在正文。
Git 在一定程度上与字符编码无关。
- blob 对象的内容是未解释的字节序列。在核心级别没有编码转换。
- 路径名以 UTF-8 规范化形式 C 编码。这适用于树对象、索引文件、引用名称,
以及命令行参数、环境变量和配置文件(`.git/config`(参见 [git-config(1)](/commands/git-config))、
[gitignore(5)](/commands/gitignore)、[gitattributes(5)](/commands/gitattributes) 和
[gitmodules(5)](/commands/gitmodules))中的路径名。
+
请注意,Git 在核心级别将路径名简单地视为非 NUL 字节序列,
不进行路径名编码转换(Mac 和 Windows 除外)。因此,使用非 ASCII 路径名
在使用传统扩展 ASCII 编码的平台和文件系统上通常也能正常工作。
但是,在此类系统上创建的仓库在基于 UTF-8 的系统(如 Linux、Mac、Windows)上无法正常工作,反之亦然。
此外,许多基于 Git 的工具直接假定路径名为 UTF-8,无法正确显示其他编码。
- 提交通常以 UTF-8 编码,但也支持其他扩展 ASCII 编码。
这包括 ISO-8859-x、CP125x 等,但不包括 UTF-16/32、
EBCDIC 和 CJK 多字节编码(GBK、Shift-JIS、Big5、EUC-x、CP9xx 等)。
虽然我们鼓励以 UTF-8 编码提交日志消息,但核心和 Git Porcelain 都设计为不强制项目使用 UTF-8。
如果某个项目的所有参与者发现使用传统编码更方便,Git 不会禁止。但是,有几点需要注意。
1. `git commit` 和 `git commit-tree` 在给定的提交日志消息看起来不像有效的 UTF-8 字符串时会发出警告,
除非您明确声明您的项目使用传统编码。声明方式是在 `.git/config` 文件中设置 `i18n.commitEncoding`,如下所示:
## commitEncoding = ISO-8859-1
+
使用上述设置创建的提交对象会在其 `encoding` 头中记录 `i18n.commitEncoding` 的值。
这是为了帮助以后查看这些提交的人。缺少此头意味着提交日志消息以 UTF-8 编码。
1. `git log`、`git show`、`git blame` 等命令会查看提交对象的 `encoding` 头,
并尝试将日志消息重新编码为 UTF-8,除非另有指示。您可以在 `.git/config` 文件中
使用 `i18n.logOutputEncoding` 指定期望的输出编码,如下所示:
## logOutputEncoding = ISO-8859-1
+
如果没有此配置变量,则使用 `i18n.commitEncoding` 的值。
请注意,我们特意选择在提交时不重新编码提交日志消息以在提交对象级别强制 UTF-8,
因为重新编码为 UTF-8 不一定是可逆操作。
## 环境和配置变量
用于编辑提交日志消息的编辑器将从以下位置依次选择:
`GIT_EDITOR` 环境变量、`core.editor` 配置变量、`VISUAL` 环境变量或 `EDITOR` 环境变量。
详见 [git-var(1)](/commands/git-var)。
本节中此行以上的所有内容均未包含在 [git-config(1)](/commands/git-config) 文档中。
以下内容与该文档中的一致:
ifdef::git-commit[]
:see-git-commit:
endif::git-commit[]
ifndef::git-commit[]
:see-git-commit: See [git-commit(1)](/commands/git-commit) for details.
endif::git-commit[]
`cleanup`::
此设置覆盖 `git commit` 中 `--cleanup` 选项的默认值。{see-git-commit}
当您始终希望保留在日志消息中以注释字符(`core.commentChar`,默认为 `#`)开头的行时,
更改默认值可能很有用,在这种情况下您可以执行 `git config cleanup whitespace`
(请注意,如果这样做,您需要自己删除提交日志模板中以注释字符开头的帮助行)。
`gpgSign`::
一个布尔值,指定是否对所有提交进行 GPG 签名。
在执行 rebase 等操作时使用此选项可能导致大量提交被签名。
使用代理来避免多次输入 GPG 密码短语可能更方便。
`status`::
一个布尔值,用于在使用编辑器准备提交消息时启用/禁用在提交消息模板中包含状态信息。
默认为 `true`。
`template`::
指定用作新提交消息模板的文件路径名。
`verbose`::
一个布尔值或整数,用于指定 `git commit` 的详细程度。{see-git-commit}
## 钩子
此命令可以运行 `commit-msg`、`prepare-commit-msg`、`pre-commit`、`post-commit` 和 `post-rewrite` 钩子。
详见 [githooks(5)](/githooks)。
## 文件
`$GIT_DIR/COMMIT_EDITMSG`::
此文件包含正在进行中的提交的提交消息。
如果 `git commit` 在创建提交之前因错误退出,
用户提供的任何提交消息(例如在编辑器会话中)将保存在此文件中,
但会被下次调用 `git commit` 时覆盖。
## 另请参阅
[git-add(1)](/commands/git-add),
[git-rm(1)](/commands/git-rm),
[git-mv(1)](/commands/git-mv),
[git-merge(1)](/commands/git-merge),
[git-commit-tree(1)](/commands/git-commit-tree)
## Git
[git(1)](/commands/git) 套件的一部分