Sil*_*eak 4 git git-pull git-push git-fetch
我已经看过这里,但无法弄清楚我想知道的事情:如何git push或git pull弄清楚另一边缺少哪些提交对象?
假设我们有一个包含以下提交的存储库:(字母代表SHA-1 ID,d是refs/heads/master)
a -> b -> c -> d
Run Code Online (Sandbox Code Playgroud)
相比之下,遥控器具有:
a -> e -> f -> g
Run Code Online (Sandbox Code Playgroud)
根据git文档,遥控器会告诉我们它refs/heads/master处于g,但由于我们不知道该提交,这实际上并没有告诉我们什么.怎么能够找出丢失的数据?
在另一个方向,该文件说:
此时,fetch-pack进程会查看它拥有的对象,并通过发送"want"然后发送它想要的SHA-1来响应它所需的对象.它使用"have" 发送它已经拥有的所有对象,然后发送SHA-1.在此列表的末尾,它写入"done"以启动upload-pack进程以开始发送所需数据的packfile:
这解释了遥控器如何确定要发送的数据,但这不会影响具有许多对象的存储库的性能吗?否则,文本中实际意味着什么呢?
显然,根据方向(推动与拉动),数据传输的方式是非常不同的.这个设计选择遇到了什么以及如何遇到挑战,我如何理解文档中的描述?
Sch*_*ern 11
神奇的是ID.提交ID由许多内容组成,但基本上它是SHA-1哈希.
更改其中任何一项,您需要使用新ID创建新的提交.请注意,包含父ID.
这对Git意味着什么?这意味着如果我告诉你我已经提交了"ABC123"并且您提交了"ABC123",我们知道我们拥有相同的内容,相同的作者,相同的日期,相同的消息和相同的父母.这些父母具有相同的ID,因此他们具有相同的内容,相同的作者,相同的日期,相同的消息和相同的父母.等等.如果ID匹配,则它们必须具有相同的历史记录,无需进一步检查该行.这是Git的强大优势之一,它深深地融入了它的设计中,没有它你就无法理解Git.
拉是一个提取加一个合并. git pull origin master是git fetch origin加git merge master origin/master(或rebase带--rebase).一个fetch看起来像这样......
remote @ http://example.com/project.git
F - G [bugfix]
/
A - B - C - D - E - J [master]
\
H - I [feature]
local
origin = http://example.com/project.git
F - G [origin/bugfix]
/
A - B - C - D - E [origin/master] [master]
Run Code Online (Sandbox Code Playgroud)
现在本地看起来像这样......
local
origin = http://example.com/project.git
F - G [origin/bugfix]
/
A - B - C - D - E [master] - J [origin/master]
\
H - I [origin/feature]
Run Code Online (Sandbox Code Playgroud)
然后它将git merge master origin/master完成拉动,这将快速前进到J.
推送类似,除了进程反向(本地发送提交到远程)并且它只会快进.
这就是Pro Git所说的"哑协议",当你的遥控器是一个简单的HTTP服务器时使用.智能协议是更经常使用的,远不那么繁琐,并且有许多优化.但是你可以看到它们是如何非常高效的.没有必要传达整个历史记录,他们只需要发送20个字节的哈希键,直到找到共同的祖先.
这是一些来源和进一步阅读.
| 归档时间: |
|
| 查看次数: |
355 次 |
| 最近记录: |