## git commit 记录缓存内容的快照
现在你使用 `git add` 命令将想要快照的内容写入了缓存, 执行 `git commit` 就将它实际存储快照了。 Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步是告诉 Git 这些都是啥。
~~~
$ git config --global user.name 'Your Name'
$ git config --global user.email you@somedomain.com
~~~
让我们写入缓存,并提交对 `hello.rb` 的所有改动。在首个例子中,我们使用 `-m` 选项以在命令行中提供提交注释。
~~~
$ git add hello.rb
$ git status -s
M hello.rb
$ git commit -m 'my hola mundo changes'
[master 68aa034] my hola mundo changes
1 files changed, 2 insertions(+), 1 deletions(-)
~~~
现在我们已经记录了快照。如果我们再执行 `git status`,会看到我们有一个“干净的工作目录”。 这意味着我们在最近一次提交之后,没有做任何改动 —— 在我们的项目中没有未快照的工作。
~~~
$ git status
# On branch master
nothing to commit (working directory clean)
~~~
如果你漏掉了 `-m` 选项,Git 会尝试为你打开一个编辑器以填写提交信息。 如果 Git 在你对它的配置中找不到相关信息,默认会打开 `vim`。屏幕会像这样:
~~~
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: hello.rb
#
~
~
".git/COMMIT_EDITMSG" 9L, 257C
~~~
在此,你在文件头部添加实际的提交信息。以“#”开头的行都会被无视 ——Git 将 `git status` 的输出结果放在那儿以提示你都改了、缓存了啥。
通常,撰写良好的提交信息是很重要的。以开放源代码项目为例,多多少少以以下格式写你的提示消息是个不成文的规定:
简短的关于改动的总结(25个字或者更少)
如果有必要,更详细的解释文字。约 36 字时换行。在某些情况下,
第一行会被作为电子邮件的开头,而剩余的则会作为邮件内容。
将小结从内容隔开的空行是至关重要的(除非你没有内容);
如果这两个待在一起,有些 git 工具会犯迷糊。
空行之后是更多的段落。
- 列表也可以
- 通常使用连字符(-)或者星号(*)来标记列表,前面有个空格,
在列表项之间有空行,不过这些约定也会有些变化。
~~~
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: hello.rb
#
~
~
~
".git/COMMIT_EDITMSG" 25L, 884C written
~~~
提交注解是很重要的。因为 Git 很大一部分能耐就是它在组织本地提交和与他人分享的弹性, 它很给力地能够让你为逻辑独立的改变写三到四条提交注解,以便你的工作被同仁审阅。因为提交与推送改动是有区别的, 请务必花时间将各个逻辑独立的改动放到另外一个提交,并附上一份良好的提交注解, 以使与你合作的人能够方便地了解你所做的,以及你为何要这么做。
### git commit -a 自动将在提交前将已记录、修改的文件放入缓存区
如果你觉得 `git add` 提交缓存的流程太过繁琐,Git 也允许你用 `-a` 选项跳过这一步。 基本上这句话的意思就是,为任何已有记录的文件执行 `git add` —— 也就是说,任何在你最近的提交中已经存在,并且之后被修改的文件。 这让你能够用更 Subversion 方式的流程,修改些文件,然后想要快照所有所做的改动的时候执行 `git commit -a`。 不过你仍然需要执行 `git add` 来添加新文件,就像 Subversion 一样。
~~~
$ vim hello.rb
$ git status -s
M hello.rb
$ git commit -m 'changes to hello file'
# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: hello.rb
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -am 'changes to hello file'
[master 78b2670] changes to hello file
1 files changed, 2 insertions(+), 1 deletions(-)
~~~
注意,如果你不缓存改动,直接执行 `git commit`,Git 会直接给出 `git status` 命令的输出,提醒你啥也没缓存。我已将该消息中的重要部分高亮,它说没有添加需要提交的缓存。 如果你使用 `-a`,它会缓存并提交每个改动(不含新文件)。
现在你就完成了整个快照的流程 ——改些文件,然后用 `git add` 将要提交的改动提交到缓存, 用 `git status` 和 `git diff` 看看你都改了啥,最后 `git commit` 永久地保存快照。
> **简而言之**,执行 `git commit` 记录缓存区的快照。如果需要的话,这个快照可以用来做比较、共享以及恢复。