阅读本教程之前最好先浏览一遍 “Git 初级教程(第一部分)”。
本教程主要介绍了 Git 的两个基本结构:“对象数据库”(object database)和“索引文件”(index file);提供给读者能够阅读Git其它文档所需的必备知识;
Git 对象数据库(object database)
$ mkdir test-project $ cd test-project $ git init Initialized empty Git repository in .git/ $ echo 'hello world' > file.txt $ git add . $ git commit -a -m "initial commit" Created initial commit 54196cc2703dc165cbd373a65a4dcf22d50ae7f7 create mode 100644 file.txt $ echo 'hello world!' >file.txt $ git commit -a -m "add emphasis" Created commit c4d59f390b9cfd4318117afde11d601c1085f241
$ git-cat-file -t 54196cc2
commit
$ git-cat-file commit 54196cc2
tree 92b8b694ffb1675e5975148e1121810081dbdffe
author J. Bruce Fields <bfields@puzzle.fieldses.org> 1143414668 -0500
committer J. Bruce Fields <bfields@puzzle.fieldses.org> 1143414668 -0500
initial commit
$ git ls-tree 92b8b694
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad file.txt
$ git cat-file -t 3b18e512
blob
$ git cat-file blob 3b18e512
hello world
$ find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/info
.git/objects/3b
.git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad
.git/objects/92
.git/objects/92/b8b694ffb1675e5975148e1121810081dbdffe
.git/objects/54
.git/objects/54/196cc2703dc165cbd373a65a4dcf22d50ae7f7
.git/objects/a0
.git/objects/a0/423896973644771497bdc03eb99d5281615b51
.git/objects/d0
.git/objects/d0/492b368b66bdabf2ac1fd8c92b39d3db916e59
.git/objects/c4
.git/objects/c4/d59f390b9cfd4318117afde11d601c1085f241
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
c4d59f390b9cfd4318117afde11d601c1085f241
$ git cat-file -t c4d59f39
commit
$ git cat-file commit c4d59f39
tree d0492b368b66bdabf2ac1fd8c92b39d3db916e59
parent 54196cc2703dc165cbd373a65a4dcf22d50ae7f7
author J. Bruce Fields <bfields@puzzle.fieldses.org> 1143418702 -0500
committer J. Bruce Fields <bfields@puzzle.fieldses.org> 1143418702 -0500
add emphasis
$ git ls-tree d0492b36
100644 blob a0423896973644771497bdc03eb99d5281615b51 file.txt
$ git cat-file blob a0423896
hello world!
$ git-cat-file commit 54196cc2
tree 92b8b694ffb1675e5975148e1121810081dbdffe
author J. Bruce Fields <bfields@puzzle.fieldses.org> 1143414668 -0500
committer J. Bruce Fields <bfields@puzzle.fieldses.org> 1143414668 -0500
initial commit
这个树对象就是我们最初查看的树,这个最初的提交对象特殊的地方在于他没有父对象。
大多数提交都仅有一个父对象,但是很多时候一个提交也可能有多个父对象。如果一个提交代表了一个合并(merge)操作,这个提交就会有多个父对象,而那些父对象指向了各个被合并的分支的头。
除了blob,树(tree)和提交(commit)之外,还有一种Git对象:标记(tag),本教程不讨论标记(tag);详情请参考git-tag(1)。
到目前为止,我们已经学习了Git怎样用对象数据库来描述一个工程的历史:
- “提交”对象指向“树”对象来表现一个目录在某个特定历史点的快照;同时,“提交”对象指向“父”提交对象来显示它们在工程历史中的轨迹。
- “树”对象表现单个目录的状态,把目录名字和一堆“blob”对象或“树(tree)”对象联系在一起;其中“blob”对象包含文件数据内容,而树对象包含子目录信息。
- “blob”对象包含文件数据内容(但不包含任何其它的结构信息)。
- ./git/refs/heads/存放了所有分支(branch)的头提交对象的引用。
- 当前分支(branch)的名字存放在./git/HEAD。
索引文件(index file)
$ echo "hello world, again" >>file.txt
$ git diff
--- a/file.txt
+++ b/file.txt
@@ -1 +1,2 @@
hello world!
+hello world, again
$ git add file.txt
$ git diff
$ git-diff HEAD
diff --git a/file.txt b/file.txt
index a042389..513feba 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1,2 @@
hello world!
+hello world, again
所以,“git diff”命令不是和头(HEAD)比较,而是和“某种其它的东西”在比较。事实上这里说的“某种其它的东西”就是索引文件(index file)。索引文件以二进制的形式存放在.git/index,我们可以用ls-files来查看索引文件:
$ git ls-files --stage
100644 513feba2e53ebbd2532419ded848ba19de88ba00 0 file.txt
$ git cat-file -t 513feba2
blob
$ git cat-file blob 513feba2
hello world!
hello world, again
可以看出,“git add” 命令新建了一个blob对象,然后放了一个指向这个blob对象的引用在索引文件中。如果我们再次修改file.txt的内容,“git-diff”的输出将会反映新的修改:
$ echo 'again?' >>file.txt
$ git diff
index 513feba..ba3da7b 100644
--- a/file.txt
+++ b/file.txt
@@ -1,2 +1,3 @@
hello world!
hello world, again
+again?
$ git diff HEAD
diff --git a/file.txt b/file.txt
index a042389..ba3da7b 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1,3 @@
hello world!
+hello world, again
+again?
$ git diff --cached
diff --git a/file.txt b/file.txt
index a042389..513feba 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1,2 @@
hello world!
+hello world, again
$ git commit -m "repeat"
$ git diff HEAD
diff --git a/file.txt b/file.txt
index 513feba..ba3da7b 100644
--- a/file.txt
+++ b/file.txt
@@ -1,2 +1,3 @@
hello world!
hello world, again
+again?
$ echo "goodbye, world" >closing.txt
$ git add closing.txt
git-add的作用就是在索引文件中加入新的一项:
$ git ls-files --stage
100644 8b9743b20d4b15be3955fc8d5cd2b09cd2336138 0 closing.txt
100644 513feba2e53ebbd2532419ded848ba19de88ba00 0 file.txt
$ git cat-file blob 8b9743b2
goodbye, world
“status”命令是一个快速获得当前概况的方法:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: closing.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: file.txt
#
进一步?
现在你已经具备了阅读所有的git命令参考手册所需的知识;通过手册先了解Everyday git里面提到的Git命令是一个好的开始。 你能在 Glossary 里面查询所有不了解的术语.
Git User's Manual 提供了对Git更深入的介绍.
CVS migration 解释了怎样把CVS库(CVS repository)导入到Git里面,以及怎样用类似CVS的方式使用Git。
howtos 提供了一些关于Git使用的有趣的例子.
对Git的开发人员, Core tutorial 深入了关于Git机制的底层细节,比如创建一个新提交的底层机制.












Git 初级教程:第二部分
翻译: 
et 举人
这是Git很重要的一个文档。中英文水平都很烂,凑合翻了翻,欢迎指正。。。
05/03/2008
et 举人
还有,其实这篇文章只讲了两个简单的东西:
1。git里面的有4种对象;
2。git里面的commit命令是从index file提交到HEAD上,要先把working 目录的变动更新到index file,以后才能再把index file的更新提交到HEAD上。
其中:
git-diff 比较工作目录和索引文件
git-diff HEAD 比较工作目录和HEAD
git diff --cached 比较index和HEAD
05/03/2008