`
wbj0110
  • 浏览: 1611034 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

何谓分支

    博客分类:
  • Git
Git 
阅读更多

为了理解 Git 分支的实现方式,我们需要回顾一下 Git 是如何储存数据的。或许你还记得第一章的内容,Git 保存的不是文件差异或者变化量,而只是一系列文件快照。

在 Git 中提交时,会保存一个提交(commit)对象,该对象包含一个指向暂存内容快照的指针,包含本次提交的作者等相关附属信息,包含零个或多个指向该提交对 象的父对象指针:首次提交是没有直接祖先的,普通提交有一个祖先,由两个或多个分支合并产生的提交则有多个祖先。

为直观起见,我们假设在工作目录中有三个文件,准备将它们暂存后提交。暂存操作会对每一个文件计算校验和(即第一章中提到的 SHA-1 哈希字串),然后把当前版本的文件快照保存到 Git 仓库中(Git 使用 blob 类型的对象存储这些快照),并将校验和加入暂存区域:

$ git add README test.rb LICENSE
$ git commit -m 'initial commit of my project'

当使用 git commit 新建一个提交对象前,Git 会先计算每一个子目录(本例中就是项目根目录)的校验和,然后在 Git 仓库中将这些目录保存为树(tree)对象。之后 Git 创建的提交对象,除了包含相关提交信息以外,还包含着指向这个树对象(项目根目录)的指针,如此它就可以在将来需要的时候,重现此次快照的内容了。

现在,Git 仓库中有五个对象:三个表示文件快照内容的 blob 对象;一个记录着目录树内容及其中各个文件对应 blob 对象索引的 tree 对象;以及一个包含指向 tree 对象(根目录)的索引和其他提交信息元数据的 commit 对象。概念上来说,仓库中的各个对象保存的数据和相互关系看起来如图 3-1 所示:


图 3-1. 单个提交对象在仓库中的数据结构

作些修改后再次提交,那么这次的提交对象会包含一个指向上次提交对象的指针(译注:即下图中的 parent 对象)。两次提交后,仓库历史会变成图 3-2 的样子:


图 3-2. 多个提交对象之间的链接关系

现在来谈分支。Git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。Git 会使用 master 作为分支的默认名字。在若干次提交后,你其实已经有了一个指向最后一次提交对象的 master 分支,它在每次提交的时候都会自动向前移动。


图 3-3. 分支其实就是从某个提交对象往回看的历史

那么,Git 又是如何创建一个新的分支的呢?答案很简单,创建一个新的分支指针。比如新建一个 testing 分支,可以使用 git branch 命令:

$ git branch testing

这会在当前 commit 对象上新建一个分支指针(见图 3-4)。


图 3-4. 多个分支指向提交数据的历史

那么,Git 是如何知道你当前在哪个分支上工作的呢?其实答案也很简单,它保存着一个名为 HEAD 的特别指针。请注意它和你熟知的许多其他版本控制系统(比如 Subversion 或 CVS)里的 HEAD 概念大不相同。在 Git 中,它是一个指向你正在工作中的本地分支的指针(译注:将 HEAD 想象为当前分支的别名。)。运行 git branch 命令,仅仅是建立了一个新的分支,但不会自动切换到这个分支中去,所以在这个例子中,我们依然还在 master 分支里工作(参考图 3-5)。


图 3-5. HEAD 指向当前所在的分支

要切换到其他分支,可以执行 git checkout 命令。我们现在转换到新建的 testing 分支:

$ git checkout testing

这样 HEAD 就指向了 testing 分支(见图3-6)。


图 3-6. HEAD 在你转换分支时指向新的分支

这样的实现方式会给我们带来什么好处呢?好吧,现在不妨再提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'

图 3-7 展示了提交后的结果。


图 3-7. 每次提交后 HEAD 随着分支一起向前移动

非常有趣,现在 testing 分支向前移动了一格,而 master 分支仍然指向原先 git checkout 时所在的 commit 对象。现在我们回到 master 分支看看:

$ git checkout master

图 3-8 显示了结果。


图 3-8. HEAD 在一次 checkout 之后移动到了另一个分支

这条命令做了两件事。它把 HEAD 指针移回到 master 分支,并把工作目录中的文件换成了 master 分支所指向的快照内容。也就是说,现在开始所做的改动,将始于本项目中一个较老的版本。它的主要作用是将 testing 分支里作出的修改暂时取消,这样你就可以向另一个方向进行开发。

我们作些修改后再次提交:

$ vim test.rb
$ git commit -a -m 'made other changes'

现在我们的项目提交历史产生了分叉(如图 3-9 所示),因为刚才我们创建了一个分支,转换到其中进行了一些工作,然后又回到原来的主分支进行了另外一些工作。这些改变分别孤立在不同的分支里:我们可以 在不同分支里反复切换,并在时机成熟时把它们合并到一起。而所有这些工作,仅仅需要 branchcheckout 这两条命令就可以完成。


图 3-9. 不同流向的分支历史

由于 Git 中的分支实际上仅是一个包含所指对象校验和(40 个字符长度 SHA-1 字串)的文件,所以创建和销毁一个分支就变得非常廉价。说白了,新建一个分支就是向一个文件写入 41 个字节(外加一个换行符)那么简单,当然也就很快了。

这和大多数版本控制系统形成了鲜明对比,它们管理分支大多采取备份所有项目文件到特定目录的方式,所以根据项目文件数量和大小不同,可能花费的时间 也会有相当大的差别,快则几秒,慢则数分钟。而 Git 的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。同时,因为每次提交时都记录了祖先信息(译注:即 parent 对象),将来要合并分支时,寻找恰当的合并基础(译注:即共同祖先)的工作其实已经自然而然地摆在那里了,所以实现起来非常容易。Git 鼓励开发者频繁使用分支,正是因为有着这些特性作保障。

 

http://git-scm.com/book/zh/Git-%E5%88%86%E6%94%AF-%E4%BD%95%E8%B0%93%E5%88%86%E6%94%AF

分享到:
评论

相关推荐

    Git中文学习手册 Git入门

    3 1 何谓分支 3 2 分支的新建与合并 3 3 分支的管理 3 4 利用分支进行开发的工作流程 3 5 远程分支 3 6 分支的衍合 3 7 小结 4 服务器上的 Git 4 1 协议 4 2 在服务器上部署 Git 4 3 生成 SSH 公钥 4 4 ...

    Git学习手册

    3 1 何谓分支 3 2 分支的新建与合并 3 3 分支的管理 3 4 利用分支进行开发的工作流程 3 5 远程分支 3 6 分支的衍合 3 7 小结 4 服务器上的 Git 4 1 协议 4 2 在服务器上部署 Git 4 3 生成 SSH 公钥 4 4 ...

    git使用教程详细介绍

    Git 分支的管理包括何谓分支、分支的新建与合并、分支的管理、利用分支进行开发的工作流程等内容。 四、服务器上的 Git 服务器上的 Git 涵盖了 Git 的协议、在服务器上部署 Git、生成 SSH 公钥、架设服务器、公共...

    ProGit 中文版

    - **何谓分支**:分支是Git中最强大的特性之一,允许开发者在不影响主分支的情况下进行实验性开发或维护不同的版本。 - **基本的分支与合并**:通过创建分支来进行独立开发,完成后可以将其合并回主分支。 - **分支...

    pro_git_中文版本

    4. Git分支的使用:何谓分支、基本的分支与合并、分支管理和不同的分支工作流程。特别提到远程分支的操作,以及衍合的基础和风险。 5. 服务器上的Git:介绍各种网络协议,如本地协议、SSH协议、Git协议和HTTP/S协议...

    progit中文版

    - **何谓分支**:分支是Git中非常重要的概念,它允许开发者在一个独立的线程中进行开发,不影响主分支。 - **基本的分支与合并**: - **基本分支**:使用`git branch`创建新的分支。 - **基本合并**:使用`git ...

    ProGit.pdf

    **3.1 何谓分支** - 分支是 Git 中的一个核心概念,它允许开发者在同一项目中同时进行多个开发任务。 - 分支是基于指针的,实际上是指向提交对象的可变引用。 **3.2 基本的分支与合并** - **基本分支**:创建分支...

    progit手册

    **何谓分支**:分支是Git中的核心概念之一,允许开发者在一个独立的环境中进行开发而不影响主干。 **基本的分支与合并**: - **基本分支**:创建、切换和删除分支。 - **基本合并**:将一个分支合并到另一个分支。...

    pro git 完整、完美中文版...

    **3.1 何谓分支** - **概念**: 分支是Git中用于隔离开发工作的功能。 - **优势**: 支持非线性开发模式,便于实验新功能而不影响主分支。 **3.2 基本的分支与合并** - **创建分支**: `git branch <branchname>` - ...

    Pro Git(中文版).pdf

    **3.1 何谓分支** - **分支概念**:Git中的分支实际上是简单的指针,指向特定提交。 - **分支优势**:便于多人协作、实验性开发和维护不同版本。 **3.2 分支的新建与合并** - **新建与切换分支**:使用`git ...

    git使用操作中文手册

    **3.1 何谓分支** 介绍分支的基本概念和作用。 **3.2 基本的分支与合并** - **3.2.1 基本分支** 创建和切换分支的基本操作。 - **3.2.2 基本合并** 如何合并不同分支的变更。 - **3.2.3 冲突的合并** 解决...

    《Pro Git》,简体中文,2011-12-16更新

    - **内容节选**:“目录...3 Git分支...3.1 何谓分支...3.2 分支的新建与合并...3.3 分支的管理...3.4 利用分支进行开发的工作流程...3.5 远程分支...3.6 分支的衍合...3.7 小结” **知识点详解:** 1. **何谓分支...

Global site tag (gtag.js) - Google Analytics