Timothy Truckle's answer 是正确的,但我会补充几点:
-
git worktree add 不仅会创建一个新的工作树,而且还会创建一个新的索引/暂存区,该索引/暂存区是该新工作树的私有。
- 在 Git 版本 2.5 到 2.14 中存在一个错误 - 一个相当糟糕的错误,已在 2.15 中修复,与此相关。
错误是这些添加的工作树中的索引/暂存区确实有一个有限的生命周期,这是错误的。存储在其中的某些文件可能会在 14 天后被错误地销毁。因此,如果您有 2.15 之前的 Git,并使用 git worktree add,请在两周内在这个添加的工作树中完成您的工作。 (或者更新到更正的 Git:更新足以保持其添加的索引文件完好无损;您无需对添加的工作树执行任何操作;您只需要在暂存区被破坏之前进行升级。)
可选的附加阅读
如果暂存区内容没有生命周期,那么它与存储库本身有何不同?在这种情况下,在我看来,它就像是第二个存储库。
Git 存储库大致上是一个包含提交 的大型数据库。这些是编号的(按大的、丑陋的、看起来随机的哈希 ID),Git 按该编号将它们从数据库中拉出。因此,在 Git 找到提交之前,您必须提供任何提交 到 Git 的哈希 ID。我们有分支和其他名称,因此我们,仅仅是人类,可以使用辅助数据库(将名称转换为数字)来帮助我们(和 Git)找到提交,而无需记住看起来随机的哈希 ID。
index,staging area,或者(用最古老和最糟糕的术语)cache,在 Git 中实际上并不是一个犯罪。它有一小部分杂项工作,因此没有一个完美的描述,但 staging area 之所以是一个很好的名字,是因为它在所有时间都拥有一个 建议下一次提交。
(有时——在冲突合并期间——它会变得一团糟,实际上无法提交。但即便如此,它也会保留某种提议的下一次提交。只是提议太多在其中,包括无法提交的额外内容。在这种情况下,git status 将告诉您有关 unmerged 文件的信息。但是如果我们忽略这种特殊情况,并忽略索引的其他额外角色播放——例如加快 git status 处理 untracked 文件的速度,例如可选的“untracked cache”——“proposed next commit”描述非常适合。)
由于 repository 是一个提交数据库,而 index / staging-area 只是一个 单个提议的提交,但实际上尚未提交,因此两者之间存在很大差异索引和存储库。事实上只有一个索引——或者更准确地说,每个添加的工作树一个,加上一个原始的1——意味着你在这里最多只能持有一个额外的提交(或者 N+1 N 是添加的工作树的数量)。
也值得看看git status 在这里的工作原理:
-
有一个当前提交,可以使用名称HEAD 找到。与所有提交一样,此提交是只读的:它实际上无法更改。 (您可以切换到其他一些当前提交,即更改哪个提交是当前的,但您不能更改任何提交的内容。)
-
然后在索引/暂存区域中有提议的下一次提交。你可以改变这里的内容。它们以预先 Git 化的格式存储,准备好提交:一旦文件位于索引/暂存区域中,文件就已经被删除重复和 Git 化。
-
最后,在您的工作树中,有一些您正在处理/使用的文件。您也可以更改这些,因为这些只是普通文件。 您计算机上的任何程序都可以读取或写入这些,而不仅仅是 Git。
所以当您运行git status 时,它会进行两个 diff,而不仅仅是一个。第一个差异将HEAD 中的文件与索引/暂存区域中的文件进行比较。 对于每个相同的文件,Git 什么都不说。对于任何不同的文件,Git 都会说staged for commit。
运行该差异后,git status 还会运行 second 差异,以将索引中的文件与工作树中的文件进行比较。再一次,对于 相同 的文件,Git 什么也没说。 对于任何不同的文件,Git 都会说not staged for commit。
当您有一个大型项目时,这种阴暗的“隐藏文件”舞蹈很有用的原因就很明显了。假设当前提交中有 10,000 个文件。因此,索引中有 10,000 个文件(可能加上或减去一个或两个),而索引中有 10,000 个文件(加上或减去几个,加上可能是一堆您永远不会提交的 untracked 文件)工作树。如果git status 每次都报告(两次!)所有 10k 个文件,您将如何在所有噪音中找到有用的数据(例如,您更改了其中的三个)?您想要一个有用的摘要,而不是包含三个有用名称的 9997 个未修改文件的列表。
(如果你想要原始列表,git ls-files --stage 会得到它。)
1这个有点笨拙的措辞(为什么不只是“工作树的数量”?)的原因是 Git 有所谓的 bare 存储库,它没有工作树。这些存储库仍然有一个索引。因此,在一个裸仓库中,我们有一个暂存区,但工作树为零。添加三个工作树,我们现在有四个暂存区和三个工作树。
我认为在 any 存储库中拥有初始工作树和索引/暂存区从根本上说是错误的,并且所有存储库都应该 start "裸”,然后添加工作树,默认情况下可能是一个,但仍作为附加组件。因此,一个真正的裸仓库将没有索引,并且 所有 工作树将被“添加”,而不是在非裸仓库的“主要工作树”和所有添加之间有一个奇怪的区别-在那些。但这已经太迟了。对于大多数用户来说,这将是一个没有区别的区别,但它会解决一些棘手的内部问题,其中一个问题目前正在邮件列表中引起大量讨论。