使用 ls 命令时,删除的文件夹仍然出现在 git bash 中

The deleted folder still appears in git bash when using ls command

对于 C# 项目,我使用 git rm -r --cached obj/git rm -r -f obj/ 命令从目录中删除 obj/,但是之后当我使用 ls 时我仍然可以看到obj/ 目录中的文件夹。当我再次尝试使用 git rm -r obj/ 命令时,它告诉我 fatal: pathspec 'obj/' did not match any files,但我仍然可以使用 cd obj/ 查看所有应该删除的文件。

这是什么意思?

git rm 只是从 git 中删除文件。如果你想从文件系统中删除文件,你应该使用 rm -rf ./obj.

git rm(没有 --cached)应该从工作树(您的磁盘)以及索引中删除这些文件,前提是它们首先没有被忽略。

检查是否:

  • 已有一条忽略规则

    git check-ignore -v obj/a_file_inside_obj
    
  • if 所有 文件仍然存在,或者只有少数(可能不会被删除,因为已经被活动线程使用)

您在 Git 中使用的每个文件都有最多三个同时活动的副本。具体来说,让我们谈谈名为obj/a的文件(我只是假设有这样一个文件)。

开始时三个地方有一份obj/a

  • 一个是——或者可能是,无论如何——在你用git checkout mastergit switch master选择的commit中,或者无论如何是您选择了一个 b运行ch,因此选择了一个提交。

  • Git 的 indexobj/a 的第二个副本。该索引也称为 暂存区,包含每个文件的副本1,准备进入下一个 你会做出承诺。索引中的副本首先由您的 git checkoutgit switch 命令放置在那里。它会一直留在那里,直到您对它采取措施或对其进行处理。

  • 最后,您可以 查看 的唯一 obj/a 副本是 工作树中的一个普通文件工作树.

提交副本的原因是每次提交都会保存一份所有文件的副本,作为提交的快照。此副本一经制作,将永远无法更改。 任何 提交的任何部分都不能更改:所有提交都被永久冻结。

工作树副本的原因是提交的副本不仅会一直冻结,还会压缩成一种特殊的 Git-only 格式,只有 Git 可以使用.这对归档很有用,但对实际完成任何工作毫无用处。 Git 必须将其解压缩并将其恢复为正常的日常文件,以便您可以使用它。这也是您的工作树被称为 "work-tree" 或 "working tree" 的原因:它是您工作的地方。

index 副本确实没有明显的存在理由。但是Git有一个。2

当你 运行:

git rm -r --cached obj/

Git 删除了 obj/aindex 副本。提交的副本不能被删除:它在提交中,任何提交的任何部分都不能更改。 obj/awork-tree 副本,这是您可以看到和使用的副本,被留下了,因为 您告诉 Git当你说 --cached 时别管它 。所以现在您只需要 两个 个文件副本,而不是三个。

如果您想删除文件的 work-tree 副本,请使用计算机的 "remove a work-tree file" 命令,无论它是什么 (rm , 也许)。如果你早点告诉 Git git rm -r obj/ 你会指示 Git 删除 两份 份:一份在索引中,一份在作品中-树。现在索引副本消失了git rm不会删除工作树副本,因为工作树副本现在是未跟踪文件.所以现在你需要使用非Git命令。

(或者,您可以 git add obj/a,这会将文件 复制到 索引中。现在它将再次出现在所有三个位置,现在 git rm obj/a 将删除索引和工作树副本。)


1从技术上讲,索引中的内容不是文件的实际 副本,而是文件的名称和模式以及参考文件数据,准备放入新的提交中。但是除非您开始直接使用 git ls-files --stage 检查索引的内容,或者使用 git update-index 来更改索引的内容,否则这里的区别并不那么重要。

2也就是说,Git 那里有一个文件的副本——尽管参见脚注 1。Git 也有一个原因:它使Git 更容易成为 Git。有些系统的工作方式很像 Git,但不用为索引而烦恼。他们只是将工作树副本用作建议的下一次提交。这行得通,但速度较慢,并且不提供 Git 提供的某些功能。