分支、标签、远程跟踪名称和其他引用的数量没有硬性限制。(Git的名称到哈希ID映射条目都是 引用(refs) 或者 参考(references):分支名称只是一个以 refs/heads/ 开头的引用。)
这些引用并不总是存储在单独的文件中。特别是,引用会随着时间变得“压缩”。 压缩后的引用存在于一个平面文件中,这使它们占用(更少的)磁盘空间,但现在读取任何一个特定引用的值 - 其哈希ID - 可能涉及读取相当大的文件,如果您有许多引用。(写入值将导致引用变为未压缩状态,在packed-refs文件中留下先前的值 - 因此,可以看出查找引用值的过程始终从查找未压缩的副本开始,因为后者必须覆盖任何已压缩的副本。)
由于每个名称和值对占用很少的磁盘空间(一个块或更少),因此肯定有可能创建数百万个引用。不过,如果您这样做,您的Git操作将明显变慢。原因是Git充满了所有引用的线性扫描。例如,要在git log输出之前“装饰”它,在git log打印提交之前,它会查看每个引用,看看该引用是否引用该提交。Stack Overflow上有一个问题(rootkonda的答案链接到它),在其中又有一个链接(qqx的答案)到关于性能问题的nabble.com归档邮件列表线程(一些已经修复,但仍然有一些存在)。
GitHub和Google也都发现多年前Git在启动时可以花费大量时间和网络带宽进行欢迎过程:例如,当您的Git为git fetch调用服务器的Git时,您的Git会要求服务器Git列出所有分支、标签和其他名称。如果列出了10,000个名称,每个名称平均扩展为约60个字符,那么在任何有用的提交交换之前,将传输约600 kilobytes的数据。
总的来说,创建数千或数百万个引用并不是一个好计划。从理论上讲,没有理由不这样做,但出于协议和性能方面的原因,建议将软引用上限设为不超过一千。
commit c7a62075917b3340f908093f63f1161c44ed1475 (HEAD -> master, origin/master, origin/HEAD)
HEAD
、master
、origin master
和 origin/HEAD
是在搜索所有引用时找到的标识;格式化的 HEAD ->
表示 HEAD
已经挂载到了 master
上。
2请注意,带注释的标签会被重复列出,因为它们同时列出了标签名称和哈希值,以及后缀为 ^{}
的标签名和标签目标。即使没有换行符或其他分隔符,refs/tags/v1.2.3 09e393d913072d7765b02aba1210d843a83cfbae
也有57个字符长度。