稀疏结账——它是如何运作的

sch*_*tte 3 git version-control git-sparse-checkout

我一直在寻找一种方法来仅克隆我的一个项目的子目录。显然我找到了这个答案。它设计精良,分步解决方案很好地解释了如何实现这一点。现在最后它引用了这样的文档:

“稀疏签出”允许稀疏地填充工作目录。它使用skip-worktree位(参见git-update-index(1))来告诉Git工作目录上的文件是否值得查看。

我的问题是我无法理解这意味着什么。我从 Git 中学到的一件事是,它是一个很棒的工具,但在实施某些操作之前,了解幕后发生的事情从长远来看确实可以帮助您。

所以,问题是:

稀疏结帐如何工作以及输出是什么?

Von*_*onC 8

Git 2.25(2020 年第一季度)中引入的新命令git sparse-checkout来自Microsoft 基于其Scalar项目的贡献

\n
\n

在 Microsoft,我们使用VFS for Git (以前称为 GVFS)支持Windows 操作系统存储库。VFS for Git 使用虚拟化文件系统来绕过有关存储库大小的许多假设,使 Windows 开发人员能够以以前认为不可能的规模使用 Git。

\n

在支持 Git 的 VFS 时,我们使用自定义跟踪系统并收集用户反馈来确定性能瓶颈。
\n我们对 Git 客户端做出了多项贡献,包括提交图文件以及对git push和 的改进sparse-checkout

\n

基于这些贡献和最近对 Git 的许多其他改进,我们启动了一个项目来支持非常大的存储库,而无需虚拟化文件系统。

\n
\n

因此, Scalar 项目已从VFS for Git的修改版本(2021 年中)转变为围绕 Git 核心功能的薄壳。
\nScalar 可执行文件现已移植并包含在microsoft/git fork中。

\n

它与Windows 2.38 的 Git集成(2022 年 10 月)

\n

Derrick Stolee的2020 年文章“通过稀疏结帐缩小单一仓库规模”解释了当今如何管理稀疏结帐(2020 年以上)

\n
\n

sparse-checkout与现有存储库一起使用

\n

要将工作目录限制为一组目录,请运行以下命令:

\n
git sparse-checkout init --cone\ngit sparse-checkout set <dir1> <dir2> ...\n
Run Code Online (Sandbox Code Playgroud)\n

如果遇到困难,请运行git sparse-checkout disable以返回到完整的工作目录。

\n

init子命令设置必要的 Git 配置选项,并sparse-checkout使用表示“仅匹配根目录中的文件”的模式填充文件。

\n

set子命令使用模式修改sparse-checkout文件以匹配给定目录中的文件。
\n此外,还包括直接位于指定目录的父目录\xe2\x80\x99 的目录中的任何文件。

\n

例如,如果您运行git sparse-checkout set A/B,则 Git 将包含名称为A/B/C.txt( 的直接子级A/B) 和A/D.txt( 的直接兄弟A/B) 以及E.txt( 的直接兄弟A) 的文件。

\n
\n

例如:

\n
\n

构建 Android 应用程序的团队通常可以只使用其中的文件client/android,并使用当前部署的服务运行所有集成测试。

\n

Android 团队在工作时需要更少的文件集。
\n这意味着他们可以使用git sparse-checkout set命令来限制该目录:

\n
\n
git sparse-checkout init --cone\ngit sparse-checkout set <dir1> <dir2> ...\n
Run Code Online (Sandbox Code Playgroud)\n

https://i2.wp.com/user-images.githubusercontent.com/121322/72286599-50af8e00-35fa-11ea-9025-d7cbb730192c.png?ssl=1

\n
\n

git sparse-checkout自 Git 2.32(2021 年第一季度)起使用稀疏索引\n请参阅Derrick Stolee
的文章“使用 Git\xe2\x80\x99s 稀疏索引让你的 monorepo 感觉很小” 。

\n
\n

稀疏索引在一方面与普通的 \xe2\x80\x9cfull\xe2\x80\x9d 索引不同:它可以存储目录路径及其树对象的对象 ID

\n

这是对与 blob 对象配对的文件路径的补充。

\n

由于锥体模式稀疏检出模式在目录级别上匹配,因此我们可以确定整个目录不在稀疏检出锥体之外,并将其包含的所有文件路径替换为单个目录路径。

\n
\n

https://github.blog/wp-content/uploads/2021/11/Fig-6-sparse-index.png?resize=432%2C314?w=432

\n
\n

稀疏目录条目对应于稀疏签出定义之外的目录。
\n这些目录还有一个缓存树节点,其范围只有一个条目:稀疏目录条目。

\n
\n
\n

