根据这个线程,应该实现Gitsparse-checkout
功能中的排除。是吗?
假设我有以下结构:
papers/
papers/...
presentations/
presentations/heavy_presentation
presentations/...
现在我想presentations/heavy_presentation
从结帐中排除,而将其余部分留在结帐中。我还没有设法让它运行。什么是正确的语法?
根据这个线程,应该实现Gitsparse-checkout
功能中的排除。是吗?
假设我有以下结构:
papers/
papers/...
presentations/
presentations/heavy_presentation
presentations/...
现在我想presentations/heavy_presentation
从结帐中排除,而将其余部分留在结帐中。我还没有设法让它运行。什么是正确的语法?
遗憾的是,上述方法都不适合我,所以我花了很长时间尝试不同的sparse-checkout
文件组合。
就我而言,我想跳过带有 IntelliJ IDEA 配置的文件夹。
这是我所做的:
跑git clone https://github.com/myaccount/myrepo.git --no-checkout
跑git config core.sparsecheckout true
.git\info\sparse-checkout
使用以下内容创建
!.idea/*
!.idea_modules/*
/*
运行 'git checkout --' 以获取所有文件。
使其工作的关键是/*
在文件夹名称之后添加。
我有 git 1.9
我本来希望像下面这样的工作:
/*
!presentations/heavy_presentation
但事实并非如此。我确实尝试了许多其他组合。我认为排除没有正确实施,并且周围存在错误(仍然)
就像是:
presentations/*
!presentations/heavy_presentation
确实有效,您将获得没有heavy_presentation文件夹的演示文件夹。
因此,解决方法是明确包含其他所有内容。
我有同样的问题。我用类似的东西修复了它:
!presentations/heavy_presentation
presentations/*
我如何理解它的工作原理:它逐条读取文件规则。如果包含某些内容,它将包含包含该单词的所有路径,并且在稀疏结帐结束之前它不会再更改其状态。如果您在包含之前添加排除规则,我认为它将首先删除文件,然后将所有文件标记为包含。
我不完全确定,这是我根据我的经验所设想的并且一直在为我工作。我希望它会帮助某人。
借助 Git 2.25(2020 年第一季度),稀疏签出工作树的管理获得了专用的“ sparse-checkout
”命令。
首先,这是一个扩展示例,从使用选项的快速克隆--filter
开始:
git clone --filter=blob:none --no-checkout https://github.com/git/git
cd git
git sparse-checkout init --cone
# that sets git config core.sparseCheckoutCone true
git read-tree -mu HEAD
使用锥形选项(详细/记录在下面)意味着您.git\info\sparse-checkout
将包含以下模式:
/*
!/*/
含义:只有顶级文件,没有子文件夹。
如果你不想要top file,你需要避免cone模式:
# Disablecone mode in .git/config.worktree
git config core.sparseCheckoutCone false
# remove .git\info\sparse-checkout
git sparse-checkout disable
# Add the expected pattern, to include just a subfolder without top files:
git sparse-checkout set /mySubFolder/
# populate working-tree with only the right files:
git read-tree -mu HEAD
详细说明:
(在Derrick Stolee的“让你的 monorepo 缩小规模sparse-checkout
”中
查看更多信息)
因此,不仅排除子文件夹确实有效,而且使用稀疏结帐的“锥形”模式(使用 Git 2.25)可以更快地工作。
请参阅Ed Maste ( ) 的提交 761e3d2(2019 年 12 月 20 日)。
请参阅提交 190a65f(2019 年 12 月 13 日),并提交 cff4e91、提交 416adc8、提交 f75a69f、提交 fb10ca5、提交 99dfa6f、提交 e091228、提交 e9de487、提交4dcd4de、提交 eb42fec、提交 af09ce2、提交 79321e 8、提交7、提交7 7bffca9,提交 f6039a9,emaste
提交 d89f09c,提交 bab3c35,提交 94c0956(2019 年 11 月 21 日),由Derrick Stolee ( derrickstolee
)。
请参阅Jeff Hostetler ( ) 的提交 e6152e3(2019 年 11 月 21 日)。(由Junio C Hamano 合并 -- --在提交 bd72a08中,2019 年 12 月 25 日)Jeff-Hostetler
gitster
sparse-checkout
:添加“锥形”模式签字人:Derrick Stolee
随着索引中模式数量和条目数量的增长,稀疏签出功能可以具有二次性能。
如果有 1,000 个模式和 1,000,000 个条目,那么这个时间可能非常重要。创建一个新的布尔配置选项core.sparseCheckoutCone,以指示我们希望稀疏结帐文件包含一组更有限的模式。
这是一个单独的配置设置,core.sparseCheckout
通过引入三态选项来避免破坏旧客户端。
config
手册页包括:
`core.sparseCheckoutCone`:
启用稀疏结帐功能的“锥形模式”。
当 sparse-checkout 文件包含一组有限的模式时,这种模式提供了显着的性能优势。
锥形图案集
完整的模式集允许任意模式匹配和复杂的包含/排除规则。
这些可能会在O(N*M)
更新索引时导致模式匹配,其中N
是模式M
数,是索引中的路径数。为了解决这个性能问题,启用时允许使用更受限制的模式集core.spareCheckoutCone
。锥形模式集中接受的模式是:
- 递归:包含目录内的所有路径。
- 父级:包含一个目录中的所有文件。
除了上述两种模式外,我们还期望根目录下的所有文件都包括在内。如果添加了递归模式,则所有前导目录都将添加为父模式。
默认情况下,运行时
git sparse-checkout init
,将根目录添加为父模式。此时,sparse-checkout 文件包含以下模式:/* !/*/
这表示“在根目录中包含所有内容,但在根目录下没有两层”。
如果我们随后将文件夹添加A/B/C
为递归模式,则文件夹A
和A/B
添加为父模式。
生成的稀疏签出文件现在是/* !/*/ /A/ !/A/*/ /A/B/ !/A/B/*/ /A/B/C/
在这里,顺序很重要,因此负面模式会被文件中较低的正面模式覆盖。
如果
core.sparseCheckoutCone=true
,则 Git 将解析期望这些类型的模式的稀疏签出文件。
如果模式不匹配,Git 会发出警告。
如果模式确实与预期格式匹配,那么 Git 将使用更快的基于哈希的算法来计算sparse-checkout
.
所以:
sparse-checkout
:初始化并设置为锥形模式协助人:Eric Wong
协助人:Johannes Schindelin
签字人:Derrick Stolee
为了使圆锥模式集易于使用,请更新 '
git sparse-checkout (init|set)
' 的行为。将 '
--cone
' 标志添加到 'git sparse-checkout init
' 以设置配置选项 'core.sparseCheckoutCone=true
'。在锥形模式下运行“
git sparse-checkout set
”时,用户只需提供递归文件夹匹配列表。Git 将自动为前导目录添加必要的父匹配项。
请注意,该--cone
选项仅记录在 Git 2.26(2020 年第一季度)中
(由Junio C Hamano 合并gitster
——在提交 ea46d90中,2020 年 2 月 5 日)
doc
::sparse-checkout
提及--cone
选项签字人:Matheus Tavares
签字人:Derrick Stolee
在af09ce2 ("
sparse-checkout
: init and set in cone mode", 2019-11-21, Git v2.25.0-rc0 -- merge ) 中,'--cone
' 选项被添加到 'git sparse-checkout
init' 中。将其记录在
git sparse-checkout
:
包括:
当
--cone
提供时,core.sparseCheckoutCone
设置也被设置,允许使用有限的一组模式获得更好的性能。
(上面介绍的“一组模式”,在CONE PATTERN SET
这个答案的“”部分)
这种新的“锥形”模式会快多少?
sparse-checkout
: 对锥形模式使用哈希图协助人:Eric Wong
协助人:Johannes Schindelin
签字人:Derrick Stolee
sparse-checkout 中的“锥形模式”选项允许的父模式和递归模式具有足够的限制性,我们可以避免使用正则表达式解析。一切都基于前缀匹配,因此我们可以使用哈希集来存储稀疏签出文件中的前缀。检查路径时,我们可以从路径中删除路径条目并检查哈希集是否完全匹配。
作为测试,我为 Linux 存储库创建了一个锥形模式稀疏签出文件,该文件实际上包含每个文件。这是通过获取 Linux 存储库中的每个文件夹并在此处创建模式对来构建的:
/$folder/ !/$folder/*/
这导致了一个稀疏的签出文件 sith 8,296 个模式。
在此文件上运行“git read-tree -mu HEAD”具有以下性能:core.sparseCheckout=false: 0.21 s (0.00 s) core.sparseCheckout=true : 3.75 s (3.50 s) core.sparseCheckoutCone=true : 0.23 s (0.01 s)
根据性能跟踪,上面括号中的时间对应于第一次
clear_ce_flags()
调用所花费的时间。trace2
虽然此示例是人为设计的,但它演示了这些模式如何减慢稀疏结帐功能。
和:
sparse-checkout
:尊重 core.ignoreCase 在锥模式签字人:Derrick Stolee
当用户在锥形模式下使用稀疏检出功能时,他们使用“”添加模式
git sparse-checkout set <dir1> <dir2> ...
或使用“--stdin
”在标准输入上逐行提供目录。
这种行为自然看起来很像用户键入“git add <dir1> <dir2> ...
”的方式如果
core.ignoreCase
启用,则“git add
”将使用不区分大小写的匹配来匹配输入。
对该功能执行相同的sparse-checkout
操作。在更新跳过工作树位时执行不区分大小写的检查
unpack_trees()
。这是通过更改散列算法和散列映射比较方法以可选地使用不区分大小写的方法来完成的。启用此选项后,散列算法的性能成本会很小。
为了梳理出最坏的情况,以下是在具有深层目录结构的 repo 上运行的:git ls-tree -d -r --name-only HEAD | git sparse-checkout set --stdin
'set' 命令被定时
core.ignoreCase
禁用或启用。
对于历史悠久的回购,数字是core.ignoreCase=false: 62s core.ignoreCase=true: 74s (+19.3%)
为了重现性,Linux 内核存储库上的等效测试具有以下数字:
core.ignoreCase=false: 3.1s core.ignoreCase=true: 3.6s (+16%)
现在,这并不是一个完全公平的比较,因为大多数用户将使用更浅的目录来定义他们的稀疏锥体,以及eb42feca97的性能改进(“unpack-trees: hashless in cone mode”2019-11-21,Git 2.25- rc0) 可以消除大部分哈希成本。要进行更实际的测试,请
-r
从ls-tree
命令中删除“”以仅存储第一级目录。
在这种情况下,Linux 内核存储库在每种情况下都需要 0.2-0.25 秒,而深层存储库在每种情况下都需要 1 秒,正负 0.05 秒。因此,我们可以证明这种变化的成本,但它对任何合理的稀疏结账锥都不重要。
在 Git 2.25(2020 年第一季度)中,“ git sparse-checkout
list”子命令学会了在“锥形”模式生效时以更简洁的形式给出其输出。
请参阅Derrick Stolee ( ) 的提交 4fd683b和提交 de11951(2019 年 12 月 30 日)。(由Junio C Hamano 合并 -- --在提交 c20d4fd中,2020 年 1 月 6 日)derrickstolee
gitster
sparse-checkout
: 以锥形模式列出目录签字人:Derrick Stolee
core.sparseCheckoutCone
启用后,“ ”git sparse-checkout set
命令将目录列表作为输入,然后创建稀疏签出模式的有序列表,以便递归包含这些目录,并且还包含父目录中的所有同级条目。
列出模式不如目录本身对用户友好。在锥形模式下,只要模式与预期的锥形模式类型匹配,就可以将 '
git sparse-checkout list
' 的输出更改为仅显示创建模式的目录。通过此更改,以下管道命令不会更改工作目录:
git sparse-checkout list | git sparse-checkout set --stdin
唯一不起作用的情况是 if
core.sparseCheckoutCone
istrue
,但 sparse-checkout 文件包含的模式与锥形模式的预期模式类型不匹配。
最近在此版本中添加的代码以在稀疏锥模式下移动到索引中同一目录中的条目之外的条目,没有计算错误跳过的条目数,已在 Git 2.25.1 中更正(2020 年 2 月)。
请参阅Junio C Hamano ( ) 的提交 7210ca4(2020 年 1 月 27 日)。
请参阅Derrick Stolee 通过 GitGitGadget (``)提交的 4c6c797(2020 年 1 月 10 日) 。(由Junio C Hamano 合并 -- --在提交 043426c中,2020 年 1 月 30 日)gitster
gitster
unpack-trees
:正确计算结果计数报告人:Johannes Schindelin
签字人:Derrick Stolee
该
clear_ce_flags_dir()
方法处理公共目录中的缓存条目。返回int
的是该目录处理的缓存条目数。
在锥模式下使用稀疏签出功能时,我们可以跳过完全包含或完全排除的目录中的条目的模式匹配。eb42feca ("
unpack-trees
: hash less in cone mode", 2019-11-21, Git v2.25.0-rc0 -- merge列在批次 #0中) 引入了这个性能特性。旧机制依赖于调用返回的计数,但新机制通过从“”中减去“ ”来clear_ce_flags_1()
计算行数以找到范围的大小。 但是,方程是错误的,因为它除以。这不是指针算术的工作原理!cache_end
cache
sizeof(struct cache_entry *)
为 2.25.0 版本做准备的适用于 Windows 的 Git 的覆盖构建发现此问题并带有警告:
Pointer differences, such as `cache_end` - cache, are automatically scaled down by the size (8 bytes) of the pointed-to type (struct `cache_entry` *). Most likely, the division by sizeof(struct `cache_entry` *) is extraneous and should be eliminated.
这个警告是正确的。
这给我们留下了一个问题“这甚至是如何工作的?”
这种不正确的指针算法出现的问题是一个仅性能错误,而且是一个非常轻微的错误。
由于返回的条目计数clear_ce_flags_dir()
减少了 8 倍,循环 inclear_ce_flags_1()
将重新处理来自这些目录的条目。通过将全局计数器插入
unpack-tree.c
并跟踪它们trace2_data_intmax()
(在私有更改中,用于测试),我能够看到内部循环clear_ce_flags_1()
处理条目的次数和clear_ce_flags_dir()
调用次数。
随着当前的变化,这些中的每一个都至少减少了 8 倍。
当重复多个级别的目录时,会发生大于 8 的因子。具体来说,在 Linux 内核 repo 中,命令
git sparse-checkout set LICENSES
将工作目录限制为仅位于根目录和 LICENSES 目录中的文件。
以下是测量的计数:
clear_ce_flags_1
循环块:Before: 11,520 After: 1,621
clear_ce_flags_dir
调用:Before: 7,048 After: 606
虽然这些都是惊人的数字,但
clear_ce_flags_1()
在每种情况下花费的时间都在 1 毫秒以下,因此无法将改进作为端到端时间来衡量。
在 Git 2.26(2020 年第一季度)中,稀疏结账功能中的一些粗糙边缘,尤其是在锥形模式周围,已被清理干净。
请参阅提交F998A3F,提交E53FFF2,提交E55682E,提交BD64DE4 ,提交D585F0E,Commit 4F52C2C,Commit 9ABC60F(Commit 9E6D3E6,Commit 41DE0C6 ,Commit 47DBF10 ,提交3C75406,提交D622C34,提交D622C34 ,提交D622C34,提交D622C34,提交D622C34,提交D622C25F4 2020 年 1 月),由Derrick Stolee ( derrickstolee
)撰写。
请参阅Jeff King ( ) 的提交 7aa9ef2(2020 年 1 月 24 日)。(合并于peff
Junio C Hamano -- gitster
--在提交 433b8aa中,2020 年 2 月 14 日)
sparse-checkout
:修复锥模式行为不匹配报告人:Finn Bryant
签字人:Derrick Stolee
稀疏检出功能中特殊的“锥形模式”的目的是始终匹配与禁用锥形模式时相同的稀疏检出文件匹配的相同模式。
当在锥形模式中将文件路径提供给“
git sparse-checkout
设置”时,锥形模式会不正确地将文件匹配为递归路径。
设置跳过工作树位时,文件不期望MATCHED_RECURSIVE
响应,因此这些被排除在匹配的锥体之外。通过检查以及添加防止回归的测试
MATCHED_RECURSIVE
来修复此错误。MATCHED
该文档现在包括:
启用后
core.sparseCheckoutCone
,输入列表被视为目录列表,而不是稀疏签出模式。
该命令将模式写入 sparse-checkout 文件以包括包含在这些目录中的所有文件(递归地)以及作为祖先目录的兄弟的文件。
输入格式与输出相匹配git ls-tree --name-only
。这包括将以双引号 ( ) 开头的路径名解释"
为 C 风格的带引号的字符串。
在 Git 2.26(2020 年第一季度)中,“ git sparse-checkout
”学习了一个新的“ add
”子命令。
请参阅Derrick Stolee ( ) 的提交6c11c6a ( 2020 年 2 月 20 日)和提交 ef07659、提交 2631dc8、提交 4bf0c06、提交 6fb705a(2020 年 2 月 11 日)。(由Junio C Hamano 合并 -- --在提交 f4d7dfc中,2020 年 3 月 5 日)derrickstolee
gitster
sparse-checkout
:创建“添加”子命令签字人:Derrick Stolee
使用稀疏结账功能时,用户可能希望逐步增长其稀疏结账模式集。
允许使用新的“添加”子命令添加模式。这与 'set' 子命令没有太大区别,因为我们仍然希望允许 '
--stdin
' 选项并在锥体模式下将输入解释为目录,否则将其解释为模式。在圆锥模式下,我们正在增长圆锥。当已经是锥体中的目录时
,这实际上可以减少添加目录A
时的模式集。A/B
测试不同的案例:兄弟姐妹、父母、祖先。当不处于锥形模式时,我们只能假设模式应该附加到 sparse-checkout 文件中。
和:
sparse-checkout
: 使用 Windows 路径签字人:Derrick Stolee
使用 Windows 时,用户可以将“ A/B/C”运行到他们的稀疏结帐模式。
git sparse-checkout
set A\B\C' to add the Unix-style path
在我们将字符串 '
A/B/C
' 添加到递归哈希集之前,规范化输入路径会将反斜杠转换为斜杠。
稀疏签出模式长期以来一直被禁止排除所有路径,留下一棵空的工作树。
在 Git 2.27(2020 年第二季度)中,这一限制已被解除。
请参阅Derrick Stolee ( ) 的提交 ace224a(2020 年 5 月 4 日)。(由Junio C Hamano 合并 -- --在提交 e9acbd6中,2020 年 5 月 8 日)derrickstolee
gitster
sparse-checkout
:停止阻止空工作目录报告人:Lars Schneider
签字人:Derrick Stolee
删除更新稀疏结帐时的错误条件会留下一个空的工作目录。
此行为是在9e1afb167中添加的(“稀疏结帐:禁止空工作树”,2009-08-20,Git v1.7.0-rc0 --合并)。
该评论已添加到a7bc906f2中(“添加解释为什么我们不允许稀疏结帐到空工作树”,2011-09-22,Git v1.7.8-rc0 --合并)以响应84563a624中的“可疑”评论(“
[
unpack-trees.c](https
://github.com/git/git/blob/ace224ac5fb120e9cae894e31713ab60e91f141f/unpack-trees.c):外观修复”,2010-12-22,Git v1.7.5-rc0 --合并)。使用最近的“cone mode”和“
git sparse-checkout init [--cone]
”命令,设置合理的sparse-checkout模式集是很常见的/* !/*/
仅匹配根目录下的文件。如果存储库没有此类文件,则它们的“
git sparse-checkout init
”命令将失败。现在我们希望这是一种常见的模式,我们不应该让命令在空工作目录上失败。
如果这是一个令人困惑的结果,那么用户可以用“git sparse-checkout disable
”或“git sparse-checkout set
”恢复。这在使用锥形模式时尤其简单。
简短的回答:
git sparse-checkout set /* !/presentations/heavy_presentation/
git sparse-checkout init [--cone]
--cone
选项:仅与少数模式/小型回购无关,但通常用于加速。sparse-checkout
需要/CONE PATTERN SET
文档中解释的模式的某种规范顺序)。稍后也可以通过以下方式介绍:
git config core.sparseCheckoutCone true