git 如何在我从索引中删除文件后提交 -a 工作

how can git commit -a work after i remove a file from index

假设我跟踪了文件empty.txt。 现在我使用 rm empty.txt 从工作目录中删除文件。 现在我正在使用 git rm empty.txt 从索引中删除文件,现在应该取消跟踪文件,因为我已将其从索引中删除。 在此之后我使用 git commit -a -m "remove empty.txt" 但它是如何工作的 -a 参数用于跳过显式将跟踪文件添加到暂存区但我已经从索引中删除了文件? 它应该是未跟踪的。

最初我认为文档对此很清楚,但在测试后这里有一点奇怪的情况...

所以在大多数情况下,-a 标志将跳过 索引并应用工作树中的更改。删除文件是一种改变。我对(可能含糊不清的)文档的阅读表明索引基本上会被忽略,除了不会添加新文件。

不过,从舞台上删除上一次提交中的文件的情况有些奇怪。我的测试显示,在这种情况下 文件从新提交中删除 基于从索引中删除;然后忽略工作树中的任何进一步更改(即如果文件已重新创建)。从这个意义上说,OP 观察到的是一致的——很难从阅读文档中得到这一点。

太糟糕了,因为它破坏了一堆描述行为的看似真实的简单陈述;但这里是:

git init
touch file1
git add .
git commit -m "initial commit"

echo CHANGES > file1
git rm --cached file1
git status

# this will show a staged change to remove the file, and an untracked file
# with the CHANGES

git commit -a -mtest

...现在提交有一个空目录,并且 file1 未被跟踪。考虑到这一点,问题中的情况只是退化的情况,其中工作树的变化与索引的变化相同。

你可能有两种误解:

  • 这与“跟踪”无关。

  • 一个 git 提交与 更改 无关。它是整个文件集的快照、照片,如索引中所反映的那样,索引本身就是整个文件集的完整副本。

如果您拍摄一只狗站在两棵树之间的照片,照片中包含一只狗和两棵树。那是一个提交。

如果狗走开了,而您再拍一张照片,则照片包含两棵树,但 狗。你拍那张照片的时候它不在那里。那是另一个提交。

创建第二个提交时没有涉及“删除”操作。这不是对第一张照片的修改。这只是一张照片。

在您创建的 git 提交的情况下,“什么是”是索引,简单明了(默认情况下;有办法解决这个问题,通过说 git commit someFile,但是为了我们的目的忽略它)。


好的,那么,关于你的问题的细节。你说:

i remove file from working directory using rm empty.txt

now i am removing file from index using git rm empty.txt

after this i used git commit -a

所以:

  • 如果您从工作树中删除一个文件,git commit -a 会在提交之前自动从索引中删除该文件(就像通过调用 git rm --cached 一样)。该文件现在不在索引中,因此从它创建的提交缺少该文件(就像狗一样)。

  • 在你的例子中,你你自己工作树 索引。因此,就此文件而言,现在 git commit -a-a 部分与索引无关;你已经做了那项工作。现在发生了非常相同的操作:该文件现在不在索引中,因此从它创建的提交缺少该文件(就像狗一样)。