我使用命令错误地将文件添加到 Git :

git add myfile.txt

我还没有执行 git 承诺 。 我如何撤销此操作, 使这些更改不被包含在承诺中 ?


当前回答

您可以在 Git 2. 23 版本后使用此命令 :

git restore --staged <filename>

或者,你可以使用这个命令:

git reset HEAD <filename>

其他回答

您可以在 Git 2. 23 版本后使用此命令 :

git restore --staged <filename>

或者,你可以使用这个命令:

git reset HEAD <filename>

如上文所述,从中转区删除新文件(仅在出现新文件的情况下):

git rm --cached FILE

使用 rm -- -- 刻录仅用于新文件不小心添加 。

git 重置命令有助于您修改中转区或中转区和工作树。 Git 的手工能力与您想要的完全一样,意味着您有时需要取消对您用 Git 添加的修改的更改 。

您可以通过调用 git 重置 HEAD < file to change > 来做到这一点。 您有两个选项可以完全清除更改。 git checkout HEAD < file (s) 或 path(s) > 是撤销您中位区域和工作树的更改的快速方法 。

但是要小心这个命令, 因为它会消除你工作树上的所有变化。 Git 根本不知道这些变化, 因为他们从未被执行过。 一旦你执行这个命令, 就没有办法让这些变化回来 。

您可支配的另一个命令是 git 重置 -- hard 。 它同样会破坏您的工作树, 任何未承诺的更改或分阶段更改在运行后都会丢失。 正在运行 git 重置 - HEAD 和 git 检查退出 HEAD 一样。 它不需要文件或工作路径 。

您可以使用 -- 软化的 git 重置。 它重新将仓库设置为您指定的所有更改, 并分阶段进行这些更改。 您已经进行的任何更改都不会受到影响, 您的工作树上的更改也不会受到影响 。

最后, 您可以使用 -- mixed 来重置工作树而不进行任何修改 。 这也可以取消任何正在准备的修改 。

在接受的答案之外, 如果你的错误添加文件是巨大的, 你可能会注意到, 即使从索引中删除了“ git 重置 ” , 它似乎仍然在. git 目录中占据着空间 。

这没什么可担心的;文件确实还在存储库中,但只是作为“空天体”而已。它不会被复制到其他存储库(通过克隆、推推),空间最终会被回收——也许不会很快。如果你急躁,你可以运行:

git gc --prune=now

最新消息(以下是我试图澄清在最受欢迎的答复中可能出现的一些混乱):

那么,Git 添加的哪一种才是真正的反差呢?

git 重置 HEAD < file > 吗 ?

git rm -- ccared <file > 吗 ?

严格地说,如果我没弄错:没有。

无法撤销 git 添加 - 一般来说是安全的 。

让我们首先回忆一下 Git 添加 < file > 实际所做的 :

如果 < file > 之前没有被跟踪, Git 将它添加到缓存中, 并包含其当前内容 。 如果 < file > 已经被跟踪, git 将当前内容( snapshot, 版本) 添加到缓存中。 在 Git 中, 此动作仍然被称作添加( 不仅仅是更新) , 因为文件的两个不同版本( snapshots) 被视为两个不同的项目 : 因此, 我们确实正在缓存中添加一个新项目, 最终要执行 。

有鉴于此,问题略微模糊不清:

我使用命令错误地添加了文件...

OP 的假想似乎是第一个( 未跟踪的文件) , 我们希望“ 未做 ” 从跟踪的项目中删除文件( 不仅仅是当前内容 ) 。 如果是这样, 那么运行 git rm -- cashed < file > 就可以了 。

我们还可以运行 git 重置 HEAD < file > 。 这一般来说比较可取, 因为它在两种情况下都有效: 当我们错误地添加了已经跟踪到的项目的版本时, 它也会发生错误 。

但有两个警告。

第一: (如在答案中指出的) 只有一种情况是, git 重置 HEAD 不起作用, 但是 git rm -- cashed does: 一个新的仓库( 没有承诺 ) 。 但实际上, 这实际上是一个无关紧要的个案 。

第二:请注意, Git 重置 HEAD 无法神奇地收回先前的缓存文件内容, 它只是从 HEAD 中收回它。 如果我们错误的 GIT 添加了一个先前的未承诺版本, 我们无法收回它。 因此, 严格地说, 我们无法撤销 [ *] 。

示例:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # First add of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # Stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # Oops we didn't mean this
$ git reset HEAD file.txt  # Undo?
$ git diff --cached file.txt  # No dif, of course. stage == HEAD
$ git diff file.txt   # We have irrevocably lost "version 2"
-version 1
+version 3

当然,如果我们只是遵循通常的懒惰工作流程,只为添加新文件而做“git add” (第1个案例),而我们通过承诺、 git enture - a 命令更新新内容,这并非非常关键。


* (编辑:上述内容实际上是正确的,但是仍然可以有一些稍有黑客/参与的方式来恢复已经形成但并未实施、但又被推翻的变革——见Johannes Matokic和iolsmit的评论)

运行运行中

git gui

,然后手动删除所有文件,或者选择全部文件,然后从执行按钮中单击非阶段。