Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
git分支和标记如何存储在磁盘中?_Git_Tags_Branch_Git Branch - Fatal编程技术网

git分支和标记如何存储在磁盘中?

git分支和标记如何存储在磁盘中?,git,tags,branch,git-branch,Git,Tags,Branch,Git Branch,我最近检查了我工作中的一个git存储库,它有10000多个分支和30000多个标记。新克隆后,回购协议的总大小为12G。我确信没有理由拥有10000家分支机构。所以我相信它们会在磁盘中占据相当大的空间。因此,我的问题如下 分支和标记如何存储在磁盘中,例如使用了什么数据结构,每个分支存储了什么信息 如何获取有关分支的元数据?就像创建分支时一样,分支的大小是多少 所有git引用(分支、标记、注释、隐藏等)都使用相同的系统。这些是: 参考资料本身,以及 “重新登录” Reflogs根据引用名称存储

我最近检查了我工作中的一个git存储库,它有10000多个分支和30000多个标记。新克隆后,回购协议的总大小为12G。我确信没有理由拥有10000家分支机构。所以我相信它们会在磁盘中占据相当大的空间。因此,我的问题如下

  • 分支和标记如何存储在磁盘中,例如使用了什么数据结构,每个分支存储了什么信息
  • 如何获取有关分支的元数据?就像创建分支时一样,分支的大小是多少
  • 所有git引用(分支、标记、注释、隐藏等)都使用相同的系统。这些是:

    • 参考资料本身,以及
    • “重新登录”
    Reflogs根据引用名称存储在
    .git/logs/refs/
    中,但有一个例外:
    HEAD
    的Reflogs存储在
    .git/logs/HEAD
    中,而不是
    .git/logs/refs/HEAD

    参考文献要么是“松散的”,要么是“打包的”。压缩引用位于
    .git/Packed refs
    中,它是一个平面文件,包含用于简单引用的(SHA-1,refname)对,以及用于注释标记的额外信息。“松散”引用位于
    .git/refs/name
    中。这些文件包含原始SHA-1(可能是最常见的),或文字字符串
    ref:
    ,后跟符号ref的另一个引用的名称(通常仅适用于
    HEAD
    ,但您可以创建其他引用)。符号引用没有打包(或者至少,我似乎无法实现:-))


    打包标签和“空闲”分支头(那些没有被主动更新的分支头)节省了空间和时间。你可以用它来做这件事。但是,
    git-gc
    为您调用
    git-pack-refs
    ,因此通常您不需要自己执行此操作。

    因此,我将稍微扩展一下主题,并解释git如何存储内容。这样做将解释存储了什么信息,以及存储库的大小到底有什么关系。作为一个合理的警告:这个答案相当长:)

    Git对象 Git本质上是一个对象数据库。这些对象有四种不同的类型,都由其内容的SHA1散列来标识。这四种类型是blob、trees、commits和tags

    斑点 blob是最简单的对象类型。它存储文件的内容。因此,对于存储在Git存储库中的每个文件内容,对象数据库中都存在一个blob对象。由于它只存储文件内容,而不存储像文件名这样的元数据,因此这也是防止具有相同内容的文件被多次存储的机制

    树 上一层,树是将blob放入目录结构的对象。一棵树对应一个目录。它本质上是一个文件和子目录列表,每个条目包含一个文件模式、一个文件或目录名,以及对属于该条目的Git对象的引用。对于子目录,此引用指向描述子目录的树对象;对于文件,此引用指向存储文件内容的blob对象

    犯罪 blob和tree已经足够表示一个完整的文件系统。为了在上面添加版本控制,我们有commit对象。每当您在Git中提交某些内容时,都会创建提交对象。每次提交表示修订历史记录中的快照

    它包含对描述存储库根目录的树对象的引用。这也意味着每一个实际引入一些更改的提交至少需要一个新的树对象(可能更多)

    提交还包含对其父提交的引用。虽然通常只有一个父级(对于线性历史记录),但提交可以有任意数量的父级,在这种情况下,通常称为合并提交。大多数工作流只会让您与两个家长进行合并,但您也可以拥有任何其他号码

    最后,提交还包含您希望提交的元数据:作者和提交者(姓名和时间),当然还有提交消息

    这就是拥有完整版本控制系统所需的一切;但当然还有一种对象类型:

    标签 标记对象是存储标记的一种方法。确切地说,标记对象存储带注释的标记,即具有类似于提交某些元信息的标记。它们是由git tag-a(或在创建签名标记时)创建的,需要标记消息。它们还包含指向的提交对象的引用和标记器(名称和时间)

    工具书类 到目前为止,我们有一个完整的版本控制系统,带有带注释的标记,但是我们所有的对象都是通过它们的SHA1散列来标识的。这当然有点烦人,所以我们有一些其他的东西让它更容易:参考资料

    引用有不同的风格,但最重要的是:它们是简单的文本文件,包含40个字符,它们是指向的对象的SHA1散列。因为它们是如此简单,它们非常便宜,所以使用许多引用根本没有问题。它不会产生任何开销,也没有理由不使用它们

    通常有三种“类型”的引用:分支、标记和远程分支。它们的工作原理是一样的,都指向提交对象;除了指向标记对象的注释标记(普通标记也只是提交引用)。它们之间的区别在于如何创建它们,以及它们存储在
    /refs/
    的哪个子路径中。不过,我现在不会讨论这个问题,因为几乎每一个Git教程都会对此进行解释;请记住:引用,即分支,非常便宜,所以请毫不犹豫地为所有内容创建它们

    压缩 现在因为torek在他的回答中提到了Git的压缩,我想澄清一下。联合国