Git
英语 ▾ 主题 ▾ 最新版本 ▾ git-commit 最后更新于 2.46.1

名称

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] 中所述)。

要提交的内容可以通过以下几种方式指定

  1. 使用 git-add[1] 在使用 commit 命令之前逐步“添加”对索引的更改(注意:即使修改后的文件也必须“添加”);

  2. 使用 git-rm[1] 从工作树和索引中删除文件,同样在使用 commit 命令之前;

  3. 将文件列为 commit 命令的参数(不带 --interactive 或 --patch 开关),在这种情况下,提交将忽略索引中暂存的更改,而是记录所列文件(必须已知 Git)的当前内容;

  4. 使用 commit 命令的 -a 开关自动“添加”所有已知文件(即索引中已列出的所有文件)的更改,并自动“rm”索引中已从工作树中删除的文件,然后执行实际提交;

  5. 使用 commit 命令的 --interactive 或 --patch 开关,在最终完成操作之前,逐个决定哪些文件或块应包含在提交中,除了索引中的内容之外。请参阅 git-add[1] 的“交互模式”部分以了解如何操作这些模式。

--dry-run 选项可用于通过提供相同的参数集(选项和路径)来获取关于下一个提交包含的内容的摘要。

如果您提交了更改,然后立即发现错误,可以使用 git reset 从中恢复。

选项

-a
--all

告诉命令自动暂存已修改和删除的文件,但您没有告诉 Git 的新文件不受影响。

-p
--patch

使用交互式补丁选择界面来选择要提交的更改。有关详细信息,请参阅 git-add[1]

-C <commit>
--reuse-message=<commit>

获取现有的提交对象,并在创建提交时重用日志消息和作者信息(包括时间戳)。

-c <commit>
--reedit-message=<commit>

-C 相似,但使用 -c 会调用编辑器,以便用户可以进一步编辑提交消息。

--fixup=[(amend|reword):]<commit>

创建一个新的提交,在使用 git rebase --autosquash 应用时,该提交将“修复”<commit>。普通 --fixup=<commit> 创建一个“fixup!”提交,该提交会更改 <commit> 的内容,但保留其日志消息。--fixup=amend:<commit> 类似,但会创建一个“amend!”提交,该提交也会将 <commit> 的日志消息替换为“amend!”提交的日志消息。--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> 的日志消息,而不进行任何其他更改。

当被 git rebase --autosquash 应用时,无论是“fixup!”还是“amend!”提交都不会更改 <commit> 的作者身份。有关详细信息,请参阅 git-rebase[1]

--squash=<commit>

构建用于 rebase --autosquash 的提交消息。提交消息主题行取自指定的提交,并在其前面加上“squash! ”。可以与其他提交消息选项(-m/-c/-C/-F)一起使用。有关详细信息,请参阅 git-rebase[1]

--reset-author

与 -C/-c/--amend 选项一起使用时,或在冲突的 cherry-pick 后提交时,声明生成的提交的作者身份现在属于提交者。这也将重新生成作者时间戳。

--short

进行干运行时,以短格式给出输出。有关详细信息,请参阅 git-status[1]。隐含 --dry-run

--branch

即使在短格式中,也显示分支和跟踪信息。

--porcelain

进行干运行时,以瓷器就绪格式给出输出。有关详细信息,请参阅 git-status[1]。隐含 --dry-run

--long

进行干运行时,以长格式给出输出。隐含 --dry-run

-z
--null

在显示 shortporcelain 状态输出时,以 NUL 而不是 LF 结束条目,并逐字打印文件名。如果未给出格式,则隐含 --porcelain 输出格式。如果没有 -z 选项,则带有“非正常”字符的文件名将被引用,如配置变量 core.quotePath 所述(请参阅 git-config[1])。

-F <file>
--file=<file>

从给定的文件获取提交消息。使用 - 从标准输入读取消息。

--author=<author>

覆盖提交作者。使用标准 A U Thor <[email protected]> 格式指定明确的作者。否则,<author> 被认为是模式,用于按该作者搜索现有提交(即 rev-list --all -i --author=<author>);然后从找到的第一个此类提交中复制提交作者。

--date=<date>

覆盖提交中使用的作者日期。

-m <msg>
--message=<msg>

使用提供的 <msg> 作为提交信息。如果提供了多个 -m 选项,它们的 value 会被连接起来,作为独立的段落。

-m 选项与 -c-C-F 互斥。

-t <file>
--template=<file>

编辑提交信息时,使用给定文件中的内容启动编辑器。commit.template 配置变量通常用于隐式地将此选项提供给命令。这种机制可供希望在提交信息中提供一些提示以指导参与者如何编写信息的项目使用,例如,提示应按照什么顺序编写信息。如果用户在未编辑信息的情况下退出编辑器,提交将被中止。如果通过其他方式提供信息(例如,使用 -m-F 选项),则此选项无效。

