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 术语

本地存储库

每个 VCS 工具都提供一个私有工作场所作为工作副本。 开发人员在他们的私人工作场所进行更改,提交后,这些更改成为存储库的一部分。 Git 通过为他们提供整个存储库的私有副本更进一步。 用户可以使用此存储库执行许多操作,例如添加文件、删除文件、重命名文件、移动文件、提交更改等等。

工作目录和暂存区或索引

工作目录是签出文件的地方。 在其他 CVCS 中,开发人员通常会进行修改并将其更改直接提交到存储库。 但是 Git 使用了不同的策略。 Git 不会跟踪每个修改过的文件。 每当您提交操作时,Git 都会查找暂存区域中存在的文件。 只有那些存在于暂存区的文件才会被考虑提交,而不是所有修改过的文件。

让我们看看 Git 的基本工作流程。

步骤 1 − 您从工作目录修改文件。

步骤 2 − 您将这些文件添加到暂存区。

步骤 3 − 您执行从暂存区移动文件的提交操作。 推送操作后,它将更改永久存储到 Git 存储库。

Git Tutorial

假设您修改了两个文件,即"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”

Blobs

Blob 代表 Binary Large Object。 文件的每个版本都由 blob 表示。 Blob 保存文件数据,但不包含有关文件的任何元数据。 它是一个二进制文件,在 Git 数据库中,它被命名为该文件的 SHA1 哈希。 在 Git 中,文件不是按名称寻址的。 一切都是以内容为导向的。

Trees

Tree 是一个对象,代表一个目录。 它包含 blob 以及其他子目录。 树是存储对 blob 和树的引用的二进制文件,这些引用也称为树对象的 SHA1 哈希。

Commits

Commit 保存存储库的当前状态。 提交也由 SHA1 哈希命名。 您可以将提交对象视为链表的一个节点。 每个提交对象都有一个指向父提交对象的指针。 从给定的提交中,您可以通过查看父指针来查看提交的历史记录。 如果一个提交有多个父提交,则该特定提交是通过合并两个分支创建的。

Branches

分支用于创建另一条开发线。 默认情况下,Git 有一个 master 分支,与 Subversion 中的 trunk 相同。 通常,会创建一个分支来处理新功能。 一旦功能完成,它就会与主分支合并回来,我们删除该分支。 每个分支都被 HEAD 引用,它指向分支中的最新提交。 每当您进行提交时,HEAD 都会使用最新的提交进行更新。

Tags

标签为存储库中的特定版本分配一个有意义的名称。 标签与分支非常相似,但不同之处在于标签是不可变的。 这意味着,标签是一个分支,没有人打算修改它。 一旦为特定的提交创建了标签,即使您创建了新的提交,它也不会被更新。 通常,开发人员会为产品发布创建标签。

Clone

克隆操作创建存储库的实例。 克隆操作不仅会检出工作副本,还会镜像完整的存储库。 用户可以使用此本地存储库执行许多操作。 唯一涉及网络的时间是在同步存储库实例时。

Pull

拉取操作将更改从远程存储库实例复制到本地存储库实例。 拉取操作用于两个存储库实例之间的同步。 这与 Subversion 中的更新操作相同。

Push

推送操作将更改从本地存储库实例复制到远程存储库实例。 这用于将更改永久存储到 Git 存储库中。 这与 Subversion 中的提交操作相同。

HEAD

HEAD 是一个指针,它始终指向分支中的最新提交。 每当您进行提交时,HEAD 都会使用最新的提交进行更新。 分支的头部存储在 .git/refs/heads/ 目录中。

[CentOS]$ ls -1 .git/refs/heads/
master

[CentOS]$ cat .git/refs/heads/master
570837e7d58fa4bccd86cb575d884502188b0c49

Revision

Revision 代表源代码的版本。 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/*