简体   繁体   English

如何从 Git 中的暂存区(= 索引 = 缓存)中删除文件?

[英]How to remove a file from the staging area (= index = cache) in Git?

EDIT This question can be understood in two ways, and the optimal answer is different in the two cases. EDIT这个问题可以有两种理解,两种情况下的最佳答案是不同的。

  • Question 1: I added a previously untracked file to the staging area.问题 1:我将以前未跟踪的文件添加到暂存区。 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 :回答 1:使用以下命令,如John Feminella 的回答中所述

     git rm --cached <file>
  • Question 2: I modified a file already tracked , and added my modifications to the staging area.问题 2:我修改了一个已跟踪文件,并将我的修改添加到暂存区。 How can I remove my modifications from the staging area?如何从暂存区删除我的修改? Ie, how can I unstage my modifications in the file?即,如何在文件中取消我的修改?

    Answer 2: Use the following command, as described in David Underhill's answer :回答 2:使用以下命令,如David Underhill 的回答中所述

     git reset <file>

You want:你要:

git rm --cached [file]

If you omit the --cached option, it will also delete it from the working tree.如果省略--cached选项,它也会从工作树中删除它。 git rm is slightly safer than git reset , because you'll be warned if the staged content doesn't match either the tip of the branch or the file on disk. git rmgit reset稍微安全一些,因为如果暂存内容与分支的尖端或磁盘上的文件不匹配,您将收到警告。 (If it doesn't, you have to add --force .) (如果没有,则必须添加--force 。)

这应该为您取消暂存 <file> (无需删除或以其他方式修改文件):

git reset <file>
git reset HEAD <file> 

for removing a particular file from the index.用于从索引中删除特定文件。

and

git reset HEAD

for removing all indexed files.用于删除所有索引文件。

Depending on your workflow, this may be the kind of thing that you need rarely enough that there's little point in trying to figure out a command-line solution (unless you happen to be working without a graphical interface for some reason).根据您的工作流程,这可能是您很少需要的东西,以至于尝试找出命令行解决方案毫无意义(除非您由于某种原因碰巧没有图形界面)。

Just use one of the GUI-based tools that support index management, for example:只需使用支持索引管理的基于 GUI 的工具之一,例如:

  • git gui <-- uses the Tk windowing framework -- similar style to gitk git gui <-- 使用 Tk 窗口框架 -- 与gitk风格类似
  • git cola <-- a more modern-style GUI interface git cola <-- 更现代风格的 GUI 界面

These let you move files in and out of the index by point-and-click.这些使您可以通过点击将文件移入和移出索引。 They even have support for selecting and moving portions of a file (individual changes) to and from the index.它们甚至支持从索引中选择和移动文件的部分(个别更改)。


How about a different perspective: If you mess up while using one of the suggested, rather cryptic, commands:换个角度看怎么样:如果你在使用建议的,相当神秘的命令之一时搞砸了:

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

...you stand a real chance of losing data -- or at least making it hard to find. ...您确实有可能丢失数据——或者至少很难找到。 Unless you really need to do this with very high frequency, using a GUI tool is likely to be safer .除非您确实需要非常频繁地执行此操作,否则使用 GUI 工具可能更安全


Working without the index没有索引的工作

Based on the comments and votes, I've come to realize that a lot of people use the index all the time.根据评论和投票,我开始意识到很多人一直在使用该索引。 I don't.我不。 Here's how:就是这样:

  • Commit my entire working copy (the typical case): git commit -a提交我的整个工作副本(典型情况): git commit -a
  • Commit just a few files: git commit (list of files)只提交几个文件: git commit (list of files)
  • Commit all but a few modified files: git commit -a then amend via git gui提交所有修改过的文件: git commit -a然后通过git gui修改
  • Graphically review all changes to working copy: git difftool --dir-diff --tool=meld以图形方式查看对工作副本的所有更改: git difftool --dir-diff --tool=meld

Only use git rm --cached [file] to remove a file from the index.仅使用git rm --cached [file]从索引中删除文件。

git reset <filename> can be used to remove added files from the index given the files are never committed . 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

NOTE: git reset First.txt has no effect on index after the commit.注意: git reset First.txt在提交后对索引没有影响。

Which brings me to the topic of git restore --staged <file> .这让我git restore --staged <file>git restore --staged <file>的话题。 It can be used to (presumably after the first commit) remove added files from the index given the files are never committed .它可用于(大概在第一次提交之后)从索引中删除添加的文件,因为这些文件从未提交

% 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;dr Look at last 15 lines. tl;dr看看最后 15 行。 If you don't want to be confused with first commit, second commit, before commit, after commit.... always use git rm --cached [file]如果您不想与第一次提交、第二次提交、提交前、提交后……混淆,请始终使用git rm --cached [file]

According to my humble opinion and my work experience with git, staging area is not the same as index.根据我的拙见和我在 git 方面的工作经验,staging area 和 index.html 是不一样的。 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.我当然可能是错的,但正如我所说,我使用 git 的经验和我的逻辑告诉我,该索引是一个遵循您对工作区域(本地存储库)所做更改的结构,不会因忽略设置和暂存区域而排除在外是保留已经确认提交的文件,也就是运行 add 命令的索引中的文件。 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.您没有注意到并意识到“轻微”差异,因为您使用git commit -a -m "comment"将索引和缓存文件添加到git commit -a -m "comment"区并在一个命令中提交或使用 IDEA 之类的 IDE 太频繁。 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>

And, please, don't ask me where I was 10 years ago... I missed you, this answer is for further generations)而且,请不要问我 10 年前我在哪里......我想念你,这个答案是为了后代)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM