Git tracked, untracked, staged, indexed 是什么意思?

Git tracked, untracked, staged, indexed meaning?

谁能解释一下这些术语的含义?跟踪文件是否是在某个时候添加到舞台上的任何文件? "index" 和 "stage" 一样吗?是否跟踪了所有暂存文件,但反之则不一定正确(即曾经暂存和提交但不属于要提交的当前阶段的文件)?我如何知道跟踪了哪些文件?我如何知道暂存了哪些文件?

这里需要考虑三件事:当前提交(也称为 HEAD@)、index工作树.

索引也称为暂存区缓存。这些代表了它的各种功能,因为索引不仅仅是保存提议的下一次提交的内容。不过,它作为缓存的用途大部分是不可见的:您只需使用 Git,而使 Git 运行速度更快的缓存技巧都是在幕后完成的,无需手动干预。所以你只需要 "cached" 记住一些命令使用 --cached,例如 git diff --cachedgit rm --cached。其中一些有额外的名称 (git diff --staged),而另一些则没有。

Git 在使用这些术语的地方不是很一致,因此您必须简单地记住它们。一个问题似乎是,对于许多用户来说,"the index" 很神秘。这可能是因为您无法直接 看到 它,除非使用 git ls-files (这不是一个用户友好的命令:它用于编程,而不是日常使用)。

请注意,工作树(也称为 工作树,有时也称为 工作目录工作目录) 与索引完全分开。您可以很容易地查看和修改工作树中的文件。

我曾经以为"tracked"更复杂,但事实证明tracked字面上的意思是在索引中.当且仅当 git ls-files 显示它将在下一次提交中时,文件才会被跟踪。

您无法轻易地在索引中看到文件,但是您可以使用 git add:

轻松地将工作树中的文件复制到索引中
git add path/to/file.txt

将文件从工作树复制到索引中。如果它不在索引中(未被跟踪),它现在在索引中(被跟踪)。


因此:

Are tracked files any files that have, at some point, been added to the stage?

没有!跟踪的文件是索引 现在 中的文件。过去发生了什么,在任何提交中,或者在过去的任何时候都没有关系。如果某些路径 path/to/file.txt 出现在索引 现在 中,该文件将被跟踪。如果不是,则不会对其进行跟踪(并且可能还会 忽略 )。

如果 path/to/file.txt 现在在索引中,并且您将其删除,则不再跟踪该文件。它可能在也可能不在任何现有的提交中,它可能在也可能不在工作树中。

Is the "index" the same as the "stage"?

是的,或多或少。各种文档和人们对此不是很一致。

Are all staged files tracked, but the reverse is not necessarily true (namely, files that were once staged and committed, but aren't part of the current stage to be committed)?

这个问题不太合理,因为 "the staging area" 索引。我认为 staged 没有一个完美定义的含义,但我会这样定义它。如果满足以下条件,文件 暂存

  • 不在@/HEAD中,但在索引中,或者
  • @/HEAD 中都是索引,两者不同。

等价地,你可以说 "when some path is being called staged, that means that if I make a new commit right now, the new commit's version of that file will be different from the current commit's version." 请注意,如果你没有以任何方式触及文件,那么它在索引 中的当前提交中 在工作树中,但是 所有三个版本都匹配 ,文件仍将被提交。它既不是 "staged" 也不是 "modified".

How do I know which files are tracked?

虽然git ls-files可以告诉你,但通常的查找方式是间接:你运行git status.

How do I know which files are staged?

假设上面的定义,你必须要求Git到diff当前提交(HEAD/@)和索引。它们之间的不同之处在于"staged"。 运行 git status 将为您做这个差异,并报告此类文件的名称(不显示详细的差异)。

要获得详细的差异,您可以 运行 git diff --cached,它将 HEAD 与索引进行比较。这也有名称 git diff --staged(这是一个更好的名称 - 但是,也许只是为了烦人,--staged 不能作为 git rm 的选项!)。

因为每个文件有 三个 个副本,你需要 两个 个差异来查看发生了什么:

  • 比较 HEAD 与索引:git diff --cached
  • 比较索引与工作树:git diff

运行git status运行s bothgit diff-s给你,总结一下。您可以使用 git status --short 获得更短的摘要,您将在其中看到类似以下内容:

 M a.txt
M  b.txt
MM c.txt

第一列是比较HEAD与索引的结果:空白表示两者匹配,M表示HEADindex不同。第二列是比较索引与工作树的结果:空白表示两者匹配,M 表示它们不同。连续的两个 M 意味着 所有三个版本的 c.txt 都是不同的 。你不能直接在索引中看到那个,但是你可以git diff它!

通过显示而不是描述可能会很清楚。

请注意,@torek 的回答中的信息是正确的。

回想一下 indexstagecache 都是 [= 中的同义词25=].

## No new files

$ git status
On branch master
nothing to commit, working tree clean  
# So git shows no files or changes

## New file that is not tracked
$ touch foo
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        foo

nothing added to commit but untracked files present (use "git add" to track)
# So git realises there is a new file, but it is not tracking it

## Tracked but not staged
$ git add --intent-to-add foo  # shorthand equivalent flag is -N
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        new file:   foo

no changes added to commit (use "git add" and/or "git commit -a")
# Now git is tracking the file, but no changes are staged for commit yet

## Tracked and staged
$ git add foo
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   foo

# Now the file is still tracked and the change is staged

希望您能从中看出未跟踪、跟踪和暂存之间的区别