1、Git简介
Git简单的来说,是一种分布式的版本管理工具,其具有以下优点:
1、速度快
2、简单的设计
3、对非线性开发模式的强力支持(可以同时允许几千个分支同时进行开发和切换)
4、完全分布式(防止集中式版本管理工具所出现的单点故障问题)
Linus花了两个星期用C语言写出了一套Git的原型代码,在Linux数千开发者的努力与完善之下,形成了目前的Git这一套版本管理工具。
2、如何分布式
Git是分布式的,并没有服务端跟客户端之分,所谓的服务端安装的其实也是Git。
Git支持四种协议,file,ssh,git,http。ssh是使用较多的,下面使用ssh搭建一个免密码登录的服务端。
Git与SVN是目前大多数企业所选择的版本管理工具,两者也代表了版本管理的两个主要的设计模式和理念。SVN是集中式版本管理系统的代表,中央代码库存储着所有代码提交者的代码,而每个项目的参与者只负责代码的提交,中央代码库则保存着完整版的所有代码。但这也造成了一系列的问题:
1、中央代码库单点故障所带来的项目风险,并且一旦发生,代码则无法恢复。
2、提交代码时由于网络带宽问题所带来时间上的延迟,影响开发人员的工作效率。
3、对于中央代码库而言,其服务器压力过大,数据库容量暴增。
Git则是建立在本地库基础之上的分布式版本管理工具,最终可以使得任何代码的提交者都可以成为“中央代码库”。Git的根本思想和基本工作原理主要是在本地复制一个“代码库”,每次提交的代码均是推送到本地代码库中,节约了由于网络带宽所带来的限制,不至于出现提交5MB的代码而需等待20分钟的情况。另一方面,一旦中央代码库的服务器出现“崩溃”,那么任何“本地库”均可以还原中央代码库。
Linus是如何通过Git来实现这个目标的呢?
Git的核心思想在于,每次代码版本的更迭和变化,Git都会记录数据文件的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异变化,这类系统每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容。
Git并不保存这些前后变化的差异数据。实际上,Git更像是把变化的文件快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件一一作快照,然后保存一个指向这次快照的索引。为提高性能,若文件没有变化,Git不会再次保存,而只是对上一次保存的快照作一链接。
总的来说,Git是一个存储着整个代码快照或者代码快照链接的小型文件系统,所以在每次代码修改之后都能够保持整个代码库的“风貌”,而不是像其他版本管理系统一样,只记录修改的文件和具体的修改内容。要复原整个代码库的话,还需借助“原始材料”。
3、Git的基本设计理念
3.1 近乎所有操作都是本地执行
在Git中的绝大多数操作都只需要访问本地文件和资源,不用联网。如查看提交记录、修改内容信息、版本更新、建立分支、切换分支等等。因为Git在本地磁盘上就保存着所有当前项目的历史更新,所以处理起来速度飞快。例如,你如果想要查看现在的代码和一个月前的版本有何差异,那么Git会取出一个月前的代码快照和此时的代码做一次对比,而不用请求远程服务器来做这件事,或者是把老版本的代码拉到本地作比较。
如果是SVN的话,那么你必须在有网络的情况下才能够提交代码,而此时你现在在火车上,那么你无法做任何事情,然而如果你正在使用Git,那么你可以随时的提交已经测试通过的代码模块,等到有网络的时候再上传到远程仓库即可。
3.2 时刻保持数据的完整性
Git通过对管理起来的每个文件计算Hash值,从而得到每个数据的唯一标识和索引。在Git中也全靠这些Hash值来唯一识别文件,而不是文件名。该“指纹”Hash值是一个由40位16进制字符串组成的,任何文件的损坏或者数据缺失都会被Git通过Hash值校验轻松识别到。
3.3 Git的三个文件区域
对任何一被Git管理的文件而言,其只具有三种可能的状态,分别是“已提交”,“已修改”和“已暂存”。已提交表示该文件已经被安全保存在本地数据库中了;已修改表示此文件修改了,但没有提交保存;已暂存表示已经把修改后的文件提交到了暂存区域但还没有提交。
4、Git的精髓——分支
分支是Git的核心所在,犹如操作系统的内核对于操作系统而言至关重要,也是Git能够支持上千个分支并发处理的关键所在。为了要理解Git分支的本质思想,我们需要结合Git的保存数据的方式来仔细讲解,Git保存的不是文件差异或者变化量,而只是一系列文件快照,理解这点很关键。
在Git提交时,会保存一个提交(commit)对象,这个commit对象包含着以下内容:
1、指向暂存内容快照的指针。
2、本次提交的作者等相关附属信息。
3、零个或多个指向该提交对象的父对象指针(普通提交只有一个父亲,如果从多个分支合并而来则有多个父亲)。
讲完这些之后,我们再回过头来谈Git的分支。Git中的分支,其实本质上仅仅是指向commit提交对象的可变指针,它在每次提交的时候,都会自动向前移动。新建一个新的分支只是在当前commit对象上再创建一个新的可变指针;Git会保存一个名为HEAD的特别指针,指向分支的可变指针,HEAD表示当前分支。
5、分支合并,变基
分支合并不是简单地把分支指针右移,而是对三方合并后的结果重新做一个新的快照,并自动创建一个指向它的提交对象。这个提交对象。这个提交对象比较特殊,它有两个祖先。在分支合并的时候,可能会导致冲突的发生,需要人工解决冲突才能够重新提交代码。
分支变基指的是回到两个分支最近的共同祖先,根据当前分支后续的历次提交对象,生成一系列的文件补丁,然后在基底分支的基础之上,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象。切勿对已发布版本的代码进行变基操作。