Git 🌙
简体中文 ▾ Topics ▾ Latest version ▾ git-commit last updated in 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] ,在再次使用“提交”命令之前从工作树和索引中删除文件;

  3. 通过将文件列为“commit”命令的参数(不带—​interactive或—​patch switch),在这种情况下,提交将忽略索引中的更改,而是记录所列文件的当前内容(Git必须已经知道);

  4. 通过在’commit’命令中使用-a开关,自动 "添加 "所有已知文件的修改(即所有已经列在索引中的文件),并自动 "清除 "索引中已经从工作树中删除的文件,然后执行实际的提交;

  5. 通过在’commit’命令中使用 --interactive 或 --patch 开关,在最终完成操作之前,逐一决定哪些文件或块应该成为提交的一部分,而不是索引中的内容。参见 git-add[1] 的 ``交互式模式’一节,了解如何操作这些模式。

`--dry-run`选项可以用来获得上述任何一个选项为下一次提交所包含的内容的摘要,只要给出相同的参数(选项和路径)即可。

如果你做了一个提交,然后紧接着发现了一个错误,你可以用’git reset’来恢复它。

选项

-a
--all

告诉命令自动阶段化已经被修改和删除的文件,但你没有告诉 Git 的新文件不受影响。

-p
--patch

使用交互式补丁选择界面来选择要提交的修改。详情见 git-add[1]

-C <提交>
--reuse-message=<提交>

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

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

和'-C’一样,但用 -c 会调用编辑器,这样用户可以进一步编辑提交信息。

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

创建一个新的提交,在使用 git rebase --autosquash 时,"修复"<commit>。普通的`--fixup=<commit>会创建一个 "fixup!"的提交,改变<commit>的内容,但不改变其日志信息。--fixup=amend:<commit>类似,但会创建一个 "修正!"的提交,同时用 "修正!"的提交的日志信息替换<commit>的日志信息。 `--fixup=reword:<commit>`创建一个 "修正!"提交,用自己的日志信息替换<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`。

--fixup=reword:<commit>`是--fixup=amend:<commit>--only`的简写。它创建一个只有日志信息的 "修正!"提交(忽略索引中的任何修改)。当被`git rebase --autosquash`压制时,它会替换`<commit>`的日志信息而不做任何其他改动。

当被 git rebase --autosquash 应用时,"fixup!"和 "amend!"提交都不会改变 <commit> 的作者身份。 详情见 git-rebase[1]

--squash=<提交>

构建一条提交信息,供`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

当显示 "short "或 "porcelain "状态输出时,逐字打印文件名,用NUL而不是LF来结束条目。 如果没有给出格式,就意味着是`--porcelain`输出格式。 如果没有`-z`选项,带有 "不寻常 "字符的文件名将被引用,正如对配置变量`core.quotePath`的解释(见git-config[1])。

-F <文件>
--file=<文件>

从给定文件中获取提交信息。 使用'-'可以从标准输入中读取信息。

--author=<提交人>

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

--date=<日期>

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

-m <消息>
--message=<msg>

使用给定的<msg>作为提交信息。 如果给定了多个`-m`选项,它们的值会作为单独的段落串联起来。

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

-t <文件>
--template=<文件>

编辑提交信息时,以给定文件中的内容启动编辑器。 commit.template`配置变量经常被用来给命令隐含这个选项。 这个机制可以被那些希望通过一些提示来指导参与者在消息中以何种顺序书写的项目所使用。 如果用户在没有编辑消息的情况下退出编辑器,提交将被中止。 当用其他方式给出消息时,例如用-m`或`-F`选项时,这没有影响。

-s
--signoff
--no-signoff

在提交日志信息的末尾添加提交者的 "Signed-off-by "预告片。 签名的意义取决于你所提交的项目。 例如,它可以证明提交者有权利在项目许可下提交作品,或者同意一些贡献者的陈述,如开发者的原产地证书。 关于Linux内核和Git项目使用的证书,请参见http://developercertificate.org)。 请查阅你要贡献的项目的文档或领导层,以了解该项目如何使用签名。

--no-signoff选项可以用来反驳先前在命令行上的—​signoff选项。

--trailer <令牌>[(=|:)<值>]

指定一个(<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
--[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>可以是`strip`、whitespaceverbatimscissors`或`default

剥离

剥离前面和后面的空行、后面的空白、注释和折叠的连续空行。

空白字符

与 "strip "相同,只是#commentary不被删除。

逐字逐句

完全不要改变信息。

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`选项和显式pathspec的效果),当命令行没有通过`-m`、-F-c`等选项指定其他信息时,原始提交的信息会被用作起点,而不是空信息。 新的提交与当前的提交具有相同的父辈和作者(--reset-author`选项可以反驳)。

它大致相当于:

	$ git reset --soft HEAD^
	$ ... 另辟蹊径,找到正确的目录树中 ...
	$ git commit -c ORIG_HEAD

但可以用来修改合并提交。

如果你修改了一个已经发布的提交,你应该明白重写历史的意义。 参见 git-rebase[1]中的 “从上游仓库重建中恢复” 部分。)

