6

根据Subdirectory Checkouts with git sparse-checkoutgit read-tree -mu HEAD在已经存在的存储库的情况下配置稀疏检出后调用一次,即:

# Enable sparse-checkout:
git config core.sparsecheckout true

# Configure sparse-checkout 
echo some/dir/ >> .git/info/sparse-checkout
echo another/sub/tree >> .git/info/sparse-checkout

# Update your working tree:
git read-tree -mu HEAD
  • 你能read-tree更详细地解释一下这个步骤吗?
  • 它是如何工作的?
  • 到底是怎么回事?
  • 为什么一个人使用read-tree而不是,让我们说,checkout
  • 为什么要使用-mu(为什么这是合并,以及合并了什么)?

-m

    Perform a merge, not just a read. The command will refuse to run if
    your index file has unmerged entries, indicating that you have not
    finished previous merge you started.

-u

    After a successful merge, update the files in the work tree with the
    result of the merge.
4

1 回答 1

3

借助 Git 2.25(2020 年第一季度),稀疏签出工作树的管理获得了专用的“稀疏签出”命令。
它引入了一个锥形模式(我在“ Git sparse checkout with exclude ”中有详细介绍),这将使sparse-checkout必须更快。

但它也间接描述了为什么git read-tree -mu HEAD使用(或者,使用新的“锥形”模式

请参阅Jeff Hostetler ( ) 的提交 e6152e3(2019 年 11 月 21 日。 请参阅Ed Maste ( ) 的提交 761e3d2(2019 年 12 月 20 日。 请参阅提交 190a65f(2019 年 12 月 13 日),并提交 cff4e91提交 416adc8提交 f75a69f提交 fb10ca5提交 99dfa6f提交 e091228提交 e9de487提交 4dcd4de 提交eb42fec、提交 af09ce2 、提交 96cc8ab 、8提交Jeff-Hostetler
emaste
提交 72918c1提交 7bffca9提交 f6039a9提交 d89f09c提交 bab3c35提交 94c0956(2019 年 11 月 21 日),作者Derrick Stolee ( derrickstolee)
(由Junio C Hamano 合并 -- gitster--提交 bd72a08中,2019 年 12 月 25 日)

sparse-checkout: 在进程中更新工作目录

签字人:Derrick Stolee

sparse-checkout builtin 使用 ' git read-tree -mu HEAD' 来更新索引中的 skip-worktree 位并更新工作目录。
这个额外的过程过于复杂,并且容易失败。它还要求我们在尝试更新索引之前将更改写入 sparse-checkout 文件。

unpack_trees()通过以与 ' ' 相同的方式创建直接调用来删除这个额外的进程调用git read-tree -mu HEAD
此外,提供内存中的模式列表,这样我们就可以避免从 sparse-checkout 文件中读取。这允许我们在写入文件之前测试对文件的提议更改。

此补丁的早期版本包含一个错误,当“ set”命令由于“稀疏签出在工作目录上没有条目”错误而失败时。
它不会回滚index.lock文件,因此旧的 sparse-checkout 规范的重放将失败。t1091 中的测试现在涵盖了该场景。


而且,使用 Git 2.27(2020 年第二季度),“ sparse-checkout”知道如何重新应用自己:

参见提交5644CA2提交681C637提交EBB568B提交22AB0B3提交6271D77提交1AC83F4提交CD002C1 ,CODS 4EE5D50,提交F56F31A提交7AF7A25 ,提交7AA25提案30EE89C1 ,提交3cc7c50 commit 3cc7c50 compes b0433312222adad7dc1e1提交 031ba55(2020 年 3 月 27 日),作者Elijah Newren ( newren)
(由Junio C Hamano 合并 -- gitster--提交 48eee46中,2020 年 4 月 29 日)

sparse-checkout: 提供一个新的重新应用子命令

审核人:Derrick Stolee
签字人:Elijah Newren

如果像 merge 或 rebase 这样的命令将文件具体化作为其工作的一部分,或者之前的 sparse-checkout 命令由于脏更改而未能更新单个文件,用户可能希望命令简单地“重新应用”稀疏规则。

提供一份。

更新git sparse-checkout手册页现在包括:

reapply

将稀疏模式规则重新应用于工作树中的路径。

命令喜欢mergerebase可以实现路径以完成其工作(例如,为了向您显示冲突),而其他稀疏检出命令可能无法稀疏化单个文件(例如,因为它具有未暂存的更改或冲突)。

git sparse-checkout reapply在这种情况下,在清理受影响的路径(例如解决冲突、撤消或提交更改等)之后再运行是有意义的。


但是,在 Git 2.27 中,它不再使用以下方式重新应用/更新自身git read-tree

参见提交5644CA2提交681C637提交EBB568B提交22AB0B3提交6271D77提交1AC83F4提交CD002C1 ,CODS 4EE5D50,提交F56F31A提交7AF7A25 ,提交7AA25提案30EE89C1 ,提交3cc7c50 commit 3cc7c50 compes b0433312222adad7dc1e1提交 031ba55(2020 年 3 月 27 日),作者Elijah Newren ( newren)
(由Junio C Hamano 合并 -- gitster--提交 48eee46中,2020 年 4 月 29 日)

unpack-trees: 添加新update_sparsity()功能

审核人:Derrick Stolee
签字人:Elijah Newren

SKIP_WORKTREE以前,为各种路径更新位的唯一方法是调用git read-tree -mu HEAD或调用此代码路径调用的相同代码。

但是,如果索引或工作目录不干净,则会出现许多问题。

首先,让我们考虑一下这种情况:

Flipping SKIP_WORKTREE -> !SKIP_WORKTREE (materializing files)

如果工作树是干净的,这很好,但如果有文件或目录或符号链接或给定路径中已经存在的任何内容,则操作将因错误而中止。

让我们标记这个案例以供以后讨论:

  • A) 途中有一条未跟踪的路径

现在让我们考虑相反的情况:

Flipping !SKIP_WORKTREE -> SKIP_WORKTREE (removing files)

如果索引和工作树是干净的,这很好,但如果有任何不干净的路径,我们就会遇到问题。

需要考虑三种不同的情况:

  • B) 路径未合并
  • C) 路径有未分级的更改
  • D) 路径有阶段性变化(不同于 HEAD)