在 Git 2.36(2022 年第 2 季度)中,“ git update-index( man )、 " git checkout-index" ( man )和 " git clean" ( man )被教导如何更好地使用稀疏结帐功能。

\n

请参阅提交 b9ca5e2提交 c35e9f5提交 e015d4d、提交35682ad提交 88078f5提交 b553ef6提交 1e9e10e提交 1624333提交 bb01b26(2022 年 1 月 11 日),作者:Victoria Dye ( vdye)
\n (由Junio C Hamano 合并 -- gitster--提交 2f45f3e中,2022 年 2 月 17 日)

\n
\n

update-index:与稀疏索引集成

\n

签署人:Victoria Dye
\n审阅人:Elijah Newren

\n
\n
\n

启用稀疏索引与update-index.
\n大多数update-index工作变体都没有显式扩展索引或在update-index.c.

\n

需要额外更改的一种用法是--cacheinfo;如果指定了稀疏目录中的文件,则直到缓存树失效后索引才会扩展,从而导致索引和缓存树之间不匹配。
\n这种情况是通过重新排列来处理的add_index_entry_with_check,允许在尝试使相关缓存树路径无效之前index_name_stage_pos扩展索引,从而避免缓存树/索引损坏。

\n
\n
\n

使用 Git 2.36(2022 年第 2 季度),可以更好地控制 git 稀疏结帐锥模式。

\n

请参阅Elijah Newren ( )的提交 8dd7c47提交 4ce5043提交 bb8b5e9提交 d526b4d提交 f748012(2022 年 2 月 19 日)。\n (由Junio C Hamano 合并 -- --提交9671764,2022年 3 月 6 日)newren
gitster

\n
\n

sparse-checkout:拒绝圆锥模式中看起来像模式的参数

\n

审阅者:Derrick Stolee
\n签署者:Elijah Newren

\n
\n
\n

sparse-checkout add/setundercone模式下,传递的参数应该是目录而不是gitignore-style模式。

\n

然而,考虑到手册讨论模式所花费的精力,用户很容易认为他们需要传递诸如

\n
/foo/*\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
!/bar/*/\n
Run Code Online (Sandbox Code Playgroud)\n

或者也许他们确实忽略了目录规则并指定了一个随机gitignore-style模式,例如

\n
*.c\n
Run Code Online (Sandbox Code Playgroud)\n

为了帮助捕获此类错误,如果有任何位置参数,请抛出错误:

\n
* starts with any of \'/!\'\n* contains any of \'*?[]\'  \n
Run Code Online (Sandbox Code Playgroud)\n

--skip-checks告知用户,如果他们的目录名称中确实包含此类特殊字符,他们可以通过。
\n(由于稀疏结帐对反斜杠的特殊处理,我们排除了 \'\';请参阅t1091.46 中的 MINGW 测试。

\n
\n

并且,仍然是 2.36:

\n

使用 Git 2.36(2022 年第 2 季度),进一步完善 git稀疏结帐”。

\n

请参阅Elijah Newren ( )的提交 8dd7c47提交 4ce5043提交 bb8b5e9提交 d526b4d提交 f748012(2022 年 2 月 19 日)。\n (由Junio C Hamano 合并 -- --提交9671764,2022年 3 月 6 日)newren
gitster

\n
\n

sparse-checkout: 注意 {set, add} 的前缀

\n

帮助者:Junio Hamano
\n审阅者:Derrick Stolee
\n签署者:Elijah Newren

\n
\n
\n

在cone模式下,set和add的非选项参数显然是路径,因此,我们应该注意前缀。

\n

在非圆锥模式下,由于输入是模式,因此不清楚人们是否打算提供路径gitignore-style
\n注意前缀会阻止人们做类似的事情

\n
git sparse-checkout add /.gitattributes\ngit sparse-checkout add \'/toplevel-dir/*\'\n
Run Code Online (Sandbox Code Playgroud)\n

事实上,前者会导致

\n
fatal: \'/.gitattributes\' is outside repository...\n
Run Code Online (Sandbox Code Playgroud)\n

而后者将导致:

\n
fatal: Invalid path \'/toplevel-dir\': No such file or directory\n
Run Code Online (Sandbox Code Playgroud)\n

尽管事实上这两种模式都是有效的gitignore-style模式,如果添加到稀疏签出文件中,它们都会选择真实的文件。

\n

这可能会导致人们只使用不带前导斜杠的路径,从而可能导致他们在整个目录层次结构中抓取具有相同名称的文件,这与他们的预期相反。
\n另请参阅此线程此线程

\n

添加前缀似乎充满了错误;因此,现在,当从子目录运行稀疏检出集/添加时,只需在非圆锥模式下抛出错误即可。

\n
\n