Why “git rm --cached” remove the up-to-date files?
我在本地Git报告中有一个readme.md。本地git repo在工作树中没有任何阶段和变化。见下文:
1 2 3 4
| $ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean |
然后我运行git rm --cached -- README.md,上面写着:
1 2
| $ git rm --cached -- README.md
rm 'README.md' |
号
根据git help rm号文件:
--cached
Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.
号
readme.md没有阶段性的更改,因此阶段性区域/索引不应包含任何内容。为什么它仍然被移除?
ADD1
根据@dietrichepp的回答:
就Git而言,国家存在于3个地方:
工作树
指数
回购协议
Git通过比较1和2来决定什么是un-tracked或un-staged;
Git通过比较2和3来决定什么是to-be-commited;
git reset可用于改变1和/或2中的状态。
- 更准确地说,这里有HEAD承诺(它应该取代您的项目3),然后是索引(您的2),然后是工作树(您的1)。如果你使用git status --short,这些是从左到右的成对比较。索引(并且只有索引)定义了跟踪的内容。
索引不包含任何内容,它包含您要提交的内容,包括已经是repo一部分的文件。假设您运行以下命令:
1 2 3 4 5
| touch a.txt b.txt
git add a.txt b.txt
git commit
git rm --cached a.txt
git commit |
第一次运行git add时,它会将a.txt和b.txt添加到索引中。然后,git commit获取索引中的任何内容并提交。
该指数仍包含a.txt和b.txt。
当您使用git rm --cached时,它会从索引中删除a.txt,但b.txt仍在索引中。然后,git commit获取索引中的任何内容(仅b.txt)并提交。a.txt文件仍然存在,因为git rm --cached不接触实际文件,git commit也不接触实际文件。
因为第一个提交包含a.txt,而第二个提交不包含,所以显示为删除。
git status所做的主要工作是显示索引和磁盘上实际文件之间的差异。因此,如果git status为空,那么磁盘上所有未忽略的文件也都在索引中。
- 我又试了一下。似乎index保存了所有的跟踪文件。当我从索引中RM一个文件时,它就变成了未跟踪的。未从文件系统中物理删除。提交之后,它(readme.md)就变成了未跟踪的文件之一。
- 这很有趣。如果我用reset将index中的某个文件状态设置为其他一些撤销,git status会告诉我我有一些changes to be commited文件。我真的没有改变工作树。一旦我使用git add来添加特定的文件,但还没有运行git commit,git status说我没有什么可承诺的。因此,似乎git status只是盲目地比较了索引、回购和工作树中的内容。它不关心历史。
- 没错,git status不在乎历史。