如果任何路径落入案例 B 或 C,则整个操作将因错误而中止。

使用sparse-checkout,对于 case D 也将中止整个操作,但对于其git read-tree -mu HEAD直接使用的前身,任何落入 case D 的路径都将从工作​​副本中删除,并且该路径的索引条目将被重置以匹配HEAD-这对用户来说看起来和感觉就像数据丢失(只有少数人甚至知道询问是否可以恢复,即使这样,它也需要遍历松散的对象以尝试匹配正确的对象)。

拒绝删除未保存用户更改的文件是好的,但拒绝在任何其他路径上工作对​​用户来说是非常有问题的。

如果用户正在进行 rebase 或者对文件进行了修改,从而引入了更多依赖项,那么为了使他们的构建工作,他们需要更新稀疏路径。

这种逻辑一直在阻止他们这样做。

有时,作为响应,用户会暂存文件并重试,但使用稀疏签出无济于事,或者如果他们使用其前身git read-tree -mu HEAD.

添加一个新update_sparsity()函数,该函数在任何这些情况下都不会出错,但在特殊情况下的行为如下:

  • A) 将文件单独留在工作副本中,清除该SKIP_WORKTREE位,并打印警告(从而使路径处于状态将报告文件为已修改的状态,这似乎合乎逻辑)。
  • B) 不要将此路径标记为SKIP_WORKTREE,并将其保留为未合并。
  • C) 不要将此路径标记为SKIP_WORKTREE并打印有关脏路径的警告。
  • D) 将路径标记为SKIP_WORKTREE,但不要将存储在索引中的版本还原为匹配HEAD;不理会内容。

我为 A 尝试了不同的行为(保留SKIP_WORKTREE位设置),但发现它非常令人惊讶且违反直觉(例如,用户看到它与该目录中的所有其他文件一起存在,尝试暂存它,但git add忽略它,因为该SKIP_WORKTREE位已设置)。

A & C 对我来说似乎是最佳行为。

B 可能也是如此,但我想知道打印警告是否会有所改进。

起初,有些人可能会对 D 感到有些惊讶,但考虑到它使用git commitand even git commit -a(git add忽略标记的条目,SKIP_WORKTREE因此不会删除它们,并且commit -a是相似的),这对我来说似乎是合乎逻辑的。

而且,仍然使用 Git 2.27(2020 年第二季度):

请参阅Elijah Newren ( ) 的提交 6c34239(2020 年 5 月 14 日(由Junio C Hamano 合并 -- --提交 fde4622中,2020 年 5 月 20 日)newren
gitster

unpack-trees: 也允许get_progress()在不同的索引上工作

通知人:Jeff Hostetler
签字人:Elijah Newren

commit b0a5a12a60 (" unpack-trees: allow check_updates()to work on a different index", 2020-03-27, Git v2.27.0-rc0 -- merge在批次 #5中列出) 允许check_updates()在不同的索引上工作,但它调用get_progress()的是硬编码为工作o->result很像check_updates()以前。

更新它以接受索引参数并check_updates()传递该参数,以便两者都在同一个索引上工作。


Git 2.29(2020 年第四季度)的代码更加健壮:

请参阅Jeff King ( ) 的提交55fe225、提交1c89001、提交9a53219 ( 2020 年 8 月 17 日)和提交 f1de981提交 c514c62提交 9101c8e提交 8dc3156(2020 年 8 月 14 日(由Junio C Hamano 合并 -- --0d9a8e3 提交中,2020 年 8 月 27 日)peff
gitster

clear_pattern_list(): 清除嵌入的哈希图

签字人:Jeff King
签字人:Derrick Stolee

提交96cc8ab531 (" sparse-checkout: use hashmaps for cone patterns", 2019-11-21, Git v2.25.0-rc0 -- merge ) 向结构添加了一些辅助哈希图,但在调用pattern_list时它们会泄漏。clear_pattern_list()

于 2019-12-28T22:35:21.573 回答