得到什么;克隆的;及;推;在git克隆和git推送期间
当我运行命令时,例如得到什么;克隆的;及;推;在git克隆和git推送期间,git,Git,当我运行命令时,例如 git push 或 我的回购协议看起来像 B--C--D <- master / A--E--F <- foo-branch A <- master 我知道我通常得到一个分支(似乎通常是master),但我是否也有其他分支的本地提交副本,即使我没有得到指向它们头部的指针?部分依赖于传输:git有“哑传输”(例如使用http一次传输一个对象)和“智能传输”(使用git://或ssh://协议,其中两个git相互协商,然后
git push
或
我的回购协议看起来像
B--C--D <- master
/
A--E--F <- foo-branch
A <- master
我知道我通常得到一个分支(似乎通常是
master
),但我是否也有其他分支的本地提交副本,即使我没有得到指向它们头部的指针?部分依赖于传输:git有“哑传输”(例如使用http一次传输一个对象)和“智能传输”(使用git://
或ssh://
协议,其中两个git相互协商,然后只要接收方表示没有问题,发送方就会构建一个“瘦包”)
它还部分依赖于命令:例如,如果您请求一个“浅层”克隆或一个分支,您通常会得到比执行“普通”克隆更少的结果。而且,当您运行git push
时,您可以选择您最初向远程存储库交付的特定提交ID(如果有的话),以及哪个分支名称你想让他们用
不过,现在让我们忽略浅分支克隆和单分支克隆
以你的例子:
B--C--D <- master
/
A--E--F <- foo-branch
此时,您的git知道需要哪些提交才能将所有提交到远程:如果您在存储库中运行git rev list master ^A(当然,请填写A
的实际SHA-1),这些提交将被列出。无需排除其他SHA-1,因为远程源站
只有一个分支,其提示为提交A
这在内部工作的方式是gitpush
运行gitpack objects
(使用--thin
),然后运行git rev list
,将您请求推送的提交id传递给它,并对git发送给您的所有提交id进行排除(--not
或前缀^
)(同样在我们的例子中,这只是一个提交IDA
)。请参阅git rev list
的文档,特别注意--objects edge
选项(或--objects edge aggressive
处理浅克隆时)
因此,您的git rev list
输出提交D
的ID,加上其树的ID以及该树的所有子树和blob,除非它结束(通过否定的ID,在本例中是排除提交A
)的^A
)远程git必须已经有了它们。然后它输出commitC
的ID及其树,并使用相同的“除非”条件等。请注意,提交A
有一个与其关联的源树;假设提交C
有相同的树,例如,假设提交C
是B
的还原。在这种情况下,不需要发送C
的树:远程必须有它,因为远程有提交Ade>
(这个对象查找可以通过位图进行优化。我认为,github的博客文章描述了这些位图的开发,这是一个解决方案,它解决了遍历大量提交图的缓慢过程,以便根据一些分支提示ID查找哪些对象必须已经在某个远程存储库中。这极大地帮助了这些对象的查找。)因为通过智能协议的获取过程与推送过程是对称的:我们只需交换发送和接收角色。)
在任何情况下,git rev list
的输出都会为您的git pack对象--thin
提供所有要获取的对象ID(commitD
,如果需要,它的树,以及任何需要的子树和blob;commitC
和需要的对象;commitB
和需要的对象),以及明确不获取的ID:提交A
及其对象,如果在A
之前有提交,则这些对象及其对象。打包对象步骤生成一个增量压缩包,其中“获取这些对象”对象相对于“不获取这些其他对象”对象进行压缩
作为一个超级简化的例子,假设a
的树包含一个10MB的文件,其最后一行是“结束”。假设B
的树有一个几乎相同的文件,只是删除了“结束”一词。Git可以将该文件压缩为指令“从blob开始,然后删除最后一行”这些指令的长度远小于10 MB,允许在“瘦包”中使用
通过Internet电话连接(或连接两个git实例的任何数据线)发送的就是这个“瘦包”。接收器然后将包“加厚”为普通git包(普通包不允许对包中不存在的对象进行增量压缩)
好的,这很长,但归结起来是:git不会发送F
(因为您没有要求它发送),也不会发送E
(因为您没有发送F
),也不会查看附加到这两个提交的两个树。但这取决于您使用的确切命令,以及您是否使用智能协议
如果在不使用单分支的情况下运行git clone
,则克隆操作会像往常一样调用远程设备,并获取该远程设备的所有引用列表(就像推送一样!)。要查看这些引用,请使用git ls remote
:
From git://git.kernel.org/pub/scm/git/git.git
aa826b651ae3012d1039453b36ed6f1eab939ef9 HEAD
fdca2bed90a7991f2a3afc6a463e45acb03487ac refs/heads/maint
aa826b651ae3012d1039453b36ed6f1eab939ef9 refs/heads/master
595b96af80404335de2a8c292cee81ed3da24d29 refs/heads/next
60feb01a0d7c7d54849c233d2824880c57ff9e94 refs/heads/pu
7af04ad560ab8edb07b498d442780a6a794162b0 refs/heads/todo
d5aef6e4d58cfe1549adef5b436f3ace984e8c86 refs/tags/gitgui-0.10.0
3d654be48f65545c4d3e35f5d3bbed5489820930 refs/tags/gitgui-0.10.0^{}
[又剪了数百个]
然后,git从远程请求几乎所有的内容是不必要的,但是如果他们向您提供refs/
而不是heads/
和tags/
,您可能无法获得这些标签。您还可以控制git带来的标签。这里的细节有点混乱,但在大多数普通存储库中,克隆会带来所有标签。)
当你这样说的时候,你被错误的假设绊倒了:
我知道我通常会得到一个分支(似乎通常是主分支),但我是否也有用于fo的提交的本地副本
B--C--D <- master
/
A--E--F <- foo-branch
(your git) "what options do your support? I have thin-packs etc"
(their git) "I have thin-packs and ofs-delta and so on"
(your git) "ok, send me all your refs and their SHA-1s"
(their git) "refs/heads/master is <SHA-1 of A>"
(their git) "that's all I have"
From git://git.kernel.org/pub/scm/git/git.git
aa826b651ae3012d1039453b36ed6f1eab939ef9 HEAD
fdca2bed90a7991f2a3afc6a463e45acb03487ac refs/heads/maint
aa826b651ae3012d1039453b36ed6f1eab939ef9 refs/heads/master
595b96af80404335de2a8c292cee81ed3da24d29 refs/heads/next
60feb01a0d7c7d54849c233d2824880c57ff9e94 refs/heads/pu
7af04ad560ab8edb07b498d442780a6a794162b0 refs/heads/todo
d5aef6e4d58cfe1549adef5b436f3ace984e8c86 refs/tags/gitgui-0.10.0
3d654be48f65545c4d3e35f5d3bbed5489820930 refs/tags/gitgui-0.10.0^{}
git rev-list --use-bitmap-index --count HEAD -- foo
Test HEAD~ HEAD
---------------------------------------------------------------------------------------------------------------
5310.3: repack to disk 193.18(181.46+16.42) 194.61(183.41+15.83) +0.7%
5310.4: simulated clone 25.93(24.88+1.05) 25.81(24.73+1.08) -0.5%
5310.5: simulated fetch 2.64(5.30+0.69) 2.59(5.16+0.65) -1.9%
5310.6: pack to file (bitmap) 58.75(57.56+6.30) 58.29(57.61+5.73) -0.8%
5310.7: rev-list (commits) 1.45(1.18+0.26) 1.46(1.22+0.24) +0.7%
5310.8: rev-list (objects) 15.35(14.22+1.13) 15.30(14.23+1.07) -0.3%
5310.9: rev-list with tag negated via --not --all (objects) 22.49(20.93+1.56) 0.11(0.09+0.01) -99.5%
5310.10: rev-list with negative tag (objects) 0.61(0.44+0.16) 0.51(0.35+0.16) -16.4%
5310.11: rev-list count with blob:none 12.15(11.19+0.96) 12.18(11.19+0.99) +0.2%
5310.12: rev-list count with blob:limit=1k 17.77(15.71+2.06) 17.75(15.63+2.12) -0.1%
5310.13: rev-list count with tree:0 1.69(1.31+0.38) 1.68(1.28+0.39) -0.6%
5310.14: simulated partial clone 20.14(19.15+0.98) 19.98(18.93+1.05) -0.8%
5310.16: clone (partial bitmap) 12.78(13.89+1.07) 12.72(13.99+1.01) -0.5%
5310.17: pack to file (partial bitmap) 42.07(45.44+2.72) 41.44(44.66+2.80) -1.5%
5310.18: rev-list with tree filter (partial bitmap) 0.44(0.29+0.15) 0.46(0.32+0.14) +4.5%