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

Question 1: I added a previously untracked file to the staging area. How can I remove this file from the staging area without removing it from the file system? Answer 1: Use the following command, as described in John Feminella's answer: git rm --cached <file> Question 2: I modified a file already tracked, and added my modifications to the staging area. How can I remove my modifications from the staging area? I.e., how can I unstage my modifications in the file? Answer 2: Use the following command, as described in David Underhill's answer: git reset <file>


当前回答

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

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

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

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


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

Git rm—缓存[文件] git重置HEAD <文件>

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


没有索引的工作

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

提交我的整个工作副本(典型情况):git Commit -a 只提交几个文件:git Commit(文件列表) 提交除了少数修改过的文件以外的所有文件:git Commit -a然后通过git gui进行修改 以图形方式查看工作副本的所有更改:git difftool——dir-diff——tool=meld

其他回答

According to my humble opinion and my work experience with git, staging area is not the same as index. I may be wrong of course, but as I said, my experience in using git and my logic tell me, that index is a structure that follows your changes to your working area(local repository) that are not excluded by ignoring settings and staging area is to keep files that are already confirmed to be committed, aka files in index on which add command was run on. You don't notice and realize that "slight" difference, because you use git commit -a -m "comment" adding indexed and cached files to stage area and committing in one command or using IDEs like IDEA for that too often. And cache is that what keeps changes in indexed files. If you want to remove file from index that has not been added to staging area before, options proposed before match for you, but... If you have done that already, you will need to use

Git restore --staged <file>

还有,请不要问我十年前在哪里…… 我想念你,这个答案留给后人。

这应该为你取消<文件>(不删除或修改文件):

git reset <file>

只使用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恢复的主题——staging <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  

看最后15行。如果您不想与第一次提交、第二次提交、提交前、提交后混淆....总是使用git rm——cached [file]

你想要的:

git rm --cached [file]

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

git reset HEAD <file> 

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

and

git重置

用于删除所有索引文件。