如果您在 Mac 上的 Git 项目中暂存了一个文件,但希望将其排除在下一次提交之外,请在终端中对该文件运行 git restore --staged。这将更新 Git 的暂存区,同时保留工作文件夹中的文件,以便稍后查看或暂存其修改。在提交之前,请检查文件路径并通过 git status 确认结果。

“取消暂存”会改变什么

Git 会将计划进行的下一次提交保存在索引(也称为暂存区)中。一次提交通常包含已暂存的更改;尚未暂存的修改仍保留在您的工作树中。因此,从索引中移除文件会更改为提交所准备的内容,而无需让 Git 重写工作副本。Git 文档指出,git restore --staged 默认从 HEAD 恢复索引。Git 的 restore 文档

当您暂存了错误的文件,或者决定某个文件不应包含在提交中时,这非常有用。只要提供指定路径,该命令就仅针对特定文件生效。不要添加 --worktree:Git 文档说明,同时使用 --staged 和 --worktree 会恢复这两个位置,而当您想要保留修改时,这并不是您期望的结果。

在终端中取消暂存单个文件

在 Mac 上打开终端并切换到仓库文件夹。终端的默认 shell 是 zsh,不过受管理配置的 Mac 可能会使用不同的 shell。Apple 的终端使用指南

首先运行 git status。在“Changes to be committed”(要提交的变更)下找到已暂存的文件,并记下相对于仓库根目录的路径。如果您看到的不是预期的仓库或路径不明确,请在更改任何内容之前停下来检查您当前所在的位置。

例如,要取消暂存 src/Feature.swift,请运行:

git restore --staged -- src/Feature.swift

-- 用于将选项与路径分隔开。对于可能会被误读为选项的文件名,这非常有用。用引号包裹包含空格的路径,以便 zsh 将该路径作为单个参数传递:

git restore --staged -- "Documentation/Setup Notes.md"

请使用 Git 所报告的路径,包括大小写和所有目录名称。如果您已经在仓库的子目录中,Git 对路径的处理可能不够直观;从仓库根目录运行命令并使用完整的仓库相对路径,可以更轻松地核对目标文件。

确认修改仍然存在

再次运行 git status。对于已跟踪的受修改文件,暂存的更改应从“Changes to be committed”(要提交的变更)中消失,并出现在“Changes not staged for commit”(尚未暂存以备提交的变更)下。这意味着工作副本仍然与 HEAD 不同,但索引中已不再包含该预期的更改。Git 将 status 描述为显示 HEAD 与索引之间、以及索引与工作树之间的更改。Git 的 add 文档

您可以通过以下命令检查未暂存的修改:

git diff -- "src/Feature.swift"

该 diff 会比较工作文件与索引。由于对于该已跟踪文件而言,索引现在与 HEAD 一致,因此它会显示您刚刚从暂存区撤出但依然保留的修改。要为以后的提交准备该文件,可以使用 git add -- "src/Feature.swift" 再次暂存它。

新文件和删除操作的处理情况

如果该文件是新文件且从未提交过,则它在 HEAD 中没有版本。在通过 git restore --staged -- path/to/new-file 将其从索引中移除后,该文件应作为未跟踪文件保留在磁盘上。请检查它是否出现在 git status 的“Untracked files”(未跟踪文件)下;如果您想保留它,切勿删除。

如果您暂存了一个已跟踪文件的删除操作,从 HEAD 恢复索引会将已跟踪的版本放回索引中,而工作副本仍保持已删除状态。Status 应显示未暂存的删除。这种区别很重要:取消暂存并不一定会让工作树看起来完全未发生变动;它保留的是磁盘上当前的实际状态。

如果只暂存了文件的一部分

同一个命令会一次性取消暂存该文件已暂存的全部内容。如果您是有意暂存了某些代码块(hunks),并希望仅保留部分代码块处于暂存状态,请不要运行全文件命令。Git 的 restore 命令支持交互式补丁模式,但选择正确的方向和代码块需要格外小心。在使用之前,请查阅 Git 文档中关于 git restore --patch 的行为说明;Git 同样也提供了关于交互式选择要暂存的代码块的 git add --patch 文档说明。Git 的 restore 文档

对于此任务,请避免使用 git restore --worktree 或 git restore --staged --worktree。这些选项会影响工作树,并可能会丢弃您正试图保留的修改。如果 git status 中的结果与您的预期不符,请先停下来检查路径和 diff,然后再运行其他 restore 命令。

来源