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

git add myfile.txt

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


当前回答

运行运行中

git gui

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

其他回答

运行运行中

git gui

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

请注意,如果您没有指定修改,则必须包含一个分隔符。例如,我的控制台:

git reset <path_to_file>
fatal: ambiguous argument '<path_to_file>': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

git reset -- <path_to_file>
Unstaged changes after reset:
M    <path_to_file>

(1.7.5.4版总版)

取消对未承诺更改的修改的 git 添加 :

git reset <file>

这将将文件从当前索引( “ 即将被承诺” 列表) 中删除, 而不更改其它内容 。


取消所有文件的所有更改 :

git reset

在旧版本的 Git 中, 上述命令分别相当于 git 重置 HEAD < file > 和 git 重置 HEAD, 如果 HEAD 未定义( 因为您尚未在仓库中做出任何承诺) 或含糊不清( 因为您创建了一个名为 HEAD 的分支, 这是您不应该做的蠢事 ) , 则上述命令将失败。 但是, 在 Git 1.8. 2 中, 这被更改了 。 因此, 在现代版本的 Git 中, 您可以在第一次承诺之前使用上面的命令 :

当您在历史中没有任何承诺时, “ 将重置” (没有选项或参数) 用于错误退出, 但它现在给了您一个空索引( 匹配不存在的重置, 您甚至没有在 ) 。

文献资料:Git重置

使用 git 添加 - i 来从您即将做出的承诺中删除仅添加的文件。 例如 :

添加您不想添加的文件 :

$ git add foo
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   foo
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]#

进入交互式添加以取消您的添加( 这里输入的 git 命令是“ r”( revert) , “ 1”( 列表返回显示的第一个条目) , “ return” 退出返回模式, 以及“ q” ( quit) :

$ git add -i
           staged     unstaged path
  1:        +1/-0      nothing foo

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +1/-0      nothing [f]oo
Revert>> 1
           staged     unstaged path
* 1:        +1/-0      nothing [f]oo
Revert>> 
note: foo is untracked now.
reverted one path

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> q
Bye.
$

这就是你的证据 证明"foo"又回到了未追踪的名单上

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]
#       foo
nothing added to commit but untracked files present (use "git add" to track)
$

在接受的答案之外, 如果你的错误添加文件是巨大的, 你可能会注意到, 即使从索引中删除了“ 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的评论)