now*_*wox 4 git git-submodules git-sparse-checkout
有很多关于稀疏结账的文章和问题。不幸的是我没有找到具体的例子。我想让以下示例工作:
cd ~
mkdir sub && cd $_
git init
mkdir foo && touch $_/foo
mkdir bar && touch $_/bar
git add .
git commit -am "Initial commit"
Run Code Online (Sandbox Code Playgroud)
cd ~
mkdir project && cd $_
git init
git submodule add ../sub sub
git config -f .gitmodules submodule.sub.shallow true
git config -f .gitmodules submodule.sub.sparsecheckout true
echo foo/* > .git/modules/sub/info/sparse-checkout
git commit -am "Initial commit"
git submodule update
cd sub
git checkout .
Run Code Online (Sandbox Code Playgroud)
在这一点上,我希望sub文件夹只包含foo/foonot bar。不幸的是它不起作用:
$ ls
bar/ foo/
Run Code Online (Sandbox Code Playgroud)
我怎样才能让它工作?
从 Git 2.25(2020 年第一季度)开始,您将使用新命令git sparse-checkout
sparse checkout在 Git 2.28(2020 年第 3 季度)中,记录了设置对子模块的影响。
这意味着,如果您使主存储库本身稀疏地检出,除了子模块(已经稀疏,如 max630 的答案),git sparse-checkout在主存储库上使用不会对子模块产生负面影响(即,在有工作时错误地删除它)方面取得进展)。
请参阅Elijah Newren ( )的提交 e7d7c73(2020 年 6 月 10 日)。(由Junio C Hamano 合并 -- --在提交 81be89e中,2020 年 6 月 22 日)newren
gitster
git-sparse-checkout:澄清与子模块的交互签署人:Elijah Newren
审阅人:Derrick Stolee
暂时忽略稀疏签出功能,如果有一个子模块并在其中使用未推送的更改创建本地分支,并且可能向其中添加一些未跟踪的文件,那么我们希望避免意外删除这样的子模块。
因此,例如使用git.git,如果您运行
Run Code Online (Sandbox Code Playgroud)git checkout v2.13.0那么 sha1collisiondetection/ 子模块不会被删除,即使它直到 v2.14.0 才作为子模块存在。
同样,如果您之前只签出 v2.13.0 并运行
Run Code Online (Sandbox Code Playgroud)git checkout v2.14.0尽管 sha1collisiondetection/ 子模块是 v2.14.0 的一部分,但它不会自动初始化。
在这两种情况下,git 都需要单独初始化或取消初始化子模块。
此外,我们还对其他命令中的子模块进行了特殊处理,例如 clean,它需要两个
--force标志来删除未跟踪的子模块,并且某些命令具有--recurse-submodules标志。稀疏签出与签出非常相似,正如相似的名称所证明的那样——它在工作副本中添加和删除文件。
然而,出于同样避免数据丢失的原因,我们不想通过签出从工作副本中删除子模块,我们也不想通过稀疏签出来做到这一点。
所以子模块需要单独初始化或取消初始化;更改稀疏检出规则不应自动触发子模块的删除或激活。
我相信之前关于子模块的措辞
git sparse-checkout只是关于这个特定问题。不幸的是,前面的措辞可能被解释为暗示无论稀疏模式如何,子模块都应被视为活动的。
更新措辞以避免产生这样的暗示。
考虑两个示例情况可能会有所帮助,其中措辞差异变得很重要:
将来,我们希望用户能够运行类似的命令
Run Code Online (Sandbox Code Playgroud)git clone --sparse=moduleA --recurse-submodules $REPO_URL并自动设置稀疏路径并自动初始化稀疏路径内的子模块。
我们不希望使用该命令自动初始化任何路径中的所有子模块。
同样,我们希望能够做类似的事情
Run Code Online (Sandbox Code Playgroud)git -c sparse.restrictCmds grep --recurse-submodules $REV $PATTERN并在记录的稀疏模式中
$REV进行搜索。$PATTERN我们希望它递归到这些稀疏模式内的子模块,但不希望递归到与稀疏模式不匹配的目录来搜索可能的子模块。
所以文档现在包括:
如果您的存储库包含一个或多个子模块,则会根据与
git submodule命令的交互来填充子模块。
具体来说,git submodule init -- <path>将确保子模块 at<path>存在,同时git submodule deinit [-f] -- <path>将删除子模块 at 的文件<path>(包括任何未跟踪的文件、未提交的更改和未推送的历史记录)。
类似于稀疏签出从工作树中删除文件但仍然在索引中保留条目的方式,取消初始化的子模块将从工作目录中删除,但在索引中仍然有一个条目。由于子模块可能有未推送的更改或未跟踪的文件,删除它们可能会导致数据丢失。
因此,更改稀疏包含/排除规则不会导致已检出的子模块从工作副本中删除。
换句话说,就像即使checkout在删除或添加子模块的分支之间切换时也不会导致子模块自动删除或初始化一样,使用sparse-checkout减少或扩大“有趣”文件的范围也不会导致子模块自动取消初始化或初始化。此外,上述事实意味着“跟踪”文件可能不存在于工作副本中的原因有多种:稀疏检出的稀疏模式应用程序和子模块初始化状态。
因此,类似git grep对工作副本中的跟踪文件进行操作的命令可能会返回受这两个限制中的一个或两个限制的结果。
在 Git 2.31(2021 年第一季度)中,“ git grep” ( man )已被调整为仅限于稀疏的签出路径。
由于您可能需要git grep稀疏检出子模块,因此这一点很重要。
请参阅Matheus Tavares ( )的提交 42d906b(2021 年 2 月 9 日)。(由Junio C Hamano 合并 -- --在提交 628c13c中,2021 年 2 月 25 日)matheustavares
gitster
grep:尊重工作树搜索的稀疏结帐建议人:Elijah Newren
签署人:Matheus Tavares
审核人:Elijah Newren
在稀疏签出的存储库上,当条目与搜索路径规范匹配并设置了位时, ( man )(没有)最终会搜索缓存。
git grep--cachedSKIP_WORKTREE这令人困惑,因为稀疏路径预计不会出现在工作树搜索中(因为它们没有被签出),而且因为输出混合了工作树和缓存结果而不区分它们。
(请注意,grep在包含路径的工作树搜索中也会诉诸缓存--assume-unchanged。
但这种情况下的重点是假设索引条目和文件的内容相同。
这不适用于稀疏路径的情况,该文件甚至不应该存在。)通过教 grep 遵守工作树搜索的稀疏检出规则来解决这个问题。
如果用户想要 grep 当前稀疏检出定义之外的路径,他们可以更新稀疏规则以具体化文件,或者用于--cached搜索索引中注册的所有 blob。
并且,仍然对于稀疏签出的子模块:
在 Git 2.39(2022 年第 4 季度)中,“ git grep” ( man )学会了在稀疏结帐中更加懒惰地按需扩展稀疏索引。
请参阅由Shaoxuan Yuan ( )提交的提交 7cae762(2022 年 9 月 22 日)。(由Junio C Hamano 合并 -- --在提交 67bf4a8中,2022 年 10 月 10 日)ffyuanda
gitster
builtin/grep.c:与稀疏索引集成建议人:Derrick Stolee
帮助人:Derrick Stolee
帮助人:Victoria Dye
帮助人:Elijah Newren
签字人:少轩袁
打开稀疏索引并删除
ensure_full_index().在这个补丁之前,
git-grep利用ensure_full_index()扩展索引的方法来搜索所有条目。
由于该方法需要遍历所有树并构建索引,因此它是整个命令中最慢的部分。为了获得更好的性能,这个补丁使用了
grep_tree()搜索稀疏目录项并摆脱的ensure_full_index()方法。为什么
grep_tree()是更好的选择呢ensure_full_index()?
grep_tree()与 一样正确ensure_full_index()。
grep_tree()在循环索引时递归地查看每个稀疏目录条目(由树表示),并且这样做的结果与扩展索引的结果相匹配。
grep_tree()利用路径规范来限制搜索范围。
ensure_full_index()总是扩展索引,这意味着它总是会遍历存储库中的所有树和 blob,而不关心用户是否只想要内容的子集,即使用路径规范。
另一方面,grep_tree()只会搜索与路径规范匹配的内容,因此可能会遍历更少的树。
grep_tree()不会构造并复制回新索引,而ensure_full_index()会。这也节省了一些时间。
git submodule add 本身检查子模块。
对我来说成功的是:
git init
# I did not find a way to add submodule in 1 step without checking out
git clone --depth=1 --no-checkout ../sub sub
git submodule add ../sub sub
git submodule absorbgitdirs
# note there is no "submodule.sub.sparsecheckout" key
git -C sub config core.sparseCheckout true
# note quoted wildcards to avoid their expansion by shell
echo 'foo/*' >>.git/modules/sub/info/sparse-checkout
git submodule update --force --checkout sub
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3132 次 |
| 最近记录: |