基本的快照功能
Git可以用来组建并保存你的项目快照,而后你就可以使用和比较这些快照。这部分会介绍一些组建并保存你的项目快照所需要的命令。
一个很重要的概念是Git有一个“索引”,它用来对存储项目快照的数据准备区进行分类。在你的当前工作目录下,你可以对发生更改的文件形成一系列的组织良好的快照,而不是马上就提交所有的文件更改。
简单来说,你可以用 git add 命令来跟踪新建文件,也可以用这条命令将更改加入到已经跟踪的文件中。而后可以使用 git status 和 git diff 命令来查看哪些被更改和记录了,最后可以用 git commit 命令将你的项目快照记录到你的项目历史记录中。这就是你大部分时间的一个基本的工作流程。
git add 将文件目录加入到数据准备区中
在Git中,提交文件之前,你可以先将文件的目录加入到数据准备区中。如果这个文件是新的,你可以用 git add 命令先将该文件加入到你的数据准备区,但是,即使这个文件已经被跟踪了--比如说,它存在于你的上一次提交中--你仍然需要使用 git add 命令向你的数据准备区中添加新的更改。让我们看一下几个例子。
回到上一节我们创建的"Hello World"那个例子,一旦我们初始化了整个项目,我们就可以向其中加入文件,我们可以使用 git add 命令来做这个。而后我们可以使用 git status 命令来查看项目的状态。
$ git status -s
?? README
?? hello.rb
现在我们有两个未跟踪的文件,我们可以开始将它们加入。
$ git add README hello.rb
现在如果我们再次运行 git status 命令,可以发现这两个文件已经被加入了。
$ git status -s
A README
A hello.rb
还可以使用命令 git add . ,(译者注:“.”在linux指代当前目录)通过指定当前的工作目录,可以将项目下的所有文件都加入,这样做很常见。由于Git会递归的将一个目录下的所有文件都加入,如果你指定了当前的工作目录,Git就会开始追踪当前目录下的每一个文件。这种情况下, git add . 和 git add README hello.rb 的效果是一样的。对于 git add * 命令,这条命令不会递归的加入每一个子目录。
现在,如果我们修改这些文件,并再次运行 git status 命令,我们可以看到一些奇特的东西。
$ vim README
$ git status -s
AM README
A hello.rb
"AM"状态表明从我们上一次添加,磁盘上的READE文件已经发生了更改。这意味着,如果我们现在提交这一快照,我们记录的是上一次 git add的内容,而不是现在磁盘上已经发生更改的内容。Git不会主观臆测磁盘上的内容是你想要提交的快照--你必须要使用 git add 命令告诉Git.
简单来说,你可以对一个文件使用 git add 命令将文件的任何更改包含进你的下一次提交中。任何你未添加的更改都不会被包含进去,这意味着,相对于其他的SCM系统,你可以让你的项目快照变的更精确。
在 Pro Git 这本书中有一个很有趣的例子,你可以使用 git add 的“-p”选项,一次只记录已更改的文件的一部分,这样做更具灵活性。
git status 查看当前工作目录和数据准备区的文件状态
正如你在 git add 章节看到的,为了查看数据准备区的数据和你当前工作目录的代码的区别,你可以使用 git status 命令。使用 “-s”选项可以给你一个比较短的输出。没有这个选项的话,git status 会给你一个更多的上下文关系和线索。不用“-s”选项的话,输出像这样:
$ git status -s AM README A hello.rb使用选项的话,状态输出像这样:
$ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: README # new file: hello.rb # # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: README #你可以很清楚的看到短的输出有多简洁,但是长的输出对于你下面要使用什么命令会有很多更有用的提示。
Git会告诉你自从你上次提交之后删除掉的所有文件,或者说那些改变或记录的文件。
$ git status -s M README D hello.rb你可以看到,在短的状态输出中有两列,第一列是相对于数据准备区的,第二列是相对于当前工作目录的。举个例子,如果你已经记录了README文件,而后你再次更改这个文件,但是没有再次运行 git add 命令,你可以看到这样的输出:
$ git status -s MM README D hello.rb简单来说,你可以是使用 git status 命令来查看那些自从你上一次提交之后更改 并且/或者 提交的文件,这样你就可以决定,如果你要提交一个快照,什么需要记录在其中。
git diff 展示已经记录的文件和更改但未记录的文件之间的差异
git diff 命令主要有两个用途。一个用途我们会在这里说明,另一个用途会在"检查和比较"这个章节中说明。这里要说明的用法是为了表明那些已经记录的文件或已更改但未记录的文件之间的差异。
git diff 展示未记录的更改的差异
没有额外的参数,简单的 git diff 命令会以统一的diff格式(补丁的格式)展示自从你上一次提交或者你还未将这些改变记录进你的下一次提交快照中的你的项目代码或内容的更改。
$ vim hello.rb $ git status -s M hello.rb $ git diff diff --git a/hello.rb b/hello.rb index d62ac43..8d15d50 100644 --- a/hello.rb +++ b/hello.rb @@ -1,7 +1,7 @@ class HelloWorld def self.hello - puts "hello world" + puts "hola mundo" end end所以, git status 会展示自从你上一次提交,文件已经改变 并且/或者 记录了什么,而 git diff 命令会确切的一行一行的展示这些改变是什么。它是一个很好的 git status 的后继命令。
git diff --cached 展示已经记录的更改的文件差异
git diff --cached 会告诉你什么内容已经被写进数据准备区了。也就是说,它会向你展示下一次提交的快照中的内容。因此,如果你已经将上例中hello.rb的改变写进数据准备区了, git diff 不会向你展示任何东西,因为这条命令只会展示那些未被记录进数据缓冲区的改变。
$ git status -s M hello.rb $ git add hello.rb $ git status -s M hello.rb $ git diff $如果你想查看已经写入数据准备去的改变,可以运行 git diff --cached 命令。
$ git status -s M hello.rb $ git diff $ $ git diff --cached diff --git a/hello.rb b/hello.rb index d62ac43..8d15d50 100644 --- a/hello.rb +++ b/hello.rb @@ -1,7 +1,7 @@ class HelloWorld def self.hello - puts "hello world" + puts "hola mundo" end end
git diff HEAD 展示所有的已记录和未记录的文件差异
如果你想同时查看已经记录和未被记录的文件差异,你可以运行 git diff HEAD 命令--这标明你只想查看当前工作目录和你上一次提交之间的文件差异,忽略掉数据准备区。如果我们再次更改hello.rb 文件,我们现在就有了一些已经记录的更改和未被记录的更改。下面会向你展示这三条diff命令:
$ vim hello.rb $ git diff diff --git a/hello.rb b/hello.rb index 4f40006..2ae9ba4 100644 --- a/hello.rb +++ b/hello.rb @@ -1,7 +1,7 @@ class HelloWorld + # says hello def self.hello puts "hola mundo" end end $ git diff --cached diff --git a/hello.rb b/hello.rb index 2aabb6e..4f40006 100644 --- a/hello.rb +++ b/hello.rb @@ -1,7 +1,7 @@ class HelloWorld def self.hello - puts "hello world" + puts "hola mundo" end end $ git diff HEAD diff --git a/hello.rb b/hello.rb index 2aabb6e..2ae9ba4 100644 --- a/hello.rb +++ b/hello.rb @@ -1,7 +1,8 @@ class HelloWorld + # says hello def self.hello - puts "hello world" + puts "hola mundo" end end
git diff --stat 展示这些改变的概要,而不是把文件差异都展示出来
如果我们不想要完全的diff输出,但是也不仅仅想要 git status 的输出,我们可以使用 --stat 这一选项,它会给我们一个所有更改的概要。下面是和前面相同的例子,但使用的是 --stat 选项。
$ git status -s MM hello.rb $ git diff --stat hello.rb | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) $ git diff --cached --stat hello.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) $ git diff HEAD --stat hello.rb | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
你也可以在这些选项之后提供一个文件路径,将 diff 限制到制定的文件或子目录。
简单来说,你可以运行 git diff 来查看比 git status 命令的更详细的一些内---逐行的展示文件已经改变或记录了什么。
(未完待续。。。。这一节剩下的部分改日补上,实在受不了了)