git ls-files --stage 即使在提交后也显示文件

git ls-files --stage shows files even after committing

我正在执行 git 命令显示当前驻留在临时区域内的所有文件(它与索引相同吗?)。

首先我从索引中删除了所有文件:

$ git rm --cached *
rm 'newfile'
rm 'os-list.txt'
rm 'remote_stuff'
rm 'removethis'

现在我检查索引中的文件:

$ git ls-files --stage
100644 07e6e472cc75fafa944e2a6d4b0f101bc476c060 0       .gitignore

您只能看到。git剩下忽略文件。

然后我们更改newfile的内容。然后我们将 newfile 添加到 index.

$ git add newfile

查看状态:

$ git status -s
M  newfile
D  os-list.txt
D  remote_stuff
D  removethis
?? os-list.txt
?? remote_stuff
?? removethis

我们可以看到新文件现在在索引中。

现在我们希望在提交文件时暂存区是空的。

$ git commit -m "TEST333"
[master 0adab53] TEST333
 4 files changed, 1 insertion(+), 13 deletions(-)
 delete mode 100644 os-list.txt
 delete mode 100644 remote_stuff
 delete mode 100644 removethis

但即使在提交之后,我们仍会看到新文件仍在暂存区中:

$ git ls-files --stage
100644 07e6e472cc75fafa944e2a6d4b0f101bc476c060 0       .gitignore
100644 76abab2928bdd7dfe157109666023bb0c5e4c465 0       newfile

但是如果我们检查状态,我们会发现暂存区没有任何内容:

$ git status -s
?? os-list.txt
?? remote_stuff
?? removethis

好吧,我要的是在暂存区显示所有文件的命令。命令 git ls-files --stage 正在返回我不理解的输出。

谢谢!

Now we expect staging area to be empty when we commit the files.

那是你的错误。不要指望这个!

... if we check status we see there's nothing in staging area

git status 不会向您显示索引/暂存区中的内容。相反,对于每个文件,它 将索引/暂存区中的内容 与:

进行比较
  • HEAD 提交中的内容:如果不同,则文件为 "staged for commit";和
  • 工作树中的内容:如果不同,则文件为 "not staged for commit"

——这就是为什么一个文件可以是"staged for commit""not staged for commit"。这只是意味着 index 副本,即您看到的带 git ls-files --stage 的副本,不同于 其他两个副本 .

每个文件有三个活动副本1当三个都相同时, git status 什么也没说。当文件 F 的某些副本不同时,git status 会告诉您文件 F。这就是它真正的全部,在这里。

索引/暂存区始终包含[​​=57=]2您计划(或Git计划)放入下一个 提交。这就是为什么你必须在更改工作树副本后更新它:这样 Git 计划放入 next 提交的内容将匹配工作树副本。


1从技术上讲,它 最多 三份,因为您可能会遗漏一两份。一个文件是 tracked 当且仅当它在索引中有一个副本(即使它在 HEAD 提交中,它只有在 时才会被跟踪也在索引中)。如果工作树文件存在且不在索引中,则它是 untracked。 (因此,在 git rm --cached 之后,位于 HEAD 和工作树中的文件将同时被删除和取消跟踪。)

2见脚注1,再见冲突合并案例。在冲突合并期间,索引最多包含每个文件的 三个 副本:合并基础副本、--ours 副本和 --theirs 副本。如果添加 HEAD 副本和工作树副本,这意味着在冲突合并期间,任何一个文件最多有 5 个活动副本。