git - 为什么 'checkout master' 花费的时间比 'checkout feature-branch' 长?

标签 git git-branch git-checkout

我刚刚注意到,有时在 master 和 feature-branch 之间切换时, 即使一切都已经 pull/推 + 最新...

如果我这样做

git checkout featureBranch

它是即时的(没有进度信息)。

但是当我这样做的时候

git checkout master

它需要更长的时间,并且您还会获得进度信息:

Checking out files: 100% (312/312), done.

即使我只是来回切换几次,这种行为也是可重复的。

只是好奇——导致这种情况的底层实现细节(?)是什么?

最佳答案

更新 - torek 指出(在评论中)git 在开始显示状态之前用完了一个计时器 - 所以快速 checkout 根本不显示状态,但如果它开始花费足够长的时间你可能会注意到,你可以看到进步。更新了几句话来反射(reflect)这一点。


在某种程度上,我会说这一定与特定的 repo 有关,因为我不知道 git 考虑的任何方式(除了“作为第一个分支的默认名称”) master 随着分支的发展而特别。

但我可以做出有根据的猜测。当存在打包对象时,git 会针对任何给定文件的最新版本进行优化。例如,假设您有

A --- B --- C <--(master)
             \
              D <--(feature)

D 中的每个文件都将是该特定文件的“最新版本”;所以它要么是一个松散的对象,要么是包文件中的“非差异”对象。因此检查 feature 不需要修补任何文件;它只是读取 blob。它可能发生得足够快,以至于 git 感觉不需要开始显示状态。

理论上 C 可以有一些文件的“旧版本”,在一个包中可以表示为“与 较新版本的文件 的差异”。实际上,如果您的事件分支中只有一个较新的提交,我怀疑它会变成那样。但是在真实的 repo 中,master 可能在 develop 之后,而 develop 可能在任意数量的功能分支之后,master head commit 有一些 packed-and-diffed 对象需要解析。我怀疑补丁的应用需要足够的时间来提供可见的状态报告。

这不是唯一的可能解释。也许您在 master 下有一个更大的工作树,或者 LFS 的使用可能是一个因素(尽管我认为在那种情况下您会看到不同的输出)。就像我说的,通常我会怀疑 repo ​​特定因素在起作用。只是我上面描述的是一个“ repo 特定因素”,可能适用于大多数重要的 repo 。


更新 2 - 我在这里的基本主张 - master 并不特别 - 很容易测试。克隆 repo,并在克隆中

git checkout master
git branch featureOldMasterBranch
git checkout featureBranch
git branch -f master

现在,master 的克隆 check out 应该是即时的,而 featureOldMasterBranch 的 check out 应该需要足够的时间来显示可见的进度更新。

请记住,分支只是一个 ref 只是一个指针,这表明它与提交有所不同 - 即某些特定于 repo 的东西 - 而不是对 master 的任何特殊处理。

关于git - 为什么 'checkout master' 花费的时间比 'checkout feature-branch' 长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44309482/

相关文章:

Git子模块不 pull

git - 如何从 TortoiseGit 重命名我的分支?

java - Eclipse 和 Git - 来自 GitHub 的存储库无法从“导入”菜单中使用(来自 Git 的项目可用)

git - 旧源代码到新存储库

git - 如何显示带有分支名称的git日志

git - 如何在 SourceTree 本地 checkout fork 的 pull 请求?

git - 什么是 git稀疏 checkout 以及它在什么情况下有用?

git - 在推送当前分支期间 check out 新的 git 分支是否安全?

git - 如何从 git kraken rebase 分支

git - 如何将一个git分支 merge 到多个发布分支