Git 简明教程
Git - Basic Concepts
Version Control System
Version Control System (VCS) 是一款软件,用于帮助软件开发人员共同协作并维护其工作完整记录。
以下列出了 VCS 的功能 −
-
允许开发人员同时工作。
-
不允许相互覆盖更改。
-
维护每个版本的记录。
以下为 VCS 的类型 −
-
集中式版本控制系统 (CVCS)。
-
分布式/分散式版本控制系统 (DVCS)。
在本章中,我们将仅集中讨论分布式版本控制系统,特别是 Git。Git 属于分布式版本控制系统。
Distributed Version Control System
集中式版本控制系统 (CVCS) 使用中央服务器存储所有文件,并实现团队协作。但 CVCS 的主要缺点在于它的单点故障,即中央服务器发生故障。不幸的是,如果中央服务器中断一个小时,那么在这个小时内,根本没有人可以协作。在最坏的情况下,如果中央服务器的磁盘损坏且未进行适当的备份,那么您将丢失项目的整个历史记录。此处,分布式版本控制系统 (DVCS) 发挥了作用。
DVCS 客户端不仅可以签出目录的最新快照,还完全镜像仓库。如果服务器发生故障,那么可以从任何客户端将仓库复制回服务器,以便恢复它。每次签出都是仓库的完整备份。Git 不依赖于中央服务器,这就是为什么您在离线时可以执行许多操作的原因。您可以在离线时提交更改、创建分支、查看日志并执行其他操作。您仅需要网络连接即可发布更改并获取最新更改。
Advantages of Git
Free and open source
Git 在 GPL 开源许可下发布。它可免费在网上获得。您无需支付一分钱即可使用 Git 来管理房地产项目。由于它是开源的,您可以下载其源代码,并根据您的要求执行更改。
Fast and small
由于大多数操作都将在本地执行,因此它在速度方面具有巨大的优势。Git 不依赖于中央服务器;这就是为什么无需为每个操作与远程服务器进行交互的原因。Git 的核心部分是用 C 语言编写的,这避免了与其他高级语言相关的运行时开销。尽管 Git 镜像整个仓库,但在客户端上的数据大小却很小。这说明了 Git 在客户端压缩和存储数据方面的效率。
Security
Git 使用一种称为安全散列函数 (SHA1) 的常见加密散列函数,在数据库中对对象命名和标识。每次签出时,都会对每个文件和提交进行校验和,并通过其校验和进行检索。这意味着,在不知道 Git 的情况下,无法从 Git 数据库更改文件、日期和提交消息以及任何其他数据。
DVCS Terminologies
Local Repository
每个 VCS 工具都提供一个私有工作区作为工作副本。开发人员在其私有工作区中进行更改,而在提交后,这些更改将成为仓库的一部分。Git 将其更进一步,为他们提供了整个仓库的私有副本。用户可以使用此仓库执行许多操作,例如添加文件、移除文件、重命名文件、移动文件、提交更改等许多操作。
Working Directory and Staging Area or Index
工作目录是签出文件的位置。在其他 CVCS 中,开发人员通常进行修改并直接提交其更改到仓库。但是 Git 使用了一种不同的策略。Git 不会跟踪每个修改过的文件。每当您执行提交操作时,Git 都会查找暂存区中存在的文件。只有暂存区中存在的文件才会提交,而并非所有修改过的文件。
让我们看看 Git 的基本工作流。
Step 1 − 你修改了工作目录中的一个文件。
Step 2 − 你将这些文件添加到暂存区。
Step 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”
Blobs
Blob 表示 二进制 大 对象。文件的每个版本都由 blob 表示。blob 保存着文件数据,但不包含任何关于该文件元数据。它是一个二进制文件,在 Git 数据库中,它被命名为该文件 SHA1 哈希值。在 Git 中,文件并非通过名称来寻址。每种文件都是根据其内容进行寻址的。
Commits
Commit 存储着存储库的当前状态。commit 也被 SHA1 哈希值命名。你可以将 commit 对象视作一个链表的节点。每个 commit 对象都有一个父级 commit 对象指针。从给定的 commit 开始,你可以通过查看父级指针来追溯历史提交。如果一个 commit 有多个父级 commit,那么该特定 commit 是通过合并两个分支创建的。
Branches
Branch 用来创建另一个开发线路。默认情况下,Git 有一个 master 分支,它与 Subversion 的 trunk 相同。一般来说,一个分支被创建来开发一个新功能。一旦该功能完成,它就会被合并回 master 分支,然后我们删除这个分支。每个分支都通过 HEAD 引用,该引用指向分支中的最新 commit。每当你进行一次 commit,HEAD 就会被更新为最新 commit。
Tags
Tag 使用一个有意义的名称为存储库中的一个特定版本命名。Tag 与分支非常相似,但不同之处在于 tag 是不可变的。这意味着,tag 是一个分支,没有人打算对其进行修改。一旦为特定 commit 创建了一个 tag,即使你创建了一个新的 commit,它也不会被更新。一般来说,开发人员会在产品发布时创建 tag。
HEAD
HEAD 是一个指针,它总是指向分支中的最新 commit。每当你进行一次 commit,HEAD 就会被更新为最新 commit。分支的头部存储在 .git/refs/heads/ 目录中。
[CentOS]$ ls -1 .git/refs/heads/
master
[CentOS]$ cat .git/refs/heads/master
570837e7d58fa4bccd86cb575d884502188b0c49
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/*