这节课主要介绍下本地目录的文件修改后如何添加到暂存区、提交到 Git 版本库,以及如何比较文件内容差异、如何跳过添加暂存区步骤提交等内容。大家也发现了,提交的操作我们前几节提到过,当时可能没有太多概念,这节我们就来个系统讲解,补充强化之前学过的内容。

工作目录中的每个文件都有两种状态:已跟踪或未跟踪。跟踪的文件是最后一个快照中的文件,在此基础上可以不修改,修改或提交。简而言之,已跟踪文件就是 Git 知道的文件。

而未跟踪的文件就是工作目录中不在上一个快照中且不在暂存区中的所有文件,也就是说这部分内容你做了修改,但是还没告诉 Git。

第一次克隆存储库时,所有文件都会被跟踪,因为是从 Git 上拉取下来的,Git 当然知道。

在编辑文件时,Git 会将其视为已修改,因为自上次提交以来已对其进行了更改。在工作时,有选择地暂存这些已修改的文件,然后提交所有已暂存的更改,重复这个过程,就是我们的常规操作流程。

好了,接下来就跟着我的步骤进行进一步的学习,看下怎么让 Git 去实现文件修改提交的每一步。

1. 查看文件状态

如果想查看我们的工作目录下的文件处于已跟踪还是未跟踪状态,也就是说我们想看看哪些文件修改了还没告诉 Git,或者一些别的信息,比如当前所处的分支(分支的知识后续会讲)等。就可以用下面的命令:

$ git status
On branch master
Your branch is up to date with 'origin/master'.


nothing to commit, working tree clean

可以看到,当前所处的分支是 master,并且当前工作目录下没有任何要提交的内容。也就是说,目前工作目录的内容与 Git 管理的内容一样。

那么我在当前目录新增一个文件,并写入一些内容之后,我们再看下会发生什么。

$ echo 'test status' > test2.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.


Untracked files:
  (use "git add <file>..." to include in what will be committed)


        test2.txt


nothing added to commit but untracked files present (use "git add" to track)

可以看到,已经有未跟踪的内容了,就是 Untracked files 那部分信息。因为我们刚刚并没有添加到暂存区,Git 还不知道。

附:演示流程如下:

图片描述

2. 将修改添加到暂存区

上面的操作我们也看到了,当新增了一个文件之后,使用 "git status" 命令查看文件状态信息时,最后一行内容:nothing added to commit but untracked files present (use “git add” to track)。提示我们没有提交任何内容但是存在未跟踪的文件,括号里面说可以使用 “git add” 命令去使其被跟踪管理。

这个 “git add” 命令就是将新做的修改添加到 git 暂存区的,那么我们就来试一下,把上一步新建的文件进行添加:

$ git add test2.txt

之后再查看下文件状态:

$ git status
On branch master
Your branch is up to date with 'origin/master'.


Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)


        new file:   test2.tx

此时,文件 test2.txt 就到了 “Changes to be committed” 的内容下面,也就是将要被提交的修改,因为已经添加到了暂存区,接下来可以进行提交。

直到这里,一切都是那么顺滑,不对,顺利!

附:演示流程如下:
图片描述

3. 将暂存区内容提交

接着上一点,我们准备将 test2.txt 进行正式提交。

但是,但是,但是,我就不提交(微笑脸)。

直接提交岂不是太简单了?现在我在提交之前又反悔了,突然想起来还想加一句 “hello world”,那就加呗,加完我们再看看会变成什么鬼样子。

$ echo 'hello world' >> test2.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.


Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)


        new file:   test2.txt


Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)


        modified:   test2.

哎!不对啊。test2.txt 这个文件刚刚不是在 “Changes to be committed” 下面吗?现在怎么同时又存在于 “Changes not staged for commit” 下面了。这个文件怎么同时存在 “已暂存” 和 “未暂存” 两种状态了?

附:这部分演示流程如下:
图片描述

别急,跟我往下继续看!那要不我们先执行下提交看看会变成什么状态?好!说干就干!对了,忘了说了,提交命令是 “git commit -m ‘这是提交说明’”,hiahia~~~

$ git commit -m 'commit 1'
[master bba6ffb] commit 1
 1 file changed, 1 insertion(+)
 create mode 100644 test2.txt


$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)


Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)


        modified:   test2.txt


no changes added to commit (use "git add" and/or "git commit  -a")

仔细看:我在执行 "git commit" 之后,提示 test2.txt 已提交。但是我执行 “git status” 之后,却发现在 “Changes not staged for commit” 部分还存在一个 test2.txt,这是为啥?

其实,提交后只把前面步骤中执行了 “git add” 那部分修改进行了提交,而后面我再追加的 “hello world” 的内容由于没有执行 “git add”,并没有纳入 git 的暂存区,提交也就自然提交不了。那想要再提交这部分内容怎么办?简单啊!继续执行 “git add”,“git commit” 就好了。

$ git add test2.txt
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)


Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)


        modified:   test2.txt


$ git commit -m 'commit 2'
[master 446c174] commit 2
 1 file changed, 1 insertion(+)


$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)


nothing to commit, working tree clean

看,现在状态正常了。是不是一切都是那么熟悉?就像初恋般的感觉。

附:这部分演示流程如下:
图片描述

通过这个过程,我们可以看到,“git commit” 只把暂存区的修改提交了,也就是第一次执行了 “git add” 的修改被提交了,第二次的修改不会被提交。

4. 比较工作区和版本库的文件差异

前面步骤我们操作了修改文件后如何去添加到暂存区、提交版本库等流程,那么如果我们提交后又在本地做了修改,怎么比较版本库和本地工作区的差异呢?自然也是有办法的,执行如下命令就可以了:

$ git diff HEAD -- test.txt

我们试着在提交版本库后又做一些修改,比如我追加一行内容,再看下与版本库的差异,演示流程如下:

图片描述

5. 跳过暂存区直接提交

我们知道,如果对一个文件做了修改,想要提交至版本库之前必须先加入暂存区。但是,git 提供了一个偷懒的办法(毕竟,程序员效率至上嘛),就是可以跳过暂存区提交,使用如下命令:

$ git commit -a -m '备注'

演示流程如下:

图片描述

注意:“git commit -a -m” 这个命令必须在文件内容修改后使用,如果你的文件是刚新建的并且还没提交过,那么还是需要先 “git add”。

正常的开发过程中,对于提交日志的规范都有要求。日志是我们作为历史版本维护的一个很重要的内容,一个好的日志模板可以方便进行代码 review,以及后续开发者快速了解历史问题等等。本教程只是演示,实际开发中请遵守具体规范!

6. 总结

温故而知新,我们先走起。本节课内容总结如下:

  • 查看文件状态:git status
  • 将修改添加到暂存区:git add 文件名
  • 将暂存区内容提交:git commit -m ‘描述’
  • 比较工作区和版本库的文件差异:git diff HEAD – 文件名
  • 跳过暂存区直接提交:git commit -a

好了,今天的内容我们就讲到这里,希望大家多加练习,早日 get 到 git 的精髓!