--no-post-rewrite

绕过post-rewrite钩子。

-i
--include

在对迄今为止的暂存内容进行提交之前,对命令行上给出的路径内容也进行暂存。 这通常不是你想要的,除非你正在结束一个冲突的合并。

-o
--only

在提交时,只取命令行上指定的工作树的最新内容,而不考虑其他路径上的缓存内容。这是’git commit’的默认操作模式,如果在命令行中给出了任何路径,在这种情况下可以省略该选项。 如果该选项与`--amend`一起指定,则不需要指定路径,可以用来修改最后的提交,而不提交已经被暂存的修改。如果和`--allow-empty`一起使用,也不需要指定路径,将创建一个空的提交。

--pathspec-from-file=<file>

Pathspec 在 <文件> 中传递,而不是在命令行参数中传递。如果 <文件> 正好是 -,则使用标准输入。路径规范元素由 LF 或 CR/LF 分隔。可以引用配置变量 core.quotePath 的路径规范元素(请参见 git-config[1])。另请参见 --pathspec-file-nul 和全局 --literal-pathspecs

--pathspec-file-nul

只有在使用 --pathspec-from-file 选项时才有意义。指定路径元素用 NUL 字符分隔,所有其他字符都按字面意思(包括换行符和引号)表示。

-u[<模式>]
--untracked-files[=<模式>]

显示未追踪文件。

模式参数是可选的(默认为 "所有"),用于指定对未追踪文件的处理;当没有使用-u时,默认为 "正常",即显示未追踪的文件和目录。

可选项:

  • no - 显示未被追踪的文件

  • normal - 显示未被追踪的文件和目录

  • all - 也显示未被追踪的目录中的单个文件。

All usual spellings for Boolean value true are taken as normal and false as no. The default can be changed using the status.showUntrackedFiles configuration variable documented in git-config[1].

-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[=<键 ID>]
--no-gpg-sign

GPG 签名提交。keyid 参数是可选的,默认为提交者身份;如果指定了,则必须与选项相连,不加空格。--no-gpg-sign 用于还原 commit.gpgSign 配置变量和先前的 --gpg-sign

--

不将之后的参数解释为选项。

<路径规范>…​

当命令行中给出pathspec时,提交符合pathspec的文件内容,而不记录已经添加到索引中的修改。这些文件的内容也会在下一次提交时在之前的文件基础上被暂存。

更多细节请参见 gitglossary[7] 中的 路径规范 条目。

实例

在记录自己的工作时,工作树中修改过的文件的内容会通过 git add 暂时存储到一个叫做 "index" 的暂存区域。 一个文件可以用 git restore --staged <问价> 恢复到上次提交时的状态,只是在索引中,而不是在工作目录树中,这实际上是恢复了’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 add`和`git 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.c`和`hello.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.name`和`user.email`,或者,如果不存在,环境变量EMAIL,或者,如果没有设置,系统用户名和用于发送邮件的主机名(取自`/etc/mailname`,如果该文件不存在,则返回到完全合格的主机名)。

如果设置了`author.name`和`committer.name`及其相应的email选项,将覆盖`user.name`和`user.email`,并由环境变量自行覆盖。

典型的用法是只设置 "user.name "和 "user.email "变量;其他选项是为更复杂的使用情况提供的。

日期格式

GIT_AUTHOR_DATE, GIT_COMMITTER_DATE 环境变量:

Git 内部格式

<unix 时间戳> <时区偏移量>,其中 <unix 时间戳> 是自 UNIX epoch 以来的秒数。 <时区偏移量> 是相对于 UTC 的正或负偏移量。例如,CET(比 UTC 提前1小时)为 +0100

RFC 2822

The standard date format as described by RFC 2822, for example 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

Note
此外,日期部分还接受以下格式: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

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

  2. git loggit showgit blame 和它们的朋友们会查看提交对象的 encoding 头,并尝试将日志信息重新编码为 UTF-8,除非另有指定。 您可以在`.git/config` 文件中使用 i18n.logOutputEncoding 指定所需的输出编码,像这样:

    [i18n]
    	logOutputEncoding = ISO-8859-1

    如果你没有这个配置变量,则使用`i18n.commitEncoding`的值来代替。

请注意,我们特意选择在提交对象层面上,不对提交日志信息进行重新编码,因为重新编码为UTF-8不一定是一个可逆的操作。

环境和配置变量

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

Warning

Missing zh_HANS-CN/includes/cmd-config-section-rest.txt

See original version for this content.

Warning

Missing zh_HANS-CN/config/commit.txt

See original version for this content.

钩子

这个命令可以运行`commit-msg`、prepare-commit-msgpre-commit、`post-commit`和`post-rewrite`钩子。 更多信息见githooks[5]

文件

$GIT_DIR/COMMIT_EDITMSG

该文件包含正在进行的提交的提交信息。 如果`git commit`在创建提交前因错误而退出,任何由用户提供的提交信息(例如在编辑器会话中)都会在此文件中出现,但会被下次调用`git commit`时覆盖。

GIT

属于 git[1] 文档

scroll-to-top