如何在2.27+中使用git sparse-checkout [英] How to use git sparse-checkout in 2.27+

查看:152
本文介绍了如何在2.27+中使用git sparse-checkout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试从以下步骤中复制一些教程步骤:

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 (or git checkout) is run it will run unpack_trees with initial_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