【问题标题】:How to remove a file from the staging area (= index = cache) in Git?如何从 Git 的暂存区(= 索引 = 缓存)中删除文件?
【发布时间】:2010-02-08 16:58:21
【问题描述】:

EDIT这个问题可以从两个方面理解,两种情况下的最优答案是不同的。

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

    答案 1:使用以下命令,如John Feminella's answer 中所述:

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

    答案 2:使用以下命令,如David Underhill's answer 中所述:

    git reset <file>
    

【问题讨论】:

  • 您的意思是“重置为之前的内容”还是“删除,因为我不再需要该文件”?
  • 在我的情况下是一样的,因为该文件之前不存在...
  • @hcs42 接受的答案是错误的,会导致许多人删除文件。第二个最受欢迎的答案 (git reset &lt;file&gt;) 是正确的。您是否可以将绿色复选标记移至正确答案?
  • @MartinJambon 感谢您强调某些人遇到的问题。问题是我的问题可以通过两种方式来理解。接受的答案非常适合我的问题,但它让一些想要回答不同问题的人陷入困境。我编辑了问题以包含这两个问题。
  • @hcs42 太棒了,谢谢!

标签: git


【解决方案1】:

你想要:

git rm --cached [file]

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

【讨论】:

  • 这也很好用,例如你不小心签入了一些构建中间体或本地配置文件,这些文件没有进入你的 .gitignore;使用 git rm --cached 将它们从 repo 中删除,将相关文件或目录添加到 .gitignore,正常暂存和提交。它们将从 repo 中消失,但在您的本地树中保持不变,您不会意外再次签入它们。
  • 这也会在您提交和推送后从 repo(远程)中删除文件。
  • 这不会将其从索引中删除,而是将其标记为已在索引中删除。
  • 这个答案很可能是错误的,因为它从 repo 中删除了一个文件(正如@powder366 已经提到的),这不是预期的结果。
  • 这个解决方案对我不起作用。它将指定的文件标记为已删除,然后将其从本地 repo 中删除。
【解决方案2】:

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

git reset <file>

【讨论】:

  • 这将删除特定文件的最新更改,但在提交和推送后将其保留在 repo(远程)中。
  • 这是我一直在寻找的答案。请注意,您不必指定HEAD
  • 好点@MichaelDorst。我已将答案更新为省略 HEAD!
  • 我喜欢 git-reset 手册页。它说'git reset '与'git add '相反。对于曾经使用 git-add 并且只想撤消 git-add 的人来说,很高兴知道这一点。
【解决方案3】:
git reset HEAD <file> 

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

git reset HEAD

用于删除所有索引文件。

【讨论】:

    【解决方案4】:

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

    git reset &lt;filename&gt; 可用于从索引中删除添加的文件,因为这些文件从未提交

    % 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 &lt;file&gt; 的话题。鉴于文件从未提交,它可用于(大概在第一次提交之后)从索引中删除添加的文件。

    % 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 查看最后 15 行。如果您不想与第一次提交、第二次提交、提交前、提交后....混淆,请始终使用git rm --cached [file]

    【讨论】:

      【解决方案5】:

      根据您的工作流程,这可能是您很少需要的东西,因此尝试找出命令行解决方案毫无意义(除非您碰巧在没有图形界面的情况下工作)。

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

      • git gui gitk
      • git cola

      这些允许您通过点击将文件移入和移出索引。它们甚至支持从索引中选择和移动文件的某些部分(个别更改)。


      换个角度看看怎么样:如果你在使用建议的、相当神秘的命令之一时搞砸了:

      • git rm --cached [file]
      • git reset HEAD &lt;file&gt;

      ...您很有可能会丢失数据——或者至少很难找到。除非您确实需要非常频繁地执行此操作,否则使用 GUI 工具可能更安全


      在没有索引的情况下工作

      根据 cmets 和投票,我开始意识到很多人一直在使用索引。我不。方法如下:

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

      【讨论】:

      • @Martin:我想这取决于您的工作流程。在我的方法中,我从不直接使用索引。当我想保存我的工作时,我只需使用git commit -a 进行完整提交。当我回答这个问题时,这是因为我已经完成了(一个异国情调的)“inverse cherry pick”,它为您将文件放入索引中,但我想在提交之前编辑一个文件。我在编辑时将文件从索引中取出,以便差异按照我习惯的方式工作。
      • 我的用例非常狭窄而且确实没用:创建一个分支;只为分支添加充满文件的文件夹;切换到主人;合并; ops,将错误的文件夹添加到 master,将其添加到 gitignore;文件不会从提交中删除——当然,更好的解决方案是直接使用rm,但我首先认为切换分支不会杀死 ignored 文件夹。 但是...我确实使用了 github“基于 gui”的工具,这对我来说已经足够好了,并且确实支持一些索引管理,但它不支持这一点。那又怎样,我应该使用 2 gui 来进行狭窄的使用吗?还是不能同意答案。
      • 这是一个绝对不受欢迎的答案。但是,我很确定我建议的方法适合某些人(包括我自己)。我每年都会使用其中一种工具来操纵索引几次。
      • 如今的编程编辑器和 IDE 很可能支持图形索引操作。至少 GitHub 的 Atom 可以。
      • 我更喜欢 cli 界面而不是 gui,尽管它更危险。它允许我在没有 gui 的情况下使用 git,这让我感到很舒服(而不是当我无法在远程服务器上安装此类工具时迷失方向)。所有这一切都说这个答案是完全有效的,不值得“cli 精英”投票,+1 提供了一个好的 gui 替代品!
      【解决方案6】:

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

      Git restore --staged <file>
      

      还有,请不要问我 10 年前我在哪里... 我想你了,这个答案是为了后代)

      【讨论】:

      • "index is a structure that follow your changes to your working area" 事实并非如此,原因有二: (1) Git 不会跟踪您工作区域中的文件,直到您执行“git add”在他们。 (2) Git 文档清楚地表明索引包含执行“git add”的更改:git-scm.com/docs/git-add:“git-add - 将文件内容添加到索引”。另见:reddit.com/r/git/comments/2szztw/…
      猜你喜欢
      • 2013-11-12
      • 2023-03-17
      • 2010-12-03
      • 2019-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多