一、GIT的前世今生
GIT是VCS(Version Control System,版本控制系统)中的一代新秀,由于其开源性、分布式,收到广大的开发者(尤其是开源开发者)的喜爱。
在VCS发明前,修改文件是件很麻烦的事,比如写毕业论文,这里修改了一下,那里修改了一下,之前删除掉得段落,又想用怎么办?只有另存为别的文件名。到最后,你完全想不起来自己到底改了几个地方,原来的论文到底长什么样子了。
这个问题对广大程序猿更是头疼,由于程序是迭代开发的,而且是多人协作。我们在开发中,希望知道一个类是谁写的、为什么要这样写、经过了些什么修改,才能帮助我们正确的开发,否则,改错了,问题就大了。
1. SCCS
1972年的时候,贝尔实验室的程序员们快被这个问题烦死了,他们写出了史上第一个版本控制系统SCCS(Source Code Control System,源代码控制系统)。SCCS 好用是好用,但有几个问题。首先,当你对文件作出多次、大量修改后,它的速度明显变慢了——对啊,它要从原文件开始依次应用修改嘛。然后,它内置在 AT&T 生产的系统中,不能跨平台啊,广大 Windows 用户很不开心啊。
2. RCS
Water 是一个教计算机的大学教授,学校里的电脑上有 AT&T 的系统,可是到家就没辙了,老爷子很不爽啊,这叫人家在家怎么刻苦呢?1982年,他一气之下,写出了改变历史的第二个被广泛应用的 VCS,取名 Revision Control System,也就是大家熟知的 RCS。
3. CVS
RCS已经解决了单个文件的问题,但是项目是复杂的、多个文件相关联的,又产生了新的问题,CVS应时而生。CVS是革命性的成果,它不但支持了对整个项目进行监控,并且首次提出了仓库(Repository)的概念。但还是有它的局限性,它监控的对象是文件,而不是目录:在项目目录下再创建目录,这个子目录里面的文件并不会被监控;添加一个新文件,这个新文件也不会被监控。
4. SVN
到了21世纪,一个跨时代的 VCS 出现了—— Subversion。它不但支持监控整个目录,而且首次支持了监控非文本文件。这两个特性使它在 2001 年在全球范围内取代了 CVS,并且一直流行到今天。没错,上一份工作的公司用的就是SVN,也是我接触到的第一个版本控制系统,又一台服务器作主机,从主机检出代码,修改,然后提交到主机同一管理。
同时代还有另一个 VCS —— BitKeeper,也很牛,他和SVN不同的是:1、分布式管理,2、商业软件。在当初可是比SVN还出名,因为大名鼎鼎的 Linux Kernel 就存放在其免费的社区版本上!
5. GIT
2005年4月,BitMover(拥有 BitKeeper 的那家公司)突然宣布,停止 BitKeeper 的社区版本,你们这群不想交钱就用我们软件人都玩蛋去!好嘛,改变了人类历史的 Linux 就这样无家可归了。
Linux 之父 Linus 看着自己的儿子被别人赶出了家门,愤怒值立刻飙升。他环绕四周看了看,觉得 SVN 什么的简直是屎,决不能允许亲儿子流落至此。两斤啤酒下肚,他冲到电脑前三天三夜不眠不休,于是GIT诞生。好吧,这里有点夸张,没有这么快。
Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。而之前的老牌代码托管商如SourceForge逐渐衰败。
二、集中式与分布式版本控制的区别
从上面可以看到,现代VCS分为集中式管理、分布式管理。
1.集中式管理(代表:SVN)
版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
缺点:
- 服务器出现问题会对整个系统造成影响
如果主机出现故障,那在这段时间之内,谁也不能提交代码、更新代码。 - 必须要联网才能工作
如果在家中,连接不到服务器,你是没办法提交代码的,只能持续进行开发,而在这个过程中的问题,很难把控。 - 由于本地没有代码库,操作不够方便
比如一个重要的bug要立即放下手里的工作,需要创建个分支进行bug修复开发,SVN需要去申请创建分支的权限,开发完后合并分支也很痛苦
优点:
- 集中式管理,权限好控制
可以配置各个路劲、各个文件的权限,有的公司的文件安全等级高的,选择集中式管理吧 - 入门简单
好吧,相对于分布式管理,这确实也是一个优点
2.分布式管理(代表:GIT)
分布式版本控制 (DVCS) 是一种不需要中心服务器的管理文件版本的方法,但是它也可以使用中心服务器。更改可以被合并到 DVCS 的任何其他用户的系统中,因此可以实现非常灵活的工作流。
优点:
- 由于没有中心服务器,安全性高。
各个每个clone都是完整的库,哪怕多个人的电脑坏了,只要有个版本库还存在,也不会丢失代码; - 不需要联网即可工作。
在本地操作自己的代码库,完全不受网络影响。只是在需要与别的库同步的时候才需要网络。 - 它比集中的版本控制更灵活,因为它除了支持传统的(集中式)工作流,还支持其他各种工作流;
尤其是分支管理,实在是太爽了:自由创建分支、合并快,加上stash功能,随时可以处理突然加进来的工作。
缺点:
- 由于是分布式的,每个人都有完整的备份,权限控制就不好搞了。当然,它就是为了开源项目而生的,权限控制不是它的风格。
- 上手还是比较有难度的。因为开放性高,库在本地,可以各种操作。我丢过一次代码,第一次与别人合并代码搞了好久(之前用SVN习惯了,思维没改变过来)
三、工作区、暂存区、版本区的区别
由于之前用的是SVN,集中式的系统,和GIT分布式的有很大差别,就自己的理解来说说工作区、暂存区、版本区的却别。
1、工作区
就是我们进行文件操的区域,可以看到的一个个文件,就处于工作区。
我们在工作区修改、添加、删除文件,这些操作此时是未被GIT跟踪的,如果在这个阶段数据丢失了,是找不回来的!
所以,在工作区内的文件要不定期的添加到缓存区。
2、缓存区
工作区的文件可以添加到这个区域,一旦添加到这个区域,就被GIT跟踪了,那就担心数据丢失了。
通过 git add 将修改后的文件添加到缓存区。
需要注意的是,git跟踪的是修改,不是文件,举例说明:
- 在工作区创建文件 a.txt,写入数据 hello world!
- git status,看到提示:
$ git status
On branch master
Untracked files:
(use "git add ..." to include in what will be committed)
a.txt
nothing added to commit but untracked files present (use "git add" to track)
此时文件未被跟踪,还在工作区
- git add a.txt,添加到缓存区
- git status:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: a.txt
此时,a.txt添加到了缓存区,已被跟踪
- 此时,再次修改a.txt,添加新行 i like git!
- git status:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: a.txt
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: a.txt
此时看到a.txt被修改,还在工作区!
为什么呢?a.txt我们之前已经加到缓存区了呀?
这是因为git跟踪的是修改,不是文件。
这样来理解:第一次针对a.txt的修改已经添加到缓存区了,第二次针对a.txt的修改还在工作区。
所以记得每次修改了文件,一定要再次 git add 文件名,然后再提交。
3、版本区
也叫版本库,存储所有版本的区域,缓存区的修改数据,提交后将存储到此区域。
继续上面的操作:
$ git commit -m 'add file: a.txt'
[master c5e0e58] add file: a.txt
1 file changed, 3 insertions(+)
create mode 100644 a.txt
通过命令 git commit 将所有加入缓存区的数据一次性提交到版本区。
注意参数 -m “”,是添加提交的备注信息,备注好这次提交作了哪些修改,对我们以后跟踪修改、别的伙伴理解我们的操作很有帮助。
数据进入版本区,就相当于是归档了,以后想查找文件里每一次的修改变更,都能查找到了。