在暂存文件(已跟踪的文件)后,我意识到它需要做一些更改。为了取消暂存,我使用了git rm --cached <filename>
。结果,我失去了所有更改。是否有一种方法可以撤消这个操作?
在暂存文件(已跟踪的文件)后,我意识到它需要做一些更改。为了取消暂存,我使用了git rm --cached <filename>
。结果,我失去了所有更改。是否有一种方法可以撤消这个操作?
git rm --cached
只会将新文件从索引中移除,而不会从工作目录中移除。以这种方式进行操作时要小心。如果这是一个已存在的文件,则刚刚将该文件删除进行了暂存。
您可以使用git add <filename>
再次添加它。
取消暂存更改的一种更常见的方法是使用git reset HEAD <filename>
。
但是...不需要取消暂存文件以添加进一步的更改,您只需对其进行更改并再次使用git add <filename>
进行暂存即可。
git add 文件
时,Git会将工作树副本压缩成特殊的Git格式,并将压缩后的副本放入索引中。现在索引副本不再与HEAD
副本匹配,但它与工作树副本匹配。git status
将告诉您有“已准备提交的更改”和“未准备提交的更改”。git rm --cached
可以删除索引副本而不删除工作树副本,使用git rm
可以同时删除两个副本。这些操作都不会影响任何现有提交 - 没有任何现有提交可以被更改!但是删除索引副本会影响下一次提交,因为当您运行git commit
时,Git将打包所有在索引中的文件,所以如果文件从索引中消失了,它就不会出现在下一个提交中。如果您想要将文件从当前(HEAD
)提交返回到索引中,以其在当前提交中的形式,可以使用 git reset -- 文件名
命令。这里的 --
只有在文件名类似于 git reset
选项或分支名称时才需要。例如,如果您有一个名为 master
的文件和一个名为 master
的分支,那么 git reset master
看起来像是您想使用 分支 名称,因此您必须写成 git reset -- master
来告诉 git 您指的是 文件 master
。
git reset -- file
将文件从HEAD
提交复制到索引中。即使您已经删除了索引副本,这也是正确的:重置会将其放回。如果文件不在HEAD
提交中,这也是正确的。如果您已将文件F
添加到索引中,然后决定它不应再在索引中,您可以使用git reset -- F
将其从索引中删除。git rm --cached F
:此时具有相同效果。但是,如果您只想使索引副本与HEAD
副本匹配,请使用git reset
,因为它适用于两种情况:有一个HEAD
副本或没有。)
git add
将该文件添加到索引中,则现在它是被跟踪的。
HEAD:file
和:file
语法是特定于Git本身的,仅适用于一些Git命令。其中之一是git show
:例如,您实际上可以使用git show :README.md
查看README.md
的索引副本。由于git show
是一个面向用户的命令,因此您可以相对安全地执行此操作:git show HEAD:file
、git show :file
和git show <commit:>file
都是查看特定文件的特定副本的相当不错的方法,该文件已被转换为其内部Git形式,无论是保存在提交中还是准备进入提交中。git ls-files
查看所有文件的索引副本的名称。在大型存储库中,这将打印出很多名称!它不适用于日常使用,也不是非常用户友好的命令。
git checkout
写入索引要创建一个新提交,您只需将正确的文件复制到索引中并运行git commit
。索引已经包含了当前提交的所有文件,因此您只需要更新任何要更改的文件,添加任何要添加的新文件,或删除任何要删除的文件。然后您git commit
并创建一个新的提交。这个新提交现在是HEAD
提交,现在HEAD
提交和索引匹配。
如果HEAD
提交和索引匹配,并且这两者与工作树匹配,则一切都很“干净”,您可以轻松地切换到另一个提交,例如:
git checkout otherbranch
git switch
,它类似于友好版本的 git checkout branch
,不会把所有其他 Git 工具都塞进一个命令中——根据您的计算方式,git checkout
可以完成三到七个不同的工作)。
假设这个 checkout 成功,它必须:
otherbranch
尖端的所有文件填充您的暂存区(并删除任何不相关的文件);otherbranch
尖端的所有文件填充您的工作目录(并删除任何不相关的文件);以及HEAD
引用 otherbranch
的尖端提交。完成所有这些操作后,您的 HEAD
提交、暂存区和工作目录再次匹配。
3有时候,即使索引和工作树不是“干净”的,git checkout
命令也可以成功。这里“干净”一词定义不清,但如果想了解更多关于何时git checkout
允许您在携带修改的情况下切换分支,请参见当当前分支存在未提交的更改时,检出另一个分支。
您无法直接查看文件的索引副本!您可以并且应该使用git status
,它会将HEAD
文件与索引副本进行比较。在一个大型项目中,有成百上千甚至数百万个文件,Git几乎不会对它们做出任何反应。它只会提到那些不同的文件。这非常有用。
每当HEAD
、索引和工作树完全匹配时,git status
不会输出任何内容。当git status
发现一些不匹配的情况时,它会在已暂存提交更改和/或未暂存提交更改下打印文件名,具体取决于是HEAD
和索引副本不一致,还是索引和工作树副本不一致,或两者都不一致。
git add
将文件复制到索引中。如果它们之前已经在索引中了,那么现在它们被来自工作树的副本覆盖掉了。如果它们之前不在索引中,那么现在它们就在了。
git rm
命令从索引中删除文件。如果不使用 --cached
选项,它还会从工作树中删除相同的文件。如果使用了 --cached
选项,则保留工作树副本,这在现在是可以的,但是以后可能需要通过 git checkout
命令来删除工作树副本!
一般情况下,Git 会尽力避免破坏任何具有重要数据的工作树文件。那么什么是“重要的”呢?如果工作树文件 util.py
已添加并提交,并与 HEAD:util.py
和 :util.py
匹配,此时 util.py
就不再是重要的了,因为如果您需要它,它已经在提交中了。因此,您可以 git checkout
一个旧的提交,该提交中没有 util.py
,Git 将完全安全地从您的工作树中删除 util.py
。只需执行最新的 git checkout
命令即可将其恢复。
git reset --hard
,会销毁工作树文件。 git reset --hard
的理论是你想要重置索引和工作树。默认模式是 git reset --mixed
,只重置索引副本。4 这就是为什么 git reset -- file
“取消暂存”文件 - 将 HEAD:file
复制到 :file
,但不会触及文件的工作树副本。
git reset --soft
、git reset --mixed
和git reset --hard
只允许你做所有文件。当你只想做一个文件时,使用git reset -- file
,它总是使用--mixed
。对于其他情况,你必须使用git checkout
的许多备选模式之一。Git 2.23引入了一个新命令git restore
,旨在使这个过程更少混乱。时间会告诉我们它是否做到了: git restore
在技术上仍然是实验性的。你需要再次添加 </head>
。以下是一组示例命令。
echo testmodify>> FOO //Appends "testmodify" to FOO
git add FOO // Stage FOO to commit
git rm --cached FOO // Unstage FOO
git add FOO // Stage FOO
FOO仍然包含“testmodify”
git stash