git fork 200M 的仓库,服务端磁盘占用并不会变大,是怎么做到的

266 天前
 weishao666

git fork 一个 200M 的仓库 A ,得到 B ,我在 B 的裸库查看大小 du -sh ,可以看到是 200M ,但是我整个磁盘的大小并不会增加 200M ,机会没变化。这是 git 的什么机制做到的呢?假如我把 B copy 到/tmp/B ,那磁盘就增加了 200M ,又是什么原理?肯定跟底层的文件引用啥的有关系,但是我在 B 的裸库中并没有见到软链接

2813 次点击
所在节点    git
47 条回复
Muniesa
266 天前
没见到软链接,那硬链接呢
Trim21
266 天前
git 有 fork 这个命令吗…
mxT52CRuqR6o5
266 天前
git 的原理没了解过吗?
cc666
266 天前
@mxT52CRuqR6o5 #3 git 有 fork 这玩意儿么,还原理
所以楼主你具体是怎么操作的
mxT52CRuqR6o5
265 天前
@cc666 op 在服务器建了个 git 服务(可以理解成 gitlab ),然后在 gitlab 里进行 fork 操作,fork 了一个很大的仓库,但 git 服务占用的服务器磁盘空间没有增加很多,这都看不明白吗
而这个现象和 git 在本地的存储原理是息息相关的
cc666
265 天前
@mxT52CRuqR6o5 什么本地存储原理,本质上来说不就是一堆 blob 和 pack 对象么,这怎么解释 OP 的问题:空间没有增长? git 本身就没有 fork 这玩意儿,他规定了服务端是实现 fork 是复制一个新的目录还是软硬链接实现 fork 么,规定了 fork 的时候是否执行一次 aggressive gc 么?规定了服务端是否使用去重文件系统么?你要是能回答就回答,不会回答就别嚷嚷着:你不懂“git 在本地的存储原理”
mxT52CRuqR6o5
265 天前
@cc666 #6 一堆 blob 和 pack 对象还不够解释吗?
cc666
265 天前
@mxT52CRuqR6o5 那你解释一下?快解释,为什么 fork 了一个空间没有增长
mxT52CRuqR6o5
265 天前
@cc666 #6 一堆 blob 和 pack 对象还不够解释吗?你干脆从 CPU 是怎么从沙子造出来开始解释好了
cc666
265 天前
@mxT52CRuqR6o5 你干脆从因为这样所以这样来回答所有问题好了
mxT52CRuqR6o5
265 天前
@cc666 #8 fork 了又没增加新 blob 和 pack ,为啥会增长,为啥不能解释
cc666
265 天前
@mxT52CRuqR6o5 你 fork 的仓库和别人的仓库放在 path 么? git 规定了么? gitlab (假设是 gitlab )用的不是复制而是软硬链接么?还是用的去重文件系统?
mxT52CRuqR6o5
265 天前
@cc666 #12 fork 行为不增加 blob 和 pack ,基于此原理就能实现一个 fork 不增加存储占用的 git 服务,还有啥不够吗?你再往下深究什么软硬链接去重文件系统这个系统背后的细节具体是怎么设计的,不就是我之前说的干脆从 CPU 是怎么从沙子造出来开始解释好了
说得好像软硬链接文件去重我就不能继续往下深究一样,你咋不再往下解释解释软硬链接文件去重怎么就能节省存储空间了,为啥存储数据会增加存储空间,为啥磁盘会用容量上限,为啥磁盘能存储数据
cc666
265 天前
@mxT52CRuqR6o5
“基于此原理就能实现一个 fork 不增加存储占用的 git 服务”
你这个回答就是假设了 OP 用的是一个能能够做到重复文件不增加存储空间的 git 托管实现或者服务器了
mxT52CRuqR6o5
265 天前
@cc666 #14 服务器存 blob 和 pack 就行了,都不需要去重
cc666
265 天前
@mxT52CRuqR6o5 不管是 blob 还是 pack ,还是小猫小狗存,结果都是一样的,答案就是:服务器存小猫小狗就行了
并且为什么假定服务器在复制一个仓库之后不对仓库进行 gc 呢,存 blob 和 pack 如果遇到 hash 冲突呢( git 的 hash 冲突是存在的并且很坑的),这都是很复杂的情况,这其实和 git 的实现没什么关系,这完全是 git 服务的实现有关
mxT52CRuqR6o5
265 天前
@cc666 #16 你说的这些不还是我最开始说的问题「干脆从 CPU 是怎么从沙子造出来开始解释好了」
hash 冲突这些不还是实现细节,而且还是 blob 、pack 实现的(必须处理的) edge case ,fork 一个仓库服务端存储没有大幅度增加,到底是因为 blob 、pack 的设计呢?还是因为你说的这些 edge case 呢?而且为啥你会假定 fork 一个仓库就非得把所有东西复制一遍再 gc ,不是很能理解
blob 、pack 的设计不就是 git 的基本原理的一部分吗?所以我说让 OP 去了解 git 的原理到底有什么问题? fork 后服务端存储没有大幅度增加,blob 、pack 的设计就是最最最最主要的原因
cc666
265 天前
@mxT52CRuqR6o5 即使不是 blob 和 pack 存,是用小猫小狗存,只要他要在磁盘上存东西,结果都是一样,所以这个问题的本质和 git 的原理没什么关系,而是服务器的实现
cc666
265 天前
@cc666 而我们没法假定 OP 的服务用的是什么,在 OP 给出更多信息之前,也不知道问题的答案
mxT52CRuqR6o5
265 天前
@cc666 #18 我十分怀疑你还是没明白 OP 问的问题是什么,OP 是在服务器建了个 git server ( gitlab 这种),而不是在服务器 git clone 了一个仓库然后又复制了一份
什么叫「即使不是 blob 和 pack 存」,git 底层那些东西不就是 blob 、pack ,不存这些存什么,fork 一个仓库没增加 blob 、pack ,自然存储占用不会大幅增加

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1019568

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX