如何在2.27+中使用git sparse-checkout [英] How to use git sparse-checkout in 2.27+
问题描述
我正尝试从以下步骤中复制一些教程步骤:
I was trying to reproduce the few tutorial steps from:
https://github.blog/2020-01-17-将您的monorepo缩小到带有稀疏签出的尺寸
哪个版本用于git 2.25,但现在在2.27中,运行时什么也没有发生:
Which was made for git 2.25, but now in 2.27, nothing happen at all when running:
$ git sparse-checkout set client/android
我找不到使它起作用的方法.
I can't find a way to make it works.
这是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
使用git 2.25,我获得了一个非空目录:
Using git 2.25, I obtain a non empty directory:
$ ls -a
. .. bootstrap.sh LICENSE.md README.md .git
使用git 2.27,我得到一个空目录:
Using git 2.27, I obtain an empty directory:
$ ls -a
. .. .git
推荐答案
我相信我找到了原因.将 f56f31af0301
提交到Git会更改sparse-checkout
的实现如果未初始化的工作树(如在运行git clone --no-checkout
之后会立即显示的那样),则运行git sparse-checkout init
不会将任何文件检出到工作树中.在以前的版本中,该命令实际上会检出文件,因为此时您没有活动的分支,这可能会产生意想不到的效果.
I believe I found the reason for this. Commit f56f31af0301
to Git changed the implementation of sparse-checkout
so that, when you have an uninitialized working tree (as you would right after running git clone --no-checkout
), running git sparse-checkout init
will not check out any files into your working tree. In previous versions, the command would actually check out files, which could have unexpected effects given that you wouldn't have an active branch at that point.
相关的提交f56f31af0301
包含在Git 2.27中,但未包含在2.25中.这就解释了为什么您看到的行为不是您要遵循的网页上显示的行为的原因.基本上,网页上的行为是当时没有人意识到是一个错误的错误,但是使用Git 2.27时,该错误已得到修复.
The relevant commit, f56f31af0301
was included in Git 2.27, but not in 2.25. That accounts for why the behavior you see is not the behavior shown on the web page you're trying to follow. Basically, the behavior on the web page was a bug that nobody realized was a bug at the time, but with Git 2.27, it has been fixed.
我认为,在提交 b5bfc08a972d
:
This is explained very well, I think, in the message for commit b5bfc08a972d
:
所以...这把我们带到了特殊情况:一个git clone执行
--no-checkout
.根据标志的含义,--no-checkout
不 签出任何分支,这意味着您不在一个分支上, 克隆后需要切换到一个.在实施上,HEAD
是 仍然设置(因此从某种意义上说,您部分处于分支上),但是
So...that brings us to the special case: a git clone performed with
--no-checkout
. As per the meaning of the flag,--no-checkout
does not check out any branch, with the implication that you aren't on one and need to switch to one after the clone. Implementationally,HEAD
is still set (so in some sense you are partially on a branch), but
- 索引是未出生的"(不存在)
- 工作树中没有文件(
.git/
除外) - 下次运行
git switch
(或git checkout
)时,它将运行 将initial_checkout
标志设置为true的unpack_trees.
- the index is "unborn" (non-existent)
- there are no files in the working tree (other than
.git/
) - the next time
git switch
(orgit checkout
) is run it will run unpack_trees withinitial_checkout
flag set to true.
直到您跑步,例如git switch <somebranch>
表示索引
将被写入并填充工作树中的文件.
It is not until you run, e.g. git switch <somebranch>
that the index
will be written and files in the working tree populated.
在这种特殊的--no-checkout
情况下,传统的read-tree -mu HEAD
行为将等同于像checkout
一样行动-
切换到默认分支(HEAD
),写出一个匹配的索引
HEAD
,并更新工作树以使其匹配.这个特例滑倒了
通过原始sparse-checkout
中的避免更改"检查
命令,并在那里继续.
With this special --no-checkout
case, the traditional read-tree -mu HEAD
behavior would have done the equivalent of acting like checkout
--
switch to the default branch (HEAD
), write out an index that matches
HEAD
, and update the working tree to match. This special case slipped
through the avoid-making-changes checks in the original sparse-checkout
command and thus continued there.
在引入和使用update_sparsity()
之后(请参见commit f56f31a
("sparse-checkout: use new update_sparsity() function
",2020-03-27)),
--no-checkout
情况的行为已更改:由于git的
自动保留空的内存索引(请参见do_read_index()
和
请注意,must_exist
为false),并且由于sparse-checkout
update_working_directory()
代码始终在索引之后写出
完成后,我们遇到了一个新错误.这样就使sparse-checkout
从具有未出生"索引(例如,仍然是
需要initial_checkout
),到具有已记录索引但没有索引的索引
条目.因此,不是所有显示在git status
中的文件都已删除
被git称为一种尚未出现在机器上的特殊工件
分支,我们对一个空索引的记录使它突然看起来像git
尽管它肯定在一个分支上,所有文件都已准备好删除!
随后的结帐或转帐必须应对以下事实:
它不是在initial_checkout
上,而是有很多分段删除.
After update_sparsity()
was introduced and used (see commit f56f31a
("sparse-checkout: use new update_sparsity() function
", 2020-03-27)),
the behavior for the --no-checkout
case changed: Due to git's
auto-vivification of an empty in-memory index (see do_read_index()
and
note that must_exist
is false), and due to sparse-checkout
's
update_working_directory()
code to always write out the index after it
was done, we got a new bug. That made it so that sparse-checkout
would
switch the repository from a clone with an "unborn" index (i.e. still
needing an initial_checkout
), to one that had a recorded index with no
entries. Thus, instead of all the files appearing deleted in git status
being known to git as a special artifact of not yet being on a
branch, our recording of an empty index made it suddenly look to git as
though it was definitely on a branch with ALL files staged for deletion!
A subsequent checkout or switch then had to contend with the fact that
it wasn't on an initial_checkout
but had a bunch of staged deletions.
这篇关于如何在2.27+中使用git sparse-checkout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!