我试图从以下几个教程步骤中重现:
https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout
这是为 git 2.25 制作的,但现在在 2.27 中,运行时什么也没有发生:
$ git sparse-checkout set client/android
Run Code Online (Sandbox Code Playgroud)
我找不到让它工作的方法。
这是一个 MWE:
$ git clone --no-checkout https://github.com/derrickstolee/sparse-checkout-example
Cloning into 'sparse-checkout-example'...
$ cd sparse-checkout-example/
$ git sparse-checkout init --cone
Run Code Online (Sandbox Code Playgroud)
使用 git 2.25,我获得了一个非空目录:
$ ls -a
. .. bootstrap.sh LICENSE.md README.md .git
Run Code Online (Sandbox Code Playgroud)
使用 git 2.27,我获得了一个空目录:
$ ls -a
. .. .git
Run Code Online (Sandbox Code Playgroud)
我相信我找到了原因。Commit f56f31af0301to Git 更改了 的实现,sparse-checkout因此,当您有一个未初始化的工作树时(就像您在运行后一样git clone --no-checkout),运行git sparse-checkout init时不会将任何文件检出到您的工作树中。在以前的版本中,该命令实际上会检出文件,这可能会产生意想不到的效果,因为此时您没有活动分支。
相关提交f56f31af0301包含在 Git 2.27 中,但未包含在 2.25 中。这解释了为什么您看到的行为不是您试图遵循的网页上显示的行为。基本上,网页上的行为是一个错误,当时没有人意识到这是一个错误,但在 Git 2.27 中,它已被修复。
我认为,在提交的消息中对此进行了很好的解释b5bfc08a972d:
所以......这给我们带来了特殊情况:使用 .git 执行的 git clone
--no-checkout。根据标志的含义,--no-checkout不检查任何分支,这意味着您不在一个分支上,需要在克隆后切换到一个分支。在实现上,HEAD仍然是设置的(所以在某种意义上你是部分在一个分支上),但是
- 索引是“未出生的”(不存在)
- 工作树中没有文件(除了
.git/)- 下一次
git switch(或git checkout)运行时,它将运行 unpack_trees 并将initial_checkout标志设置为 true。直到您运行,例如
git switch <somebranch>才会写入索引并填充工作树中的文件。在这种特殊
--no-checkout情况下,传统read-tree -mu HEAD行为会执行类似的操作checkout——切换到默认分支 (HEAD),写出匹配的索引HEAD,然后更新工作树以进行匹配。这种特殊情况没有通过原始sparse-checkout命令中的避免更改检查,因此在那里继续进行。在
update_sparsity()引入和使用之后(参见 commitf56f31a("sparse-checkout: use new update_sparsity() function", 2020-03-27)),--no-checkout案例的行为发生了变化:由于 git 对空内存索引的自动激活(参见do_read_index()并注意这must_exist是错误的),以及由于sparse-checkout的update_working_directory()代码总是在完成后写出索引,我们得到了一个新错误。这使得它可以sparse-checkout将存储库从具有“未出生”索引(即仍然需要initial_checkout)的克隆切换到具有没有条目的记录索引的克隆。因此,而不是所有文件出现在git status被 git 称为尚未在分支上的特殊工件,我们对空索引的记录使它突然看起来 git 好像它确实在一个分支上,所有文件都暂存待删除!随后的结帐或切换不得不面对这样一个事实,即它不在一个initial_checkout但有一堆分阶段删除。
| 归档时间: |
|
| 查看次数: |
2027 次 |
| 最近记录: |