git - 'git rm --cached' 、 'git restore --staged' 和 'git reset' 之间有什么区别

标签 git github staging git-reset git-rm

我遇到了以下三种方法来取消由命令 'git add' 暂存的文件

git rm --cached <file>
git restore --staged <file>
git reset <file>
当我一一运行这些命令时,它们的行为看起来完全相同。
它们之间究竟有什么区别?

最佳答案

两个是一样的;一个不是,除非在特殊情况下。
要理解这一点,请记住:

  • 提交保存 Git 知道的所有文件的快照,按照你说提交它们时的形式;
  • 快照是由 Git 索引中的文件制作的,又名暂存区,又名缓存(同一事物的三个术语);和
  • git add意味着使索引/暂存区/缓存中的副本与我的工作树中的副本匹配(如果更新了工作树副本,则从工作树中复制,或者如果删除了工作树副本,则从索引中删除)。

  • 因此,索引/暂存区始终包含您提议的下一次提交,并且最初是在您执行 git checkout 时从当前提交中播种的。或 git switch以获得该提交。1 因此,您的工作树包含每个文件的第三个副本 2,前两个副本是当前提交中的副本,即 HEAD ,以及索引中的那个。
    考虑到这一点,以下是您的每个命令的作用:
  • git rm --cached file :从索引/暂存区域中删除文件的副本,而不触及工作树副本。提议的下一次提交现在缺少该文件。如果当前提交有该文件,并且您实际上此时进行了下一次提交,则前一次提交和新提交之间的区别在于该文件已消失。
  • git restore --staged file : Git 从 HEAD 复制文件提交到索引中,而不触及工作树副本。索引副本和 HEAD复制现在匹配,无论它们之前是否匹配。现在进行的新提交将具有与当前提交相同的文件副本。
    如果当前提交缺少该文件,则会从索引中删除该文件。所以在这种情况下,它与 git rm --cached 做同样的事情.
  • git reset file : 这复制了 HEAD文件的版本到索引,就像 git restore --staged file .

  • (请注意, git restore ,与这种特殊形式的 git reset 不同,如果您要求,它可以覆盖某个文件的工作树副本。没有 --staged 选项的 --worktree 选项将其定向到只写入索引。)
    旁注:许多人最初认为 index/staging-area 只包含更改,或者只包含更改的文件。事实并非如此,但如果您是这样想的,git rm --cached看起来和其他两个一样。由于这不是索引的工作方式,因此不是。

    1当你上演一些东西时有一些古怪的边缘情况,然后做一个新的git checkout .本质上,如果可以保留不同的暂存副本,Git 会这样做。有关血腥的详细信息,请参阅 Checkout another branch when there are uncommitted changes on the current branch .
    2提交的副本和任何暂存副本实际上以内部 Git blob 对象的形式保存,该对象对内容进行重复数据删除。因此,如果这两个匹配,它们实际上只是共享一个底层副本。如果暂存副本与 HEAD 不同副本,但匹配任何(甚至很多)其他现有的已提交副本或多个副本,暂存副本与所有其他提交共享底层存储。所以称每一个为“副本”是过分的。但作为一个心智模型,它运行得足够好:没有一个可以被覆盖;全新 git add如果需要,将创建一个新的 blob 对象,如果最后没有人使用某个 blob 对象,Git 最终会丢弃它。

    关于git - 'git rm --cached' 、 'git restore --staged' 和 'git reset' 之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65434544/

    相关文章:

    Git 使用 Vim 来提交消息

    git - Azure - 使用arm模板从Visual Studio部署Web应用程序,连接到VSTS git源代码控制

    git - 禁用 git 暂存区

    ruby-on-rails - 将暂存环境添加到工作流程

    eclipse - travis 中的 Sonar `should be relative to project baseDir` 错误

    asp.net - 设置暂存环境

    git - TFS GIT - 如何仅提交某些文件?

    git - 如何在 Atom 中设置 Git-plus 以与 Github 一起工作

    github - github 支持哪些扩展,用于语法突出显示和代码/语言识别?

    git - 如何 git-cherry-pick 只更改某些文件?