`
guibin
  • 浏览: 366038 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Git基础对象模型介绍

    博客分类:
  • GIT
阅读更多
Git基础对象模型介绍
guibin.beijing@gmail.com

本文翻译自http://book.git-scm.com/1_the_git_object_model.html ,但不是全文翻译,仅供学习参考,不贴切之处敬请指正。

Git是什么?
Git是一个快速、分布式的版本控制系统

Git的对象模型
什么是SHA?
用来代表项目历史的所有信息都存储在一个文件中,这个文件名由40个字符构成,表示所谓的“对象“,看起来象:
引用
49b1775c245cbf030f52ce0c50d3758617e02395

在Git中,象这样的40个字符组成的字符串随处可见,它是由对象的内容做SHA1哈希计算得到的。所谓的SHA1哈希是一个加密的哈希函数。这样做的意义是实际上不可能找到两个不同的对象拥有相同的SHA1值(对象名)。这样做有一系列的好处,比如:
  • Git可以快速的仅仅通过对象名称决定两个对象是否相同
  • 由于对象名称在每一个库(repository)中都由相同的方式计算得到,相同的内容存储到不同的库中将总被存储到相同的名称下
  • Git可以在读取对象时通过检查对象的内容SHA1之后是否是相同的名字来检测错误(这样做的原因是由于相同的内容经过SHA1计算之后总是具有相同的SHA1值)

什么是对象?
每个对象有三个属性:类型、尺寸和内容。
尺寸就是对象的大小,内容基于对象的类型。在Git中有四种类型,分别是"blob", "tree", "commit", and "tag"。
  • blob:用来存储文件数据,就是一个通常的文件。
  • tree:看起来象一个目录结构,它引用了一串其他的tree或者blob(就像文件和子目录一样)。
  • commit:指向一个单独的tree,标志着一个项目在一个特定的时间点看起来是什么样子。
  • 它包含了那一时间点的元信息,比如时间戳、作者、自从上次提交以来所做的改变、指向前一次提交的引用,等等。
  • tag:是用特定的方法标识特定的提交。它通常用来标记特定的commit作为特定的release,或者这条主线上的其他的什么东西。
几乎所有的Git都建立在管理操纵这些简单的结构之上,即它是建立在机器文件系统之上的一种自己的小型文件系统。
  • Blob对象(Blob Object)
  • Blob对象通常存储文件的内容。可以使用命令git show来查看人和blob对象的内容。比如:
    引用
    $ git show ced3dd435d0468
    commit ced3dd435d04684ad44232709bd35841240364c6
    Author: Guibin Zhang <guibin.beijing@gmail.com>
    Date:   Wed Apr 20 17:31:31 2011 +0800

        Fix publish with null properties

    diff --git a/libs/lib.service.securities/src/main/scala/com/aiotrade/lib/service/securities/cndbf/LevelIIDataPublisher.scala
    index 535bc85..2f1650e 100644
    --- a/libs/lib.service.securities/src/main/scala/com/aiotrade/lib/service/securities/cndbf/LevelIIDataPublisher.scala
    +++ b/libs/lib.service.securities/src/main/scala/com/aiotrade/lib/service/securities/cndbf/LevelIIDataPublisher.scala
    @@ -166,7 +166,8 @@ object LevelIIDataPublisher extends Reactor{

               if(rountingKey.isDefined && secId.isDefined) {
                 val topic = rountingKey.get + secId.get + ".SZ"
    -            publisher.publish(exchange, topic , null, recordObjs)
    +            publisher.publish(exchange, topic , props, recordObjs)


    blob对象实际上就是一块二进制数据。它不会引用任何其他东西,也没有人和其他属性,甚至都没有文件名
    既然blob对象完全由其数据决定,如果两个文件在同一个目录树下(或者在多个不同版本的库中),那么他们将会共享相同的blob对象。blob对象完全独立于它在目录树中的位置,即便是对文件重命名也不会改变与此文件相关联的blob对象的内容。
  • Tree对象(Tree Object)
  • Tree对象比较简单,它有很多指针,指向其他blob和tree,它代表目录或者子目录的内容。
    git tree命令能够用来检查tree对象的内容,或者使用git ls-tree可以查看更多细节。如下面的例子
    引用
    $ git ls-tree 49b1775c245cbf030f52ce0c50d3758617e02395
    040000 tree 7e814915c9880cb367895118333f2cd4e600855b application
    040000 tree 561d4f6709e0b27943d5f0d650f9986e74673e69 branding
    100644 blob af0ae6a9fc24e6978287d47eda2727c1c664f524 pom.xml

    就像你所看到的,tree对象包含一系列入口,每个入口保护模式(如040000,100644),对象类型(tree,blob),SHA1名称(7e814915..., 561d4f67..., af0ae6a9fc...),和名字(application, branding, pom.xml)。这些内容都是tree对象49b1775c245cbf030f52ce0c50d3758617e02395...的内容,内容列出的顺序按照名称排序。这些内容就是一个单独文件夹的内容。
    能够被tree对象引用的对象可以是:blob对象-代表文件的内容,另外的tree对象-代表子目录的内容。既然tree对象和blob对象和其他对象一样,都是由其内容的SHA1 hash值决定,因此两个tree对象当且仅当他们的内容(递归的包含其子目录的内容)相同时才具有相同的SHA1值。这个特性使得git能够快速决定两个相关的tree对象的差异,因为在判断两个tree是否相同时可以忽略tree对象下面的相同名字的对象。
    注意,具有644和755权限的文件,git实际上只对可执行权限位感兴趣。
  • Commit对象(Commit Object)
  • Commit对象链接一个Tree的物理状态和其描述。这个描述描述了我们如何提交到这个commit,怎么提交的,相当于一些注释。
    你可以用在 git show 命令和 git log 命令中使用 --pretty=raw 选项查看你所感兴趣的提交(commit)。
    引用
    $ git show -s --pretty=raw c1e78911e06
    commit c1e78911e066983c797129b196f60cef256c3a3a
    tree 1afa3f0f14c1fffed0fbf3cc05507034c61cfeb4
    parent ffbeb1730537cc139bee4358010afc9953cb8615
    author Guibin Zhang <guibin.beijing@gmail.com> 1303277354 +0800
    committer Guibin Zhang <guibin.beijing@gmail.com> 1303277354 +0800

        Fix publish to wrong topic bug

    正如你所见到的,一个commit由以下几个元素组成:
    1. Tree。即Tree对象的SHA1名字,代表在特定时间点某个目录的内容。
    2. Parent。在此次提交之前的一个或几个commit的名字。上面的例子中,只有一个parent,但是Merge commit可能就有多个parent。比如
    引用
    $ git show -s  --pretty=raw 49b1775c24
    commit 49b1775c245cbf030f52ce0c50d3758617e02395
    tree 89de7605c4ec6677b3960acd7621cdb70371362b
    parent 10096820c833d42b53ed40886bb91e37f7e2607f
    parent b0cbbf20457bc7a755391b93c0f6278cb0b47b2e

    author Guibin Zhang <guibin.beijing@gmail.com> 1303449511 +0800
    committer Guibin Zhang <guibin.beijing@gmail.com> 1303449511 +0800

        Merge branch 'master' of 192.168.80.141:/home/guibin/Project/faster/faster

    如果一个commit没有parent,那么这个commit就一定是root commit,代表当这个项目初始化时的状态。每个项目都至少有一个root。一个项目也可以有多个root,但这不常见,也不必要。
    3. Author。对此次commit负责的作者及其提交时间。
    4. Committer。谁实际执行了此次提交操作及其提交时间。committer可能和author不一样,比如作者写了些代码,发送给提交者提交。
    5. Comment。注释。
    注意:一个commit事实上并没有记录这次提交做了什么内容的改变,所有的改变都根据这次commit所引用的对象的内容和其parent计算得到,尤其是git并不试图去显示的记录rename这些操作,虽然它能够根据相同的文件内容和不同的文件路径计算出rename。commit对象通常由git commit命令创建,提交时,此次提交的parent就是提交时刻的HEAD,并且HEAD的tree提取自当前存储在index中的内容。
  • Tag对象(Tag Object)
  • Tag对象包含了对象名称,对象类型,tag名称,打tag的人(tagger)和一条注释。可以使用git tag命令去创建或者验证tag,细节请参考git tag --help


Git与SVN的区别
非常重要的一点是Git与多数你所熟悉的SCM系统都不同。Subversion, CVS, Perforce, Mercurial都使用 Delta Storage systems,即他们都存储一个commit和另一次commit之间的区别,而Git却不是这样做的,它存储在项目中所有文件在这种树型结构中的快照。在使用Git时这是一个非常重要的概念。

0
0
分享到:
评论
1 楼 yuenkin 2013-08-28  
有些翻译的错误太明显了,
“既然blob对象完全由其数据决定,如果两个文件在同一个目录树下(或者在多个不同版本的库中),那么他们将会共享相同的blob对象。”
    两个文件需要内容完全相同。

相关推荐

    git版本控制介绍

    ### Git版本控制介绍 #### DVCS与Git简介 在软件开发的过程中,版本控制系统(Version Control System,VCS)扮演着至关重要的角色。它不仅能够帮助开发者有效地管理代码变更历史,还能促进团队之间的协作。传统的...

    git magic 开始git吧

    - **Git的对象模型**:深入解析Git的Blob、Tree和Commit对象,理解其在版本控制中的角色。 ### 附录:Git的局限性与翻译资源 - **局限性探讨**:分析Git可能存在的问题,如SHA1的弱点、Windows兼容性等。 - **...

    Git权威指南

    第4篇全面介绍了git的协同模型,即它在实际工作中的使用模式,包括各种经典的git协同模型、topgit协同模型、子模组协同模型、子树合并、android多版本库协同、git与svn协同模型等。第5篇介绍了git服务器的架设,首先...

    PRO GIT.pdf

    Git的对象模型、引用管理、打包文件、RefSpec规范以及传输协议等概念,构成了Git强大功能的基础。 总之,《Pro Git》这本书不仅是一份详尽的操作指南,更是一部深入了解Git设计理念和实践技巧的宝典。通过阅读本书...

    Pro Git 第二版 v2.1.17 中文版 非扫描 EPUB 和 PDF

    1. Git基础:Git的核心概念包括仓库、工作区、暂存区和提交历史。书中会详细介绍如何初始化Git仓库,配置用户信息,以及使用`git add`、`git commit`和`git push`等基本命令来管理文件和版本。 2. 分支管理:Git的...

    精通Git(第二版) 英文最新版

    接下来,书籍可能会介绍版本控制系统的基础知识,这部分内容对于初学者来说至关重要。版本控制系统是一种记录文件内容变化,以方便恢复到某一特定版本的系统。它分为集中式和分布式两种,而Git属于后者,提供了许多...

    Pro Git》中文版.

    书中还深入讲解了Git的工作原理,包括Git对象模型、引用日志、索引(暂存区)等概念,帮助用户更好地理解Git内部机制,以充分利用Git的强大功能。 此外,该书也覆盖了Git的一些高级用法和技巧,比如如何在复杂的...

    Git使用手册中文版

    #### 二、Git基础 - **获取Git仓库**:首次使用Git时需要获取项目仓库,可以通过克隆已有的仓库或将现有项目初始化为新的Git仓库。 - **记录更新**:通过`git commit`命令记录对项目的更改,提交时需附带详细的提交...

    git的详细使用教程.pdf

    执行此命令后,Git将在当前目录下创建一个名为`.git`的隐藏目录,用于存储仓库的所有元数据和对象数据库。 2. **配置Git**:使用`git config`命令配置Git用户的信息,如提交人姓名和邮箱。这些信息非常重要,因为...

    Git学习指南完整版

    - 入门教程:详细介绍Git基础命令的使用,例如git init、git clone、git add、git commit、git push、git pull等。 - 技术介绍:讲解Git背后的基本概念,比如提交的结构、对象模型、分支模型、合并策略等。 - 工作流...

    git学习资料

    Git是一款非常流行的分布式版本...例如,Git与其他版本控制系统如Subversion的交互,以及Git的内部数据结构和对象模型等。通过深入学习这些知识点,开发者可以更好地优化自己的工作流程,提高项目管理和协作的效率。

    Git Community Book(中文版)

    首先,我们要了解Git的对象模型,这涉及到四种对象类型:blob(文件快照)、tree(目录结构)、commit(版本历史记录)和annotated tag(标注标签)。每一个对象都通过SHA-1哈希值来标识。Git的目录结构包括工作目录...

    progit.pdf

    ### Git基础 - **版本控制**:是管理文件、目录随时间变化的一种系统,帮助团队合作开发软件时跟踪和管理源代码变更。 - **Git的基本命令**:包括初始化仓库、记录更改、查看提交历史、撤销操作、管理远程仓库和标签...

    廖雪峰JavaScript Git 教程

    首先,教程介绍了JavaScript语言的基础,包括变量、函数、对象、数组、字符串、日期、正则表达式等。这些是学习任何编程语言的基础,为后续更复杂的技术点打下坚实的基础。 接着,教程深入JavaScript的高级特性,如...

    Git权威指南【样张】

    第4篇全面介绍了git的协同模型,即它在实际工作中的使用模式,包括各种经典的git协同模型、topgit协同模型、子模组协同模型、子树合并、android多版本库协同、git与svn协同模型等。第5篇介绍了git服务器的架设,首先...

    Pro Git (Second Edition)

    最后,书中的Git内部实现部分深入解释了Git的数据模型和内部结构,包括对象数据库、SHA-1哈希、树对象(tree object)、blob对象(blob object)和提交对象(commit object)。这些深入理解有助于开发者在遇到问题时...

    pro git 工具书

    另外,《Pro Git》还深入到Git的内部机制,包括对象模型、引用日志、索引、差异比较和打包机制等。对象模型包括提交对象、树对象、二进制对象和标签对象。了解这些对象是如何存储和引用的,有助于理解Git如何保存和...

    pro git 英文版

    ### 二、Git基础操作 **获取Git仓库**:在第3章中,读者将学习如何创建一个新的Git仓库或从现有的Git仓库克隆一个副本。 **记录更改至仓库**:这部分讲解了如何使用`git add`和`git commit`命令来添加和提交更改,...

Global site tag (gtag.js) - Google Analytics