-s
--signoff
--no-signoff

在提交日志信息的末尾添加一个由提交者签署的 Signed-off-by 尾部。签署的含义取决于您提交的项目。例如,它可能证明提交者有权在项目许可下提交工作,或者同意一些贡献者代表,例如开发者原始证书。(有关 Linux 内核和 Git 项目使用的证书,请参阅 https://developercertificate.org.) 请咨询您正在贡献的项目的文档或负责人,以了解该项目中如何使用签署。

--no-signoff 选项可用于抵消命令行上早先的 --signoff 选项。

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

指定应作为尾部应用的 (<token>,<value>) 对。(例如,git commit --trailer "Signed-off-by:C O Mitter \ <[email protected]>" --trailer "Helped-by:C O Mitter \ <[email protected]>" 将将 "Signed-off-by" 尾部和 "Helped-by" 尾部添加到提交信息。)trailer.* 配置变量 (git-interpret-trailers[1]) 可用于定义是否省略重复的尾部,每个尾部在尾部运行中的出现位置以及其他详细信息。

-n
--[no-]verify

默认情况下,会运行 pre-commit 和 commit-msg 挂钩。如果提供了 --no-verify-n,则会绕过这些挂钩。另请参阅 githooks[5].

--allow-empty

通常,记录与唯一父提交具有完全相同树的提交是一个错误,并且该命令会阻止您进行此类提交。此选项会绕过安全措施,主要供外部 SCM 接口脚本使用。

--allow-empty-message

--allow-empty 一样,此命令主要供外部 SCM 接口脚本使用。它允许您在不使用管道命令(如 git-commit-tree[1])的情况下创建具有空提交信息的提交。

--cleanup=<mode>

此选项确定在提交之前如何清理提供的提交信息。<mode> 可以是 stripwhitespaceverbatimscissorsdefault

strip

删除前导和尾随空行、尾随空格、注释并折叠连续的空行。

whitespace

strip 相同,除了不删除 #注释。

verbatim

完全不更改信息。

scissors

whitespace 相同,除了在要编辑信息的情况下,将截断从(包括)下面找到的行开始的所有内容。"#" 可以使用 core.commentChar 自定义。

# ------------------------ >8 ------------------------
default

如果要编辑信息,则与 strip 相同。否则为 whitespace

默认值可以通过 commit.cleanup 配置变量更改(请参阅 git-config[1])。

-e
--edit

使用 -F 从文件、使用 -m 从命令行以及使用 -C 从提交对象获取的信息通常用作未修改的提交日志信息。此选项允许您进一步编辑从这些来源获取的信息。

--no-edit

使用选定的提交信息,而无需启动编辑器。例如,git commit --amend --no-edit 会修改提交,而不会更改其提交信息。

--amend

通过创建新的提交来替换当前分支的顶端。记录的树按通常方式准备(包括 -i-o 选项以及显式路径规范的影响),并且在没有从命令行通过诸如 -m-F-c 等选项指定其他信息的情况下,使用来自原始提交的信息作为起点,而不是空信息。新提交与当前提交具有相同的父级和作者(--reset-author 选项可以抵消这一点)。

它等效于

	$ git reset --soft HEAD^
	$ ... do something else to come up with the right tree ...
	$ git commit -c ORIG_HEAD

但可用于修改合并提交。

如果您修改了已发布的提交,您应该了解重写历史记录的影响。(请参阅 git-rebase[1] 中的 "RECOVERING FROM UPSTREAM REBASE" 部分。)

--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[1])。另请参阅 --pathspec-file-nul 和全局 --literal-pathspecs

--pathspec-file-nul

仅与 --pathspec-from-file 结合使用才有意义。路径规范元素由 NUL 字符分隔,所有其他字符都按字面意思解释(包括换行符和引号)。

-u[<mode>]
--untracked-files[=<mode>]

显示未跟踪文件。

模式参数是可选的(默认为 all),用于指定对未跟踪文件的处理;当不使用 -u 时,默认值为 normal,即显示未跟踪文件和目录。

可能的选项是

  • no - 不显示未跟踪文件

  • normal - 显示未跟踪文件和目录

  • all - 还显示未跟踪目录中的单个文件。

布尔值 true 的所有常用拼写都视为 normalfalse 视为 no。默认值可以使用 git-config[1] 中记录的 status.showUntrackedFiles 配置变量更改。

-v
--verbose

