基本概念
git共有3种状态:已提交(committed),已修改(modified),已暂存(staged)。 已提交表示数据已经安全的保存在本地数据库中。 已修改表示修改了文件,但还没保存到数据库中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。由此引入 Git 项目的三个工作区域的概念:Git 仓库、工作目录以及暂存区域。
image.png
描述:
Git 仓库Repository
Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。
工作目录working Directory
工作目录是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。
暂存区域 staging Area
暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。 有时候也被称作`‘索引’',不过一般说法还是叫暂存区域。
git的基本使用流程:
- 1、在工作目录中修改文件。
- 2、暂存文件,将文件的快照放入暂存区域。
- 3、提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。
创建一个空的项目,文件夹命名为gitTest,cd到该目录:
liuxingxingdeMacBook-Pro:gitTest liuxingxing$ git init
Initialized empty Git repository in /Users/liuxingxing/Desktop/MyDesk/Demo/gitTest/.git/
liuxingxingdeMacBook-Pro:gitTest liuxingxing$
此时查询状态:默认分支为master,并且提示没有需要提交的文件
liuxingxingdeMacBook-Pro:gitTest liuxingxing$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
现在我们创建一个readme文件再来测试一下状态:
liuxingxingdeMacBook-Pro:gitTest liuxingxing$ echo "My Project" > README
liuxingxingdeMacBook-Pro:gitTest liuxingxing$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
提示我们没有需要提交的文件,但是有未被跟踪的文件README。所谓untracked,是与tracked相对应的,即未跟踪与已跟踪。 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。编辑过某些文件之后,由于自上次提交后你对它们做了修改,Git 将它们标记为已修改文件。 我们逐步将这些修改过的文件放入暂存区,然后提交所有暂存了的修改,如此反复。所以使用 Git 时文件的生命周期如下:
image.png
现在我们将readme纳入到跟踪文件中:
image.png只要在 Changes to be committed 这行下面的,就说明是已暂存状态。 如果此时提交,那么该文件此时此刻的版本将被留存在历史记录中。git add 命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。
现在我们再次更新README以用来解释git add这个命令:
image.png文件 README出现在 Changes not staged for commit 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。 要暂存这次更新,需要运行 git add 命令。 这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。 将这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适。
可以使用更简单的展示方式查看状态:
image.png$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
新添加的未跟踪文件前面有 ?? 标记,新添加到暂存区中的文件前面有 A 标记,修改过的文件前面有 M 标记。 你可能注意到了 M 有两个可以出现的位置,出现在右边的 M 表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M 表示该文件被修改了并放入了暂存区。 例如,上面的状态报告显示: README 文件在工作区被修改了但是还没有将修改后的文件放入暂存区,lib/simplegit.rb 文件被修改了并将修改后的文件放入了暂存区。 而 Rakefile 在工作区被修改并提交到暂存区后又在工作区中被修改了,所以在暂存区和工作区都有该文件被修改了的记录。
忽略文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 文件 .gitignore 的格式规范如下:
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
查看已暂存和未暂存的修改
image.png查看已暂存和未暂存的修改
git diff:比较的是工作目录中当前文件和暂存区域快照之间的差异, 也就是修改之后还没有暂存起来的变化内容。若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached 命令。(Git 1.6.1 及更高版本还允许使用 git diff --staged,效果是相同的,但更好记些。)请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。
提交更新
现在的暂存区域已经准备妥当可以提交了。 在此之前,请一定要确认还有什么修改过的或新建的文件还没有 git add 过,否则提交的时候不会记录这些还没暂存起来的变化。 这些修改过的文件只保留在本地磁盘。 所以,每次准备提交前,先用 git status 看下,是不是都已暂存起来了, 然后再运行提交命令 git commit.
git commit
git commit -m "Story 182: 写提交日志"
跳过使用暂存区域
尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤
git commit -a -m 'added new benchmarks'
image.png
查看提交日志的不同显示效果
image.png使用 -p,用来显示每次提交的内容差异。 你也可以加上 -2 来仅显示最近两次提交
image.png image.png image.png移出文件,文件分为好几种状态,我们分别做演示:
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
1、移除.README.swp文件(此时文件已经commit,我们之后并未做审核修改):
image.png2、如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f(译注:即 force 的首字母)。 这是一种安全特性,用于防止误删还没有添加到快照的数据,这样的数据不能被 Git 恢复,例如,我创建的abc.text 文件的过程:
image.png因为此时的abc.text 文件在暂存区,那么使用git rm abc.text 就会出错:
image.png
所以,我们要使用 git rm -f abc.text来删除文件并查看状态:
image.png
现在abc.text文件虽然被删除,但是没有提交,我们将其恢复:
image.png
此时文件内容为“first”,因为我修改为second后放在暂存区,然后将其删除了,所以保存的是上次commit后的状态:
c
3、我修改了abc.text文件,并未将文件放入到暂存区,此时我想删除文件会出错:
image.png解决办法仍是强制删除:
git rm -f abc.text
上面个的三种操作,都是基于将文件移除到工作区域的,如果我们单纯的就是想让文件保留在磁盘,但是并不想让 Git 继续跟踪,当你忘记添加 .gitignore 文件,不小心把一个很大的日志文件或一堆 .a 这样的编译生成文件添加到暂存区时,这一做法尤其有用。 为达到这一目的,使用 --cached 选项,我们可以做如下操作(仍然需要分多种情况):
1、文件已经commit,并未被修改,此时文件还在工作目录,只是未被跟踪:
image.png image.png我们将user文件重新添加回来测试第二种情况:
image.png
2、 修改过user文件,并且已经放到暂存区域(这是可以直接移除跟踪的,不会报错):
image.png3、我修改了user文件,并未将文件放入到暂存区(也是不会报错):
移动文件操作
不像其它的 VCS 系统,Git 并不显式跟踪文件移动操作。 如果在 Git 中重命名了某个文件,仓库中存储的元数据并不会体现出这是一次改名操作。 不过 Git 非常聪明,它会推断出究竟发生了什么,至于具体是如何做到的,我们稍后再谈。
既然如此,当你看到 Git 的 mv 命令时一定会困惑不已。 要在 Git 中对文件改名,可以这么做:
git mv file_from file_to
image.png
其实,运行 git mv 就相当于运行了下面三条命令:
$ mv README.md README
$ git rm README.md
$ git add README
如此分开操作,Git 也会意识到这是一次改名,所以不管何种方式结果都一样。 两者唯一的区别是,mv 是一条命令而另一种方式需要三条命令,直接用 git mv 轻便得多。 不过有时候用其他工具批处理改名的话,要记得在提交前删除老的文件名,再添加新的文件名。
网友评论