如何删除一个文件从暂存区(=索引=缓存)在Git?

这个问题可以用两种方式来理解,两种情况下的最佳答案是不同的。

  • 问题1:我在暂存区添加了一个以前未跟踪的文件。如何从暂存区删除此文件而不将其从文件系统中删除?

    答案1:使用以下命令,如John Feminella的回答所述:

    git rm --cached <file>
    
  • 问题2:我修改了已跟踪的文件,并将我的修改添加到暂存区域。如何从暂存区域删除修改?也就是说,如何取消文件中的修改?

    答案2:使用以下命令,如大卫·安德希尔的回答所述:

    git reset <file>
    
275394 次浏览

这应该取消<文件>对于您(不删除或修改文件):

git reset <file>

你想要的:

git rm --cached [file]

如果省略--cached选项,它也会从工作树中删除它。git rmgit reset稍微安全一些,因为如果暂存的内容与分支的顶端或磁盘上的文件不匹配,您将得到警告。(如果没有,你必须添加--force。)

取决于您的工作流,这可能是您很少需要的那种东西,以至于尝试找出一个命令行解决方案没有什么意义(除非由于某种原因,您碰巧在没有图形界面的情况下工作)。

只需使用一个支持索引管理的基于gui的工具,例如:

  • git gui <——使用Tk窗口框架——风格类似于gitk
  • git cola <——一个更现代风格的GUI界面

这些工具允许您通过单击将文件移进和移出索引。它们甚至支持在索引中选择和移动文件的部分(单独的更改)。


换个角度看:如果你在使用建议的、相当晦涩的命令时搞砸了:

  • git rm --cached [file]
  • git reset HEAD <file>

...你真的有可能丢失数据——或者至少让数据很难被找到。除非你真的需要以非常高的频率这样做,使用GUI工具可能更安全


没有索引的工作

根据评论和投票,我意识到很多人一直在使用这个索引。我不喜欢。方法如下:

  • 提交我的整个工作副本(典型情况):git commit -a
  • 只提交几个文件:git commit (list of files)
  • 提交除少数修改文件外的所有文件:git commit -a然后修改通过git gui
  • 以图形方式检查工作副本:git difftool --dir-diff --tool=meld的所有更改
git reset HEAD <file>

用于从索引中删除特定文件。

而且

git reset HEAD

用于删除所有索引文件。

只使用git rm --cached [file]从索引中删除文件。

git reset <filename>可以用来从索引中删除添加的文件,前提是这些文件是从来没有承诺

% git add First.txt
% git ls-files
First.txt
% git commit -m "First"
% git ls-files
First.txt
% git reset First.txt
% git ls-files
First.txt

注意: git reset First.txt在提交后对索引没有影响。

这就引出了git restore --staged <file>的话题。它可以用来(假设在第一次提交之后)从索引中删除添加的文件,前提是这些文件是从来没有承诺

% git add Second.txt
% git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file:   Second.txt
% git ls-files
First.txt
Second.txt
% git restore --staged Second.txt
% git ls-files
First.txt
% git add Second.txt
% git commit -m "Second"
% git status
On branch master
nothing to commit, working tree clean
% git ls-files
First.txt
Second.txt
Desktop/Test% git restore --staged .
Desktop/Test% git ls-files
First.txt
Second.txt
Desktop/Test% git reset .
Desktop/Test% git ls-files
First.txt
Second.txt
% git rm --cached -r .
rm 'First.txt'
rm 'Second.txt'
% git ls-files

博士tl;看最后15行。如果您不想与第一次提交、第二次提交、提交前、提交后混淆....始终使用git rm --cached [file]

根据我个人的拙见和我使用git的工作经验,staging area和index是不一样的。当然,我可能错了,但正如我所说,我使用git的经验和我的逻辑告诉我,索引是一个结构,它跟随你对工作区域(本地存储库)的更改,这些更改不会被忽略设置而排除,staging区域是保存已经确认提交的文件,也就是在索引中运行add命令的文件。你没有注意到和意识到“轻微”;差别,是因为你用了 git commit -a -m "comment" 将索引和缓存文件添加到舞台区域,并在一个命令中提交,或者经常使用像IDEA这样的ide。缓存是用来保存索引文件中的更改的。 如果你想从索引中删除之前没有添加到暂存区的文件,之前提出的选项适合你,但是… 如果你已经这样做了,你将需要使用

Git restore --staged <file>
还有,请不要问我10年前在哪里…… 我想念你,这个答案留给后人)