显示 HEAD 提交与将在提交信息模板底部提交的内容之间的统一差异,以帮助用户通过提醒提交包含哪些更改来描述提交。请注意,此差异输出没有在其行前缀 #。此差异不会成为提交信息的一部分。请参阅 git-config[1] 中的 commit.verbose 配置变量。

如果指定两次,则还会显示将在提交的内容与工作树文件之间的统一差异,即对跟踪文件的未暂存更改。

-q
--quiet

抑制提交摘要信息。

--dry-run

不创建提交,而是显示要提交的路径列表、将保留未提交的本地更改的路径以及未跟踪的路径。

--status

在使用编辑器准备提交信息时,将 git-status[1] 的输出包含在提交信息模板中。默认情况下为启用,但可用于覆盖配置变量 commit.status

--no-status

在使用编辑器准备默认提交信息时,不将 git-status[1] 的输出包含在提交信息模板中。

-S[<keyid>]
--gpg-sign[=<keyid>]
--no-gpg-sign

使用 GPG 签署提交。keyid 参数是可选的,默认为提交者身份;如果指定,则必须附加到选项,中间没有空格。--no-gpg-sign 可用于抵消 commit.gpgSign 配置变量和早先的 --gpg-sign

--

不再将任何其他参数解释为选项。

<pathspec>…​

当命令行中给出路径规范时,提交与路径规范匹配的文件的内容,而不记录已添加到索引的更改。这些文件的内容也会在先前已暂存的内容之上,为下一次提交进行暂存。

有关更多详细信息,请参阅 gitglossary[7] 中的 pathspec 条目。

示例

记录您自己的工作时,工作树中已修改的文件的内容会使用 git add 临时存储到名为“索引”的暂存区域。可以使用 git restore --staged <file> 将文件恢复到索引中的最后一次提交的状态,但不会恢复到工作树中。这实际上会撤销 git add 并阻止对该文件的更改参与下一次提交。使用这些命令逐步构建要提交的状态后,git commit(不带任何路径名参数)用于记录到目前为止已暂存的内容。这是该命令最基本的形式。例如

$ edit hello.c
$ git rm goodbye.c
$ git add hello.c
$ git commit

您无需在每次更改后都暂存文件,而是可以告诉 git commit 注意工作树中跟踪其内容的文件的更改,并为您执行相应的 git addgit rm。也就是说,如果您的工作树中没有其他更改,则此示例与前面的示例执行的操作相同

$ edit hello.c
$ rm goodbye.c
$ git commit -a

命令 git commit -a 首先查看您的工作树,注意到您修改了 hello.c 并删除了 goodbye.c,并为您执行必要的 git addgit rm

在暂存对许多文件的更改后,您可以通过向 git commit 提供路径名来更改记录更改的顺序。当给出路径名时,该命令会进行提交,该提交仅记录对指定路径所做的更改

$ edit hello.c hello.h
$ git add hello.c hello.h
$ edit Makefile
$ git commit Makefile

这会进行提交,该提交记录对 Makefile 的修改。对 hello.chello.h 暂存的更改不会包含在生成的提交中。但是,它们的更改不会丢失 - 它们仍处于暂存状态,只是被暂时搁置。在上述序列之后,如果您执行

$ git commit

则此第二次提交将按预期记录对 hello.chello.h 的更改。

在合并(由 git mergegit pull 启动)因冲突而停止后,已干净合并的路径已暂存以便为您提交,而发生冲突的路径将保留在未合并状态。您首先需要使用 git status 检查哪些路径发生了冲突,并在手动修复工作树中的冲突后,使用 git add 像往常一样暂存结果

$ git status | grep unmerged
unmerged: hello.c
$ edit hello.c
$ git add hello.c

在解决冲突并暂存结果后,git ls-files -u 将不再提及冲突的路径。完成后,运行 git commit 以最终记录合并

$ git commit

与记录您自己的更改的情况一样,您可以使用 -a 选项来节省输入。一个区别是,在合并解决过程中,您不能使用带路径名的 git commit 来更改提交更改的顺序,因为合并应该作为一个提交记录。实际上,当给出路径名时,该命令会拒绝运行(但请参阅 -i 选项)。

提交信息

作者和提交者信息将从以下环境变量中获取(如果设置了这些变量)

GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
GIT_AUTHOR_DATE
GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL
GIT_COMMITTER_DATE

(注意“<”,">" 和 "\n" 将被删除)

作者和提交者姓名按惯例是某种形式的个人姓名(即其他人类用来称呼您的姓名),尽管 Git 不会强制执行或要求任何特定形式。可以随意使用 Unicode 字符,但需遵守上述约束条件。此名称不会影响身份验证;有关身份验证,请参阅 git-config[1] 中的 credential.username 变量。

