Git中文件有三种状态:已提交(committed)、已修改(modified)和已暂存(staged)。
状态 | 描述 |
---|---|
已修改 | 表示修改了文件,但还没有保存到数据库中 |
已暂存 | 表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中 |
已提交 | 表示数据已经安全地保存在本地数据库中 |
这会让我们的Git项目拥有三个阶段:工作区、暂存区以及Git仓库。
工作区是对项目的某个版本独立提取出来的内容。这些从Git仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。
暂存区是一个文件,保存了下次将要提交的文件列表信息,一般在Git仓库目录中。按照Git的术语叫做“索引”,不过一般说法还是叫“暂存区”。
Git仓库是Git用来保存项目的元数据和对象数据库的地方。这是Git中最重要的部分,从其他计算机克隆仓库时,复制的就是这里的数据。
基本的Git工作流程如下:
如果 Git 目录中保存着特定版本的文件,就属于 已提交 状态。 如果文件已修改并放入暂存区,就属于 已暂存 状态。 如果自上次检出后,作了修改但还没有放到暂存区域,就是 已修改 状态。
初次使用Git时需要配置以下内容:
用户信息
$ git config --global user.name "用户名"
$ git config --global user.email "电子邮箱"
文本编辑器
$ git config --global core.editor 文本编辑器
创建Git仓库后,仓库会检出所有文件的工作副本。通常我们会对这些文件进行修改,当完成一个阶段的目标后,想要记录下来,就将它提交到仓库。
工作目录下的每个文件都不外呼两种状态:已跟踪或未跟踪。已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能是未修改、已修改或已放入暂存区。简而言之,已跟踪的文件就是Git已经知道的文件。
工作目录中除了已跟踪文件外的其他文件都属于未跟踪文件,它们即不存在于上次快照的记录中,也没有被放入暂存区。
初次克隆某个仓库时,工作目录的所有文件都属于已跟踪文件,并处于未修改状态,因为Git刚刚检出了它们,而你尚未编辑过它们。
编辑过某些文件后,由于自上次提交后你对它们做了修改,Git将它们标记为修改文件。在工作时,你可以选择性地将这些修改过的文件放入暂存区,然后提交所有已暂存的修改,如此反复。
git status
命令的输出十分详细,但其用语有些繁琐。 Git 有一个选项可以帮你缩短状态命令的输出,这样可以以简洁的方式查看更改。 如果你使用 git status -s
命令或 git status --short
命令,你将得到一种格式更为紧凑的输出。
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
新添加的未跟踪文件前面有 ??
标记,新添加到暂存区中的文件前面有 A
标记,修改过的文件前面有 M
标记。 输出中有两栏,左栏指明了暂存区的状态,右栏指明了工作区的状态。例如,上面的状态报告显示: README
文件在工作区已修改但尚未暂存,而 lib/simplegit.rb
文件已修改且已暂存。 Rakefile
文件已修改,暂存后又作了修改,因此该文件的修改中既有已暂存的部分,又有未暂存的部分。
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore
的文件,列出要忽略的文件的模式。 来看一个实际的 .gitignore
例子:
$ cat .gitignore
*.[oa]
*~
第一行告诉 Git 忽略所有以 .o
或 .a
结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。 第二行告诉 Git 忽略所有名字以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。 此外,你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。 要养成一开始就为你的新仓库设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。
文件 .gitignore
的格式规范如下:
#
开头的行都会被 Git 忽略。/
)开头防止递归。/
)结尾指定目录。!
)取反。所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(*
)匹配零个或多个任意字符;[abc]
匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c); 问号(?
)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9]
表示匹配所有 0 到 9 的数字)。 使用两个星号(**
)表示匹配任意中间目录,比如 a/**/z
可以匹配 a/z
、 a/b/z
或 a/b/c/z
等。
我们再看一个 .gitignore
文件的例子:
# 忽略所有的 .a 文件
*.a
# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf
.gitignore文件创建在仓库根目录