Git 基本概念
版本控制系统
版本控制系统(VCS) 是一种帮助软件开发人员合作并维护其工作完整历史记录的软件。
以下是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术语
本地代码库
每个版本控制工具都提供一个私有的工作区作为工作副本。开发人员在他们的私有工作区中进行更改,在提交后,这些更改成为仓库的一部分。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是二进制大对象(Binary Large Object)的缩写。每个文件的每个版本都由Blob表示。Blob保存文件数据,但不包含文件的任何元数据。它是一个二进制文件,在Git数据库中,它的名称是该文件的SHA1哈希值。在Git中,文件不是通过名称来寻址的,而是以内容寻址的方式。
Tree
Tree是一个表示目录的对象。它包含Blob以及其他子目录。Tree是一个二进制文件,它存储对Blob和Tree的引用,它们的名称也是该树对象的SHA1哈希值。
Commit
Commit保存了仓库的当前状态。每个Commit也由SHA1哈希值命名。可以将Commit对象视为链表的节点。每个Commit对象都有一个指向父Commit对象的指针。从给定的Commit,可以通过查看父指针来回溯并查看Commit的历史。如果一个Commit有多个父Commit,那么该Commit是通过合并两个分支创建的。
Branch
Branch用于创建另一条开发线。默认情况下,Git有一个master分支,它与Subversion中的trunk相同。通常,会创建一个分支来开发一个新功能。一旦功能完成,它会与master分支合并,然后删除该分支。每个分支都由HEAD引用,它指向分支中的最新Commit。每次进行Commit操作时,HEAD都会更新为最新的Commit。
Tag
Tag为仓库中的特定版本分配一个有意义的名称。Tag与分支非常相似,但不同之处在于Tag是不可变的。这意味着Tag是一个分支,没有人打算修改它。一旦为特定的Commit创建了Tag,即使创建了新的Commit,Tag也不会更新。通常,开发人员会为产品发布创建Tag。
Clone
Clone操作创建仓库的实例。Clone操作不仅会检出工作副本,还会镜像完整的仓库。用户可以在本地仓库中执行许多操作。只有在同步仓库实例时才涉及网络通信。
Pull
Pull操作将远程仓库实例的更改复制到本地仓库实例。Pull操作用于两个仓库实例之间的同步。这与Subversion中的更新操作相同。
Push
Push操作将本地仓库实例的更改复制到远程仓库实例。这用于将更改永久存储到Git仓库中。这与Subversion中的提交操作相同。
HEAD
HEAD是一个指针,它始终指向分支中的最新Commit。每次进行Commit操作时,HEAD都会更新为最新的Commit。分支的HEAD存储在.git/refs/heads/目录中。
[CentOS]ls -1 .git/refs/heads/
master
[CentOS] cat .git/refs/heads/master
570837e7d58fa4bccd86cb575d884502188b0c49
修订版本
修订版本表示源代码的版本。在Git中,修订版本由提交表示。这些提交通过 SHA1 安全哈希值进行标识。
网址
网址代表Git仓库的位置。Git网址被存储在配置文件中。
[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/*