Git – 基本概念
版本控制系统
版本控制系统(VCS) 是一种帮助软件开发人员一起工作并保持其工作的完整历史的软件。
现在,创建模型,如下所示 −
- 允许开发人员同时工作。
- 不允许相互覆盖对方的修改。
- 维护每个版本的历史。
以下是VCS的类型
- 集中式版本控制系统(CVCS)。
- 分布式/分散式版本控制系统(DVCS)。
在本章中,我们将只关注分布式版本控制系统,特别是Git。Git 属于分布式版本控制系统。
分布式版本控制系统
集中式版本控制系统(CVCS)使用一个中央服务器来存储所有文件,并实现团队协作。但CVCS的主要缺点是其单点故障,即中央服务器的故障。不幸的是,如果中央服务器瘫痪一小时,那么在这一小时内,没有人可以进行协作。甚至在最坏的情况下,如果中央服务器的磁盘被损坏,而没有采取适当的备份,那么你将失去整个项目的历史。在这里,分布式版本控制系统(DVCS)进入了画面。
DVCS客户端不仅可以检查出目录的最新快照,还可以完全镜像版本库。如果服务器发生故障,那么任何客户端的版本库都可以被复制到服务器上进行恢复。每次签出都是对仓库的完整备份。Git 不依赖于中央服务器,这就是为什么你可以在离线时执行许多操作。你可以在离线状态下提交修改,创建分支,查看日志,以及执行其他操作。你只需要网络连接来发布你的修改和获取最新的修改。
Git的优势
免费和开放源代码
Git 是在 GPL 的开放源代码许可下发布的。它可以在互联网上免费使用。你可以使用Git来管理财产项目而不需要支付一分钱。由于它是一个开放源码,你可以下载其源代码,也可以根据你的要求进行修改。
快速和小型
由于大部分操作都是在本地进行的,它在速度方面给人以巨大的好处。Git 不依赖于中央服务器;这就是为什么不需要为每一个操作与远程服务器进行交互。Git 的核心部分是用 C 语言编写的,这就避免了与其他高级语言相关的运行时间开销。虽然Git镜像了整个仓库,但客户端的数据大小却很小。这说明了Git在客户端压缩和存储数据的效率。
隐式备份
当数据有多个副本时,丢失数据的几率非常小。存在于任何客户端的数据都是仓库的镜像,因此可以在崩溃或磁盘损坏的情况下使用。
安全性
Git 使用一种常见的加密哈希函数,即安全哈希函数(SHA1),来命名和识别其数据库中的对象。每个文件和提交都会被校验和,并在签出时通过校验和进行检索。这意味着,如果不了解Git,就不可能改变文件、日期、提交信息以及Git数据库中的任何其他数据。
不需要强大的硬件
在CVCS的情况下,中央服务器需要足够强大,以满足整个团队的要求。对于小团队来说,这不是一个问题,但随着团队规模的扩大,服务器的硬件限制会成为性能瓶颈。在DVCS的情况下,开发人员不与服务器互动,除非他们需要推送或拉动变化。所有繁重的工作都发生在客户端,所以服务器的硬件确实可以非常简单。
分支更容易
CVCS使用廉价的复制机制,如果我们创建一个新的分支,它就会把所有的代码复制到新的分支上,所以很耗时,效率也不高。另外,CVCS中分支的删除和合并也很复杂,很费时间。但用Git管理分支却非常简单。创建、删除和合并分支只需要几秒钟。
DVCS的术语
本地仓库
每个VCS工具都提供一个私有工作区作为工作副本。开发者在他们的私有工作区进行修改,提交之后,这些修改就成为仓库的一部分。Git更进一步,为他们提供了整个仓库的私有副本。用户可以对这个仓库进行许多操作,比如添加文件、删除文件、重命名文件、移动文件、提交修改等等。
工作目录和暂存区或索引
工作目录是文件被检出的地方。在其他的CVCS中,开发者一般都会进行修改并直接提交到仓库中。但Git采用了不同的策略。Git 并不跟踪每一个修改过的文件。每当你做提交操作时,Git 会寻找存在于暂存区域的文件。只有那些存在于暂存区域的文件才会被考虑提交,而不是所有的修改文件。
让我们来看看 Git 的基本工作流程。
第1步 - 你在工作目录中修改了一个文件。
第2步 - 你把这些文件添加到暂存区。
第3步 - 执行提交操作,将文件从暂存区域移出。在推送操作之后,它将修改内容永久地存储到 Git 仓库中。
假设你修改了两个文件,即 “sort.c “和 “search.c”,你想为每个操作进行两次不同的提交。你可以在暂存区添加一个文件并做提交。第一次提交后,对另一个文件重复同样的程序。
# First commit
[bash]git add sort.c
# adds file to the staging area
[bash] git commit –m “Added sort operation”
# Second commit
[bash]git add search.c
# adds file to the staging area
[bash] git commit –m “Added search operation”
Blob
Blob是 B inary L arge Ob ject的缩写。文件的每个版本都由blob来表示。Blob包含文件数据,但不包含任何关于文件的元数据。它是一个二进制文件,在Git数据库中,它被命名为该文件的SHA1哈希值。在Git中,文件不是用名字来命名的。所有文件都是以内容命名的。
tree
树是一个对象,它代表一个目录。它可以容纳Blobs和其他子目录。一个树是一个二进制文件,它存储了对Blobs和树的引用,这些引用也被命名为树对象的 SHA1 哈希值。
提交(Commits)
提交保存了版本库的当前状态。一个提交也是用 SHA1 哈希值命名的。你可以把一个提交对象看作是链表的一个节点。每个提交对象都有一个指向父提交对象的指针。从一个给定的提交对象开始,你可以通过查看父提交对象的指针来回溯,以查看该提交的历史。如果一个提交有多个父提交,那么该提交是由两个分支合并而成的。
分支
分支是用来创建另一条开发线的。默认情况下,Git 有一个主分支,与 Subversion 中的 trunk 相同。通常情况下,创建一个分支是为了开发一个新特性。一旦功能完成,它就会被合并到主分支中,然后我们就会删除这个分支。每个分支都被 HEAD 所引用,HEAD 指向该分支的最新提交。每当你进行提交时,HEAD就会以最新的提交来更新。
标签
标签为版本库中的特定版本分配一个有意义的名字。标签与分支非常相似,但不同的是,标签是不可更改的。这意味着,标签是一个分支,没有人打算去修改它。一旦为某个特定的提交创建了标签,即使你创建了一个新的提交,它也不会被更新。通常情况下,开发者为产品发布创建标签。
克隆
克隆操作创建版本库的实例。克隆操作不仅可以检查出工作副本,还可以镜像完整的版本库。用户可以用这个本地版本库执行许多操作。唯一涉及网络的时候是版本库实例被同步的时候。
pull
拉操作将远程版本库实例的修改复制到本地版本库。拉操作被用于两个版本库实例之间的同步。这与Subversion中的更新操作相同。
push
推送操作将本地版本库实例的修改复制到远程版本库。这被用来将更改永久地存储到 Git 仓库中。这与 Subversion 中的提交操作相同。
HEAD
HEAD 是一个指针,它总是指向分支中的最新提交。每当你提交的时候,HEAD就会被更新为最新的提交。各个分支的 HEAD 都存储在 .git/refs/heads/ 目录中。
[CentOS]ls -1 .git/refs/heads/
master
[CentOS] cat .git/refs/heads/master
570837e7d58fa4bccd86cb575d884502188b0c49
修订版
修订版代表了源代码的版本。在Git中,修订是由提交表示的。这些提交是由 SHA1 安全哈希值来识别的。
URL
URL 代表 Git 仓库的位置。Git的URL存储在配置文件中。
[tom@CentOS tom_repo]pwd
/home/tom/tom_repo
[tom@CentOS tom_repo] cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = gituser@git.server.com:project.git
fetch = +refs/heads/*:refs/remotes/origin/*