问:当git推送在
Smart Protocol上没有共同历史记录的引用时,是否可以在构建瘦包发送时考虑本地和源之间已经存在的根或子树?
TL;博士
在处理和推送到远程Git存储库时,请考虑这种(不常见的)情况.
>我有一个本地存储库,其中本地主服务器指向一棵树,其中有1110个后代子树a [0-9] / b [0-9] / c [0-9].
>远程源/主机与本地主机提交是最新的,即相同的历史.它使用ssh协议.
>无论出于何种原因,我创建了一个局部分支压扁.我将该分支设置为新的单个root-commit,但具有与master相同的内容/树.这可以使用git commit-tree完成.所以这个分支只有一个提交,没有与master共同的提交,但是根树哈希是相同的,它指向master和origin / master中的相同树对象.为了讨论这个问题,这是一个单一/压缩的提交并不重要 – 任何历史都被重写回根提交,没有共同的历史记录.
> git push origin HEAD#push squashed
从大型存储库的性能观察和发送的对象数量来看,我怀疑Smart Protocol上的push,send-pack和receive-pack以及相关的瘦包协商确实如下:
>确认被推送压缩的提交与当前任何提交源没有共同历史记录.
>忽略了这样一个事实:压扁的树不仅仅是原点,而是当前HEAD ref的树.
>打包并发送一切.
在这种情况下,树木是相同的.如果在压缩中进行后续更改…要么另外提交,要么更改a0中的文件的新壁球,2树(/和a0)将会改变,而另一个1109将保持不变.根树已经改变,这意味着需要进行下一级搜索以查看是否值得搜索更多的公共子树.这可能需要启发式算法,因为不将所有子树向下比较到叶子,不可能在任何特定深度处推断树中共有的后代树的数量.
当然,如果在推送无共同历史中存在多个提交,则需要针对每个提交重复该协商.
Smart API是否可以考虑已经存在的公共子树,或者至少是根树,因为它考虑了每次提交?或者Git已经这样做了,我的客户端或服务器出了什么问题?
git版本2.8.2
最佳答案 检查git的源代码并使用git守护程序和GIT_TRACE_PACKET进行尝试表明你对它正在做的事情是正确的:git只在提交级别进行协商.如果未共享历史记录,git将不会检测共享内容.
Does it sound reasonable that the Smart API could consider already-held common sub-trees, or at the very least, the root-tree, as it considers each commit?
如果已经持有的公共子树无法通过已经存在的公共提交来识别,那么为了识别那些必须发送其ID的子树.
问题是,对于任何不完整的读数,我都可以构建一个看似合理的角落情况,发送任意大量的冗余数据 – 但每次发送每个现有的子树ID以避免这种可能性显然是一个巨大的损失.不要忘记,往返延迟非常昂贵.那么,在考虑增加所有提取的额外开销时,您可能会在更多时间花费更多时间进行协商?如果您认为某种特定的替代方法可以节省整体时间,那么您将不得不显示实际生产流量的硬数据.
还记得你可以自己构建包.这并不难,你将对象id提供给git pack-objects包并将输出放到.git / objects / pack中,恭喜你,你刚刚将这些对象提取到该repo中.