如果(部分)这些环境变量未设置,则该信息将从配置项 user.nameuser.email 中获取,或者,如果不存在,则从环境变量 EMAIL 中获取,或者,如果该变量未设置,则从系统用户名和用于发送邮件的主机名(从 /etc/mailname 获取,当该文件不存在时,回退到完全限定的 hostname)中获取。

author.namecommitter.name 以及它们相应的电子邮件选项如果设置,则会覆盖 user.nameuser.email,并且它们本身会被环境变量覆盖。

典型用法是仅设置 user.nameuser.email 变量;其他选项用于更复杂的用例。

日期格式

GIT_AUTHOR_DATEGIT_COMMITTER_DATE 环境变量支持以下日期格式

Git 内部格式

它是 <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

注意
此外,日期部分接受以下格式:YYYY.MM.DDMM/DD/YYYYDD.MM.YYYY

除了识别上述所有日期格式外,--date 选项还会尝试理解其他更人性化的日期格式,例如像“昨天”或“上周五中午”这样的相对日期。

讨论

虽然不是必需的,但最好以一行简短的(不超过 50 个字符)总结更改的提交信息开头,然后空一行,再进行更详细的描述。提交信息中第一行空行之前的文本被视为提交标题,该标题将在整个 Git 中使用。例如,git-format-patch[1] 将提交转换为电子邮件,并使用主题行上的标题和提交的其余部分作为正文。

Git 在某种程度上是字符编码无关的。

  • blob 对象的内容是未解释的字节序列。在核心级别没有编码转换。

  • 路径名以 UTF-8 规范化形式 C 进行编码。这适用于树对象、索引文件、引用名称以及命令行参数、环境变量和配置文件(.git/config(请参阅 git-config[1])、gitignore[5]gitattributes[5]gitmodules[5])中的路径名。

    注意,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 commitgit commit-tree 会发出警告,如果提交给它的提交日志信息不像有效的 UTF-8 字符串,除非您明确说明您的项目使用传统编码。要说明这一点,您需要在 .git/config 文件中添加 i18n.commitEncoding,如下所示

    [i18n]
    	commitEncoding = ISO-8859-1

    使用上述设置创建的提交对象会将其 i18n.commitEncoding 的值记录到其 encoding 标头中。这是为了帮助以后查看这些提交的人。缺少此标头意味着提交日志信息以 UTF-8 编码。

  2. git loggit showgit blame 及其朋友会查看提交对象的 encoding 标头,并尝试将日志信息重新编码为 UTF-8,除非另有说明。您可以使用 .git/config 文件中的 i18n.logOutputEncoding 指定所需的输出编码,如下所示

    [i18n]
    	logOutputEncoding = ISO-8859-1

    如果您没有此配置变量,则将使用 i18n.commitEncoding 的值。

注意,我们故意选择在提交时不重新编码提交日志信息,以强制在提交对象级别使用 UTF-8,因为重新编码为 UTF-8 不一定是可以逆转的操作。

环境和配置变量

用于编辑提交日志信息的编辑器将从 GIT_EDITOR 环境变量、core.editor 配置变量、VISUAL 环境变量或 EDITOR 环境变量(按此顺序)中选择。有关详细信息,请参阅 git-var[1]

本节中此行以上的所有内容都不包含在 git-config[1] 文档中。以下内容与该文档中相同

commit.cleanup

此设置会覆盖git commit--cleanup选项的默认值。有关详细信息,请参阅git-commit[1]。更改默认值在您始终希望保留日志消息中以注释字符#开头的行时很有用,在这种情况下,您需要执行git config commit.cleanup whitespace(注意,如果您这样做,则必须自己删除提交日志模板中以#开头的帮助行)。

commit.gpgSign

一个布尔值,用于指定是否应该对所有提交进行 GPG 签名。在执行诸如变基之类的操作时使用此选项会导致大量提交被签名。使用代理可能很方便,以避免多次键入您的 GPG 密码。

commit.status

一个布尔值,用于启用/禁用在使用编辑器准备提交消息时在提交消息模板中包含状态信息。默认值为 true。

commit.template

指定一个文件路径,该文件用作新提交消息的模板。

commit.verbose

一个布尔值或整数,用于指定git commit的详细程度。请参阅git-commit[1]

钩子

此命令可以运行commit-msgprepare-commit-msgpre-commitpost-commitpost-rewrite钩子。有关更多信息,请参阅githooks[5]

文件

$GIT_DIR/COMMIT_EDITMSG

此文件包含正在进行的提交的提交消息。如果git commit由于错误在创建提交之前退出,则用户提供的任何提交消息(例如,在编辑器会话中)都将在此文件中可用,但将在下一次调用git commit时被覆盖。

Git

git[1]套件的一部分

scroll-to-top