git fetch如何确定客户端丢失的对象?

时间:2018-01-06 22:48:12

标签: git

我总是想知道git fetch如何确定需要转移哪些对象。客户端无法决定它,因为它不知道哪些对象属于分支,服务器无法决定它,因为它不知道客户端已经有哪些对象。

我读到客户端发送它想要获取的分支的当前状态,服务器从提交它的那个仍然缺失,但我认为这并不能完全消除不必要的对象传输的可能性。例如,考虑这两个回购:

客户端:

    b1  b2
    |   |
    v   v
A - B - C

服务器:

        b2  b1
        |   |
        v   v
A - B - C - D

现在,如果客户端提取请求自提交b1以来的所有新提交的分支B,则即使客户端已知C,也会传输b1。可以构建更复杂和破坏性的例子。

这是否被忽视或是否有一些我错过的聪明的解决方案。是否有对git的获取机制的深入描述?此外,是否有关于此类问题的学术文献? (“DAG复制/同步”可能?)

编辑:我测试了上面的示例,在抓取b2时,如果已经提取netCDF4,则转移的对象较少。所以似乎还有更多的东西,然后就是“从B开始给我一切b1。”

2 个答案:

答案 0 :(得分:0)

Here是关于git的好书。在引擎盖下,它是文件系统。每个提交都是一组对象 - 目录和文件。每个提交包含整个数据,而不是差异,如CVS / SVN。但是,如果没有更改某些内容,可以从不同的地方引用。所以这是非常理想的。

回答你的问题。客户端发送最后同步版本的fetched分支...这样服务器就知道差异了。这个差异是一组提交,已经描述了休息......希望它有所帮助。

答案 1 :(得分:0)

找到git-scm.com

  

[...] fetch-pack进程查看它拥有的对象,并通过发送“want”然后发送它想要的SHA-1来响应它所需的对象。它使用“have”发送它已经拥有的所有对象,然后发送SHA-1。在此列表的末尾,它写入“done”以启动upload-pack进程以开始发送所需数据的packfile:

003cwant ca82a6dff817ec66f44342007202690a93763949 ofs-delta
0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
0009done
0000

(其中upload-pack是服务器端的进程)

因此,如果我做对了,客户端会在请求中包含一个所有对象的列表,这似乎效率很低。但据我所知,似乎没有更好的解决方案。