运行
git-upload-pack,将打包的对象发送回
git-fetch-pack
,从另一个存储库接收缺失的对象。
您可以在 Git 2.19(2018年第三季度)中了解更多关于
git fetch-pack
的信息,因为"
git fetch-pack --all
"过去会在看到指向提交以外的对象的注释标签时不必要地失败。
请看
提交 c12c9df(2018年6月13日)作者是
Kirill Smelkov(navytux
)。
得到
Junio C Hamano(gitster
)的帮助。
请看
提交 e9502c0(2018年6月11日)作者是
Jeff King(peff
)。
得到
Junio C Hamano(gitster
)的帮助。
(由Junio C Hamano -- gitster
--在提交 0079732中合并,2018年6月28日)
Fetch-pack --all
在处理不寻常的标签时出现问题,详见5f0fc64(fetch-pack
: eliminate spurious error messages, 2012-09-09, Git v1.8.0),
并且直到最近才在e9502c0中得到修复(fetch-pack: don't try to fetch peel values with --all
, 2018-06-11)。
fetch-pack
: 不要尝试使用--all
获取剥离值
当“
fetch-pack --all
”在远程看到一个
tag-to-blob时,它会尝试获取标签本身(“refs/tags/foo”)和远程广告的剥离值(“
refs/tags/foo^{}
”)。请求后者所指向的对象可能会导致upload-pack抱怨“not our ref”,因为它不会用OUR_REF标记剥离对象(除非它们是其他引用的顶部)。
可以说
upload-pack
应该标记这些剥离对象。但过去从未这样做过,因为客户端通常只会请求标签并期望同时获得剥离值。这就是"
git fetch
"以及旧版本的"
fetch-pack --all
"的工作方式。
让我们明确地测试所有相关的4个标签对象的情况 指向:
- 一个blob,
- 一个tree,
- 一个commit,以及
- 另一个标签对象。
引用的标签对象本身是从常规
refs/tags/*
命名空间下引用的。
在e9502c0(Git 2.19)之前,
fetch-pack --all
失败了,例如:
在 Git 2.25(2020 年第一季度)中,fetch-pack 包括trace2 注释。
请参见提交 9e5afdf(2019 年 11 月 19 日),由Erik Chen(erikchen
)撰写。
(由Junio C Hamano -- gitster
--于提交 76c6824中合并,2019 年 12 月 5 日)
fetch
:添加trace2
工具
签名作者:Erik Chen
在fetch-pack.c
中添加trace2
区域,以更好地跟踪抓取过程中各个阶段所花费的时间:
- 解析远程引用并查找截止点
- 标记本地引用为完成
- 标记完成的远程引用为公共引用
对于具有许多引用的存储库,所有阶段都可能潜在缓慢。
例如:(然后您可以了解git fetch
的操作)
D:\git\git>set GIT_TRACE2_EVENT=1
D:\git\git>git fetch
23:58:43.225088 exec-cmd.c:237 trace: resolved executable dir: D:/newenv/prgs/gits/PortableGit-2.24.0.2-64-bit.7z/mingw64/bin
{"event":"version","sid":"20200111T225843.226090Z-H91a50d96-P00007560","thread":"main","time":"2020-01-11T22:58:43.234089Z","file":"common-main.c","line":48,"evt":"2","exe":"2.24.0.windows.2"}
{"event":"start","sid":"20200111T225843.226090Z-H91a50d96-P00007560","thread":"main","time":"2020-01-11T22:58:43.234089Z","file":"common-main.c","line":49,"t_abs":0.011593,"argv":["git.exe","fetch"]}
{"event":"data_json","sid":"20200111T225843.226090Z-H91a50d96-P00007560","thread":"main","time":"2020-01-11T22:58:43.260090Z","file":"compat/win32/trace2_win32_process_info.c","line":118,"repo":0,"t_abs":0.037686,"t_rel":0.037686,"nesting":1,"category":"process","key":"windows/ancestry","value":["git.exe","cmd.exe","explorer.exe"]}
{"event":"def_repo","sid":"20200111T225843.226090Z-H91a50d96-P00007560","thread":"main","time":"2020-01-11T22:58:43.261089Z","file":"repository.c","line":130,"repo":1,"worktree":"D:/git/git"}
23:58:43.262092 git.c:439 trace: built-in: git fetch
{"event":"cmd_name","sid":"20200111T225843.226090Z-H91a50d96-P00007560","thread":"main","time":"2020-01-11T22:58:43.262092Z","file":"git.c","line":440,"name":"fetch","hierarchy":"fetch"}
{"event":"region_enter","sid":"20200111T225843.226090Z-H91a50d96-P00007560","thread":"main","time":"2020-01-11T22:58:43.281090Z","file":"builtin/fetch.c","line":1361,"repo":1,"nesting":1,"category":"fetch","label":"remote_refs"}
{"event":"child_start","sid":"20200111T225843.226090Z-H91a50d96-P00007560","thread":"main","time":"2020-01-11T22:58:43.284088Z","file":"run-command.c","line":735,"child_id":0,"child_class":"remote-https","use_shell":false,"argv":["git","remote-https","origin","https://github.com/git/git"]}
23:58:43.284088 run-command.c:663 trace: run_command: GIT_DIR=.git git remote-https origin https:
从Git 2.31(2021年第一季度)开始,
ls-refs
协议操作(也被
git fetch
使用)已经进行了优化,以缩小在生成响应时遍历的
refs/
子层次结构。
这进一步说明了
git fetch
的工作原理。
请参见提交记录 b3970c7, 提交记录 16b1985 (2021年1月20日),作者为Taylor Blau (ttaylorr
)。
请参见提交记录 83befd3 (2021年1月20日),作者为Jacob Vosmaer (jacobvosmaer
)。
(该提交记录已被Junio C Hamano -- gitster
--合并于提交记录 6254fa1,2021年2月5日)
ls-refs.c
:遍历不相交的“ref-prefix”集合的前缀
原始补丁由Jacob Vosmaer提供
签署者:Taylor Blau
ls-refs
对整个 ref
命名空间执行单个修订遍历,并将与给定的 ref 前缀之一匹配的内容发送给用户。
如果总共有很多 refs,这可能会很昂贵,但是与给定前缀覆盖的部分相比,它们很少。
为了尝试减少遍历的 refs 数量和发送的 refs 数量之间的差异,只遍历在给定前缀的最长公共前缀中的引用。
这非常类似于 b31e268 中采取的方法(“ref-filter.c
:查找不相交的模式前缀”,2019-06-26,Git v2.23.0-rc0 -- merge 列在 batch #6 中),该方法对多模式 'git for-each-ref
'(man) 调用进行类似的操作。
回调函数 'send_ref
' 可以忽略任何不以指定前缀之一开头的参数,从而可以忽略额外的模式。
同样,b31e268 中引入的代码可以在元字符处停止,但是我们仅传递严格的前缀。
最坏的情况下,我们会返回太多结果,但是 send_ref
执行的双重检查将丢弃任何不以前缀列表中的内容开头的内容。
最后,如果没有提供前缀,则隐式添加空字符串(它将匹配所有引用),因为这符合现有行为(请参见 "ls-refs.c:ref_match()
" 中的“无限制”注释)。
随着 Git 2.38 (2022 年第三季度) 的发布,在 "git fetch
"(man) 会话期间进行的共同祖先协商交换现在会留下跟踪日志。
这有助于查看 git fetch
的操作内容。
请查看提交记录 a29263c(2022年8月2日),作者为Josh Steadmon(steadmon
)。
(由Junio C Hamano -- gitster
--在提交记录 098b7bf中合并,日期为2022年8月25日)
签名作者:Josh Steadmon
确认者:Jeff Hostetler
目前,V0/V1/V2获取的协商过程中有覆盖整个协商过程的trace2区域。然而,我们需要额外的数据,例如每轮协商的时间或每轮中“haves”的数量。此外,“独立协商”(也称为推送协商)根本没有追踪。拥有这些数据将使我们能够比较各种协商实现的性能,并调试意外缓慢的获取和推送会话。
- 为所有协商实现(V0+V1、V2和独立协商)添加每轮trace2区域,以及独立协商的总体区域。
- 为每轮的“haves”数量和“徒劳”的对象以及协商完成后的总轮数添加trace2数据记录。
GIT_TRACE2_EVENT="$(pwd)/trace2"
git -C myclient fetch --progress origin main
...
"key":"total_rounds","value":"6"
...
git help fetch
中涵盖了,您是否有一些文档没有解答的具体问题? - Andrew Cgit help fetch
,特别是涉及到git fetch [<repository> [<refspec>...]]
的部分。然而,由于我对 git 的知识有限,我认为目前它无法解释我上述描述的情况。你能否告诉我help
中的哪一部分可以帮助我?非常感谢。 - trooregit fetch remote branch
会将分支获取到 FETCH_HEAD。通常你想要使用git fetch remote branch:branch
,这样可以将其获取到同名的本地分支。当你没有指定时,它会回退到你的配置中,这个配置可能会指定(在 .git/config 中查找带有 fetch 的行)。 - Andrew Cgit fetch origin branch1
是否会更新本地的远程分支origin/branch1
。我以为会,但在我的情况下并没有。每当我只想更新一个特定的远程分支时,我都必须使用git fetch origin
来更新所有远程分支。 - troorefetch = +refs/heads/*:refs/remotes/origin/*
。感谢你的建议和git fetch
的帮助,我现在理解了git fetch remote branch:branch
的用法。但是当我没有指定本地分支时,“回退”的行为意义仍然不清楚。 - troore