代码改变世界

Git学习笔记(一)

2011-03-08 22:38  横刀天笑  阅读(5254)  评论(11编辑  收藏  举报

今天花了点时间学习了一下分布式版本控制系统Git,为了避免遗忘,写点笔记放在这里。也当做版本化吧。

基本概念

我看的是Pro Git这本书,第一章用很短的篇幅介绍了一下版本控制工具。从最开始的LVCS,就是将版本库放在本地,比如rcs。这样的版本控制工具有个弊端就是难以与他人协作。然后介绍到集中化的版本控制工具(CVCS),像典型的SVN啊,VSS啊,CVS啊都属于这个类别。这种版本控制工具有一个中央服务器,然后版本库放在这个服务器上。这样解决了LVCS系统难以多人协作的问题,但是出现另外一个问题:如果现在网络不可用,那么你就无法提交代码了,这中间的任何修改历史都无法保存下来(虽然像SVN这样的工具提供了Local History可以解决这样的问题)。而且,重则全部落在中央服务器上了,如果中央服务器垮掉了,那就over了。对这点我有个感受是,我现在在一个分布式的团队工作:北京和伦敦。SVN服务器在伦敦,我们通过VPN连接到伦敦的SVN Server,可想而知,那个提交的速度非常的慢,甚至还出现过几次SVN Server离线的状态,然后我们上班时间又不一致,需要等到对方同事上线之后才能解决,对正常工作带来很大的影响。还有一个感受来自Code Review中,我们每天早晨全组成员一起会对昨天提交的代码进行一次Code Review,Code Review所依赖的工具就是diff,但是对于CVCS这样的工具,需要连接远程的server才能比较版本差异(当然,也可以建一个本地SVN曲线救国),导致Code Review效率非常低。

有这么多困境,那有什么方法可以解决这些问题呢?答案就是分布式版本控制系统(DVCS)。Git就是这其中最热的那一个。Git不再将版本库完全放到远程服务器,每个客户端也都保存着自己的版本库。而且与SVN等工具相比还有一些特有的特性。比如在SVN中,有一个文件A,你修改该文件后,我们叫新文件A1,那么SVN下一次签入只保存A到A1的增量(A1-A),这样可以极大的节省空间,但是在面对上面说的Code Review的情况,我们要比较两个版本的历史,我们就必须去服务器上将原来那个版本拿下来。但是Git就不同了,在Git中,修改文件后会将A1完全保存下来。这样每一次提交就会生成一个当前版本库的新镜像,包含有新修改后的文件(对于没有修改的文件,是不会复制到新的镜像的,只有一个链接指向旧的文件)。这样在Code Review的时候直接从本地拿到两个版本的文件就行了,速度是非常快的。而且因为有了本地库,即使是没有网络的情况下,我们也可以正常的提交,等到网络可用的时候我们再将所有更新push到中央库。这样每一次提交的历史都会在本地库中有记录。

看到上面的情况,就好像算法中的时间换空间,空间换时间。SVN等就好像是用时间换空间,而Git就好像是空间换时间(但是Git会对这些镜像进行压缩,所以空间占用并没有想象的那么严重)。

Git基础

每种工具都有自己所遵循的某种哲学,而这又对该工具的使用方式和某些叫法有着重要的影响。

在Git中,大部分命令都是在本地完成的,只和本地的文件或资源打交道,不需要连接到远程服务器和别的机器。在Git中的文件有三种状态:已提交(commited)、已修改(modified)和已计划(staged)。

已提交的意思是该文件已经提交到本地库,主意是本地库。

已修改的意思是该文件已经被修改,但是还没有计划提交

已计划,其实我也不知道应该翻译成啥。它要表达的意思是本文件已经修改,而且已经提到下一次提交的日程上来了。

这样在本地就可以划分三个区域:

工作目录 这里的所有文件是你正在编辑的文件,已修改的

已计划区域 这里的文件是被修改过的,并且安排到下一次提交的文件

Git库 这里的文件是已被提交的文件

而所有的文件也都必须经历这么三个环节。

Git使用SHA-1来校验文件或文件夹等是否被修改。实际上在Git的库里,不是使用文件名来存储,而是使用SHA-1哈希来保存。

Git基本命令

初始化本地库

这有两种方式

a、从一个零起点开始

    mkdir your project dir

   cd your project dir

   git init

这样会在<your project dir>目录中创建一个名为.git的目录,这里会保存一些重要信息。

b、已有一个Git库,复制一份

     git clone git://github.com/yuyijq/async.git <your project dir>

你可以指定或不指定<your project dir>,不指定的话这里就使用async了。

忽略某些文件

对于有些文件我们并不想将其提交到版本库。比如有些日志文件,有些编译生成的符号文件等。我们可以创建一个名为.gitignore的文件,列出一些需要被忽略的模式:

*.pdb

*.obj

这样就把后缀名为pdb的符号文件,obj的目标文件都忽略了,不被提交到版本库。

查看文件状态

在上一节我们说到Git中的文件有三种状态,我们可以使用git status命令来查看文件的状态。

查看文件差异

git status只能看到一个文件状态的汇总信息,并不能看到更详细的修改信息。我们可以使用git diff进行查看。我们可以使用git diff查看被我们修改了,但是还没有安排到下一次提交的变更,对于已经安排到下一次提交的文件,但是还没有被提交的我们可以使用git diff --cached命令。

git add

git add是一个多功能的命令

a、我们在工作目录下建一个新的文件(或目录)后,开始该文件是不被git记录的,我们需要使用git add命令让git跟踪该文件。

b、已经有一个已提交的文件,我们对其进行了修改,如果我们想在下一次提交包含该文件,那就需要使用git add命令将该文件状态变成已计划(staged)

提交

注意这里的提交跟我们以前使用的提交有着不同的概念,这里的提交仅仅是将已计划的文件提交到本地库,不是将其提交到了远程服务器。提交的命令如下:

git commit –m “this is commit comment”

有人可能想,每次要将某些文件提交,还得先将其安排成已计划的,然后再提交太麻烦了。那么你就可以使用-a开关让git自动将这些文件安排成已计划的:

git commit –a –m “this is commit comment”

 

我今天就看了这么多,就写到这里了。

你可以点击这里直接看Pro Git在线免费版