原文:http://www.eecs.harvard.edu/~cduan/technical/git/git-1.shtml
翻译:http://blog.csdn.net/yhcharles/article/details/6593553
Repository的内容
Git的目的是管理一个项目,或是若干文件,这些项目或者文件会随着时间发生改变。Git把这些信息存放在一个叫做repository的数据结构中。
一个git repository包含,但不限于,以下内容:
- 一组commit(提交)对象
- 一组commit对象的引用,称为head
- 只有一个.git目录,在项目所在的根目录下
- repository与项目文件存放在一起。没有中心服务器版本库repository
一个commit对象包含以下三点:
- 一组文件,代表了该项目在某个时间点的状态
- 对父commit对象的引用
- 一个SHA1名字,长度为40的字符串来唯一的代表该commit对象。该名字是由该commit对象的相关信息hash得到,因此相同的commit具有相同的名字。
一个项目总有一个没有父对象的commit对象。这就是这个项目的第一个commit对象。
基于以上的认识,你可以把repository想象成一个commit对象组成的有向无环图,图中的边指向父commit对象,按照边的指向最终回到第一个commit。每当你想要进行一些操作来查询或者修改repository,你应该思考“我需要怎样来查询或者操作这个commit构成的图?”
Heads
一个head就是一个commit对象的引用。每一个head有一个名字。每个repository中有个默认的head称作master。一个repository中可以包含有任意多个head。在任一时刻,只有一个head作为“current head”(当前的head)。这个head也称为HEAD,必须大写。
注意:一个“head”(小写)可以代表repository中任何一个有名称的head;“HEAD”(大写)只代表当前的head。这个区别在Git的文档中被频繁使用。我也遵循这个习惯,head的名字,包括“HEAD”,使用斜体表示。
一个简单的repository
要创建一个repository,首先需要为项目创建一个目录,进入这个目录,然后运行命令git init。这个目录不一定要是空目录。
mkdir [project]
cd [project]
git init
这会在 [project]目录下创建一个 .git目录。
要创建一个commit,你需要做两件事:
- 用git add命令告诉Git哪些文件需要被包含在这个commit中。如果一个文件在上次一commit(即父commit)后没有改变,Git会自动把它包含在你将要进行的commit中。因此,你只需要把你修改或者新添加的文件用git add加进来。注意,该命令会递归处理目录,所以git add .会添加当前目录(及子目录)下所有被修改过的文件。
- 执行git commit来创建commit对象。新创建的commit对象将会把当前的HEAD作为它的父对象(然后,当提交完成后,HEAD会指向新的commit对象)。
为了简便,也可以用git commit -a来自动添加所有修改过的文件(除了新创建的文件以外)。
注意,如果你修改了一个文件,但是没有添加它,那么Git会自动包含前一个版本(未修改的版本)到这次的commit中。修改过的文件仍保留不动。
比如你用这种方式重建了三个commit。那么你的repository看起来应该是下面这样:
----> time ----->
(A) <-- (B) <-- (C)
^
|
master
^
|
HEAD
其中(A),(B)和(C)分别是第一个,第二个和第三个commit。
这里还有几个有用的命令:
- git log用来查看从HEAD回溯到第一个commit的全部提交记录。(当然,它的功能不限于此)
- git status查看当前项目状态和HEAD相比,哪些文件有过修改。文件被分成三种:新创建但未添加(用git add命令)的文件,修改过但没有添加的文件,以及已经添加过的文件。
- git diff查看HEAD和当前项目之间的diff信息。如果带上--cache选项,那么会在添加的文件和HEAD之间进行比较;不然就比较还未添加的文件。
- git mv和git rm分别用来标记需要移动(重命名)和删除的文件,和git add类似。
我个人的工作流程通常是这样:
- 写点程序
- git status查看我修改了哪些文件
- git diff [file]查看我具体做了哪些修改
- git commit -a -m [message]进行提交
现在,你已经创建了commit,那么如何引用某个commit呢?Git提供了很多方法。比如:
- 用它的SHA1名字,这个名字可以用git log命令查看到
- 用SHA1名字开头的几个字符
- 用head。例如,HEAD指的是HEAD代表的commit对象。你也可以用名字,如master。
- 利用commit的相对关系。在一个commi名字后面加上一个插入符号(^)可以表示该commit的父对象。例如,HEAD^是当前commi的父对象。