稀疏签出后为何调用`git read-tree` [英] Why does one call `git read-tree` after a sparse checkout
问题描述
根据具有git sparse-checkout的子目录检出如果存储库已经存在,则在配置了稀疏签出后调用git read-tree -mu HEAD
,即:
According to Subdirectory Checkouts with git sparse-checkout one calls git read-tree -mu HEAD
after configuring a sparse checkout in the case of an already existing repository, i.e.:
# 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
(为什么这是合并,什么被合并)? - Can you please explain the
read-tree
step in more detail? - How does it work?
- What is going on?
- Why does one use
read-tree
and not, let us say,checkout
? - Why does one use
-mu
(why is this a merge, and what is merged)?
-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.
推荐答案
在Git 2.25(2020年第一季度)中,稀疏签出工作树的管理获得了专用的稀疏签出"命令.
它引入了圆锥模式(我在"具有排除功能的Git稀疏检出中进行了详细介绍),它将形成sparse-checkout
必须更快.
With Git 2.25 (Q1 2020), Management of sparsely checked-out working tree has gained a dedicated "sparse-checkout" command.
It introduces a cone mode (that I detail in "Git sparse checkout with exclusion"), which will make a sparse-checkout
must faster.
但是它也间接描述了为什么使用git read-tree -mu HEAD
(或者,在新的"cone"模式下,使用了 ).
But it also indirectly describes why git read-tree -mu HEAD
is used (or, with the new "cone" mode, was used).
请参见提交e6152e3 (2019年11月21日),作者为提交761e3d2 (2019年12月20日)由提交190a65f (2019年12月13日),和提交416adc8 ,提交f75a69f ,提交fb10ca5 , n >, ,提交eb42fec , 96cc8ab ,提交879321e ,提交7bffca9 ,提交d89f09c ,提交bab3c35 , 提交94c0956 (2019年11月21日)通过 Junio C Hamano-gitster
-在
See commit e6152e3 (21 Nov 2019) by Jeff Hostetler (Jeff-Hostetler
).
See commit 761e3d2 (20 Dec 2019) by Ed Maste (emaste
).
See commit 190a65f (13 Dec 2019), and commit cff4e91, commit 416adc8, commit f75a69f, commit fb10ca5, commit 99dfa6f, commit e091228, commit e9de487, commit 4dcd4de, commit eb42fec, commit af09ce2, commit 96cc8ab, commit 879321e, commit 72918c1, commit 7bffca9, commit f6039a9, commit d89f09c, commit bab3c35, commit 94c0956 (21 Nov 2019) by Derrick Stolee (derrickstolee
).
(Merged by Junio C Hamano -- gitster
-- in commit bd72a08, 25 Dec 2019)
sparse-checkout
:正在更新工作目录签名人:Derrick Stolee
sparse-checkout
: update working directory in-processSigned-off-by: Derrick Stolee
内部稀疏签出使用'git read-tree -mu HEAD
'更新索引中的skip-worktree位并更新工作目录.
这个额外的过程过于复杂,容易失败.它还要求我们在尝试更新索引之前将所做的更改写入稀疏签出文件.
The sparse-checkout builtin used 'git read-tree -mu HEAD
' to update the skip-worktree bits in the index and to update the working directory.
This extra process is overly complex, and prone to failure. It also requires that we write our changes to the sparse-checkout file before trying to update the index.
通过创建对unpack_trees()
的直接调用来删除此多余的过程调用,方法与'git read-tree -mu HEAD
'相同.
另外,提供一个内存中的模式列表,这样我们就可以避免从稀疏签出文件中读取内容.这使我们能够在写入文件之前测试对文件的建议更改.
Remove this extra process call by creating a direct call to unpack_trees()
in the same way 'git read-tree -mu HEAD
' does.
In addition, provide an in-memory list of patterns so we can avoid reading from the sparse-checkout file. This allows us to test a proposed change to the file before writing to it.
此修补程序的较早版本包含一个错误,因为稀疏检出在工作目录上没有任何条目"错误导致"set
"命令失败.
它不会回滚index.lock
文件,因此重播旧的稀疏检出规范将失败.现在,t1091中的测试涵盖了该情况.
An earlier version of this patch included a bug when the 'set
' command failed due to the "Sparse checkout leaves no entry on working directory" error.
It would not rollback the index.lock
file, so the replay of the old sparse-checkout specification would fail. A test in t1091 now covers that scenario.
而且,在Git 2.27(2020年第二季度)中,"sparse-checkout
"知道如何重新应用本身:
And, with Git 2.27 (Q2 2020), "sparse-checkout
" knows how to reapply itself:
请参见提交5644ca2 ,提交ebb568b ,提交22ab0b3 ,提交1ac83f4 ,提交cd002c1 ,提交f56f31a ,提交7af7a25 ,,提交b0a5a12 ,提交fa0bde4 ,,提交031ba55 (2020年3月27日) ="https://github.com/newren" rel ="nofollow noreferrer">伊利亚·纽伦(newren
).
(由 Junio C Hamano-gitster
-在
See commit 5644ca2, commit 681c637, commit ebb568b, commit 22ab0b3, commit 6271d77, commit 1ac83f4, commit cd002c1, commit 4ee5d50, commit f56f31a, commit 7af7a25, commit 30e89c1, commit 3cc7c50, commit b0a5a12, commit 72064ee, commit fa0bde4, commit d61633a, commit d7dc1e1, commit 031ba55 (27 Mar 2020) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit 48eee46, 29 Apr 2020)
sparse-checkout
:提供一个新的重新应用子命令作者:Derrick Stolee
签名人:伊利亚·纽伦
sparse-checkout
: provide a new reapply subcommandReviewed-by: Derrick Stolee
Signed-off-by: Elijah Newren
如果诸如合并或重新设置实体化文件之类的命令作为其工作的一部分,或者先前的稀疏签出命令由于不正确的更改而无法更新单个文件,则用户可能希望该命令简单地重新应用"稀疏性规则.
If commands like merge or rebase materialize files as part of their work, or a previous sparse-checkout command failed to update individual files due to dirty changes, users may want a command to simply 'reapply' the sparsity rules.
提供一个.
已更新git sparse-checkout
手册页现在包括:
The updated git sparse-checkout
man page now includes:
reapply
:将稀疏模式规则重新应用于工作树中的路径.
reapply
:Reapply the sparsity pattern rules to paths in the working tree.
诸如merge
或rebase
的命令可以具体化路径来完成其工作(例如,为了向您显示冲突),而其他稀疏签出命令可能无法稀疏单个文件(例如,因为该文件具有未暂存的更改)或冲突).
Commands like merge
or rebase
can materialize paths to do their work (e.g. in order to show you a conflict), and other sparse-checkout commands might fail to sparsify an individual file (e.g. because it has unstaged changes or conflicts).
在这种情况下,清理受影响的路径(例如解决冲突,撤消或提交更改等)之后稍后再运行git sparse-checkout reapply
是有意义的.
In such cases, it can make sense to run git sparse-checkout reapply
later after cleaning up affected paths (e.g. resolving conflicts, undoing or committing changes, etc.).
但是,在Git 2.27中,它将不再使用git read-tree
重新申请/更新自身:
But, with Git 2.27, it won't reapply/update itself using git read-tree
anymore:
请参见提交5644ca2 ,提交ebb568b ,提交22ab0b3 ,提交1ac83f4 ,提交cd002c1 ,提交f56f31a ,提交7af7a25 ,,提交b0a5a12 ,提交fa0bde4 ,,提交031ba55 (2020年3月27日) ="https://github.com/newren" rel ="nofollow noreferrer">伊利亚·纽伦(newren
).
(由 Junio C Hamano-gitster
-在
See commit 5644ca2, commit 681c637, commit ebb568b, commit 22ab0b3, commit 6271d77, commit 1ac83f4, commit cd002c1, commit 4ee5d50, commit f56f31a, commit 7af7a25, commit 30e89c1, commit 3cc7c50, commit b0a5a12, commit 72064ee, commit fa0bde4, commit d61633a, commit d7dc1e1, commit 031ba55 (27 Mar 2020) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit 48eee46, 29 Apr 2020)
unpack-trees
:添加新的update_sparsity()
函数作者:Derrick Stolee
签名人:伊利亚·纽伦
unpack-trees
: add a newupdate_sparsity()
functionReviewed-by: Derrick Stolee
Signed-off-by: Elijah Newren
以前,更新各种路径的SKIP_WORKTREE
位的唯一方法是调用git read-tree -mu HEAD
或调用此代码路径调用的相同代码.
Previously, the only way to update the SKIP_WORKTREE
bits for various paths was invoking git read-tree -mu HEAD
or calling the same code that this codepath invoked.
但是,如果索引或工作目录不干净,则会出现许多问题.
首先,让我们考虑一下情况:
First, let's consider the case:
Flipping SKIP_WORKTREE -> !SKIP_WORKTREE (materializing files)
如果工作树是干净的,那很好,但是如果在给定路径中存在文件,目录或符号链接或任何已经存在的内容,则该操作将因错误而中止.
If the working tree was clean this was fine, but if there were files or directories or symlinks or whatever already present at the given path then the operation would abort with an error.
我们将此案例标记为以后进行讨论:
Let's label this case for later discussion:
- A)路上有一条未追踪的路径
现在让我们考虑相反的情况:
Now let's consider the opposite case:
Flipping !SKIP_WORKTREE -> SKIP_WORKTREE (removing files)
如果索引和工作树是干净的,那很好,但是,如果有任何不干净的路径,我们会遇到问题.
If the index and working tree was clean this was fine, but if there were any unclean paths we would run into problems.
要考虑三种不同的情况:
There are three different cases to consider:
- B)路径未合并
- C)路径具有未更改的更改
- D)路径已发生阶段性变化(与HEAD有所不同)
- B) The path is unmerged
- C) The path has unstaged changes
- D) The path has staged changes (differs from HEAD)
如果情况B或C进入任何路径,则整个操作将中止并出现错误.
If any path fell into case B or C, then the whole operation would be aborted with an error.
对于sparse-checkout
,对于情况D也将终止整个操作,但是对于直接使用git read-tree -mu HEAD
的前任,落入情况D的所有路径将从工作副本和索引条目中删除.该路径将被重置以匹配HEAD
-看起来和用户的数据丢失(只有少数人甚至知道问是否可以恢复它,即使那样,它也需要遍历松散的对象来尝试匹配正确的.)
With sparse-checkout
, the whole operation would be aborted for case D as well, but for its predecessor of using git read-tree -mu HEAD
directly, any paths that fell into case D would be removed from the working copy and the index entry for that path would be reset to match HEAD
-- which looks and feels like data loss to users (only a few are even aware to ask whether it can be recovered, and even then it requires walking through loose objects trying to match up the right ones).
拒绝删除尚未保存的用户更改的文件是件好事,但是拒绝在其他路径上工作对用户来说是一个很大的问题.
Refusing to remove files that have unsaved user changes is good, but refusing to work on any other paths is very problematic for users.
如果用户处于rebase的中间或对文件进行了修改以引入更多的依赖关系,则要使他们的构建正常工作,他们需要更新稀疏路径.
If the user is in the middle of a rebase or has made modifications to files that bring in more dependencies, then for their build to work they need to update the sparse paths.
此逻辑已阻止他们这样做.
This logic has been preventing them from doing so.
有时,用户会暂存文件并重试,而使用稀疏签出将无济于事,如果使用其前身git read-tree -mu HEAD
,他们会失去更改的恐惧.
Sometimes in response, the user will stage the files and re-try, to no avail with sparse-checkout or to the horror of losing their changes if they are using its predecessor of git read-tree -mu HEAD
.
添加一个新的update_sparsity()
函数,在任何情况下都不会出错,但是在特殊情况下的行为如下:
Add a new update_sparsity()
function which will not error out in any of these cases but behaves as follows for the special cases:
- A)将文件保留在工作副本中,清除
SKIP_WORKTREE
位,然后打印警告(因此,将路径保持在状态将报告文件已修改的状态,这似乎是合乎逻辑的). - B)请勿将此路径标记为
SKIP_WORKTREE
,并将其保留为未合并. - C)请勿将此路径标记为
SKIP_WORKTREE
,并打印有关脏路径的警告. - D)将路径标记为
SKIP_WORKTREE
,但不要还原存储在索引中的版本以匹配HEAD
;放下里面的东西.
- A) Leave the file in the working copy alone, clear the
SKIP_WORKTREE
bit, and print a warning (thus leaving the path in a state where status will report the file as modified, which seems logical). - B) Do NOT mark this path as
SKIP_WORKTREE
, and leave it as unmerged. - C) Do NOT mark this path as
SKIP_WORKTREE
and print a warning about the dirty path. - D) Mark the path as
SKIP_WORKTREE
, but do not revert the version stored in the index to matchHEAD
; leave the contents alone.
我为A尝试了另一种行为(保留了SKIP_WORKTREE
位),但是发现它非常令人惊讶且违反直觉(例如,用户看到它与该目录中的所有其他文件一起存在,试图进行登台)它,但 git add
会忽略它,因为已设置SKIP_WORKTREE
位).
I tried a different behavior for A (leave the SKIP_WORKTREE
bit set), but found it very surprising and counter-intuitive (e.g. the user sees it is present along with all the other files in that directory, tries to stage it, but git add
ignores it since the SKIP_WORKTREE
bit is set).
A& C对我来说似乎是最佳行为.
A & C seem like optimal behavior to me.
B也可以,但我不知道打印警告是否会有所改善.
B may be as well, though I wonder if printing a warning would be an improvement.
一开始,有些人可能会对D感到有些惊讶,但是考虑到它对git commit
甚至git commit -a
都做了正确的处理((git add
会忽略标记为SKIP_WORKTREE
的条目,因此不会删除它们,和commit -a
相似),对我来说似乎合乎逻辑.
Some might be slightly surprised by D at first, but given that it does the right thing with git commit
and even git commit -a
(git add
ignores entries that are marked SKIP_WORKTREE
and thus doesn't delete them, and commit -a
is similar), it seems logical to me.
而且,仍然使用GIt 2.27(2020年第二季度):
And, still with GIt 2.27 (Q2 2020):
参见提交6c34239 (2020年5月14日)通过 Junio C Hamano-gitster
-在
See commit 6c34239 (14 May 2020) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit fde4622, 20 May 2020)
unpack-trees
:还允许get_progress()
处理不同的索引作者:Jeff Hostetler
签名人:伊利亚·纽伦
unpack-trees
: also allowget_progress()
to work on a different indexNoticed-by: Jeff Hostetler
Signed-off-by: Elijah Newren
提交b0a5a12a60 ("unpack-trees
:允许check_updates()
继续工作一个不同的索引",2020年3月27日,Git v2.27.0-rc0-合并check_updates()
处理不同的索引,但它称为get_progress()
,它像check_updates()
一样被硬编码以在o->result
上工作.
commit b0a5a12a60 ("unpack-trees
: allow check_updates()
to work on a different index", 2020-03-27, Git v2.27.0-rc0 -- merge listed in batch #5) allowed check_updates()
to work on a different index, but it called get_progress()
which was hardcoded to work on o->result
much like check_updates()
had been.
对其进行更新以也接受索引参数,并让check_updates()
一起传递该参数,以使两者都在同一个索引上工作.
Update it to also accept an index parameter and have check_updates()
pass that parameter along so that both are working on the same index.
这篇关于稀疏签出后为何调用`git read-tree`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!