如何在提交之前撤消“git add”?

Posted

技术标签:

【中文标题】如何在提交之前撤消“git add”?【英文标题】:How do I undo 'git add' before commit? 【发布时间】:2010-09-25 18:41:15 【问题描述】:

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

git add myfile.txt

我还没有运行git commit。有没有办法撤消这个,所以这些文件不会包含在提交中?

【问题讨论】:

从 Git v1.8.4 开始,下面所有使用 HEADhead 的答案现在都可以使用 @ 代替 HEAD。请参阅 this answer (last section) 了解您为什么可以这样做。 我做了一个小总结,展示了取消暂存文件的所有方法:***.com/questions/6919121/… 如果你使用 Eclipse,就像在提交对话框中取消选中文件一样简单 这是直接来自 Github 的绝佳资源:How to undo (almost) anything with Git 在发布新答案之前,请考虑此问题已有 25 多个答案。确保您的答案贡献了现有答案之外的内容 【参考方案1】:

您可以在提交之前撤消git add

git reset <file>

这会将其从当前索引(“即将提交”列表)中删除,而不更改任何其他内容。

你可以使用

git reset

没有任何文件名以取消暂存所有到期更改。当有太多文件需要在合理的时间内一一列出时,这会派上用场。

在旧版本的 Git 中,上述命令分别等同于 git reset HEAD &lt;file&gt;git reset HEAD,如果 HEAD 未定义(因为您尚未在存储库中进行任何提交)或模棱两可(因为您创建了一个名为HEAD 的分支,这是您不应该做的愚蠢的事情)。不过,was changed in Git 1.8.2,因此在现代版本的 Git 中,您甚至可以在首次提交之前使用上述命令:

“git reset”(不带选项或参数)用于错误输出时 您的历史记录中没有任何提交,但它现在为您提供 一个空索引(匹配不存在的提交,你甚至都没有)。

文档:git reset

【讨论】:

当然,这不是真正的撤消,因为如果错误的git add 覆盖了之前暂存的未提交版本,我们将无法恢复。我试图在下面的回答中澄清这一点。 git reset HEAD *.ext 其中ext 是您要取消添加的给定扩展名的文件。对我来说是*.bmp & *.zip @Jonny,索引(又称暂存区)包含 所有 文件,而不仅仅是更改的文件。它“开始生命”(当您签出提交或克隆存储库时)作为 HEAD 指向的提交中所有文件的副本。因此,如果您从索引 (git rm --cached) 中删除 一个文件,这意味着您正准备提交一个 删除 该文件的提交。另一方面,git reset HEAD &lt;filename&gt; 会将文件从 HEAD 复制到索引,这样下一次提交就不会显示对该文件所做的任何更改。 我刚刚发现有一个git reset -p,就像git add -p一样。这太棒了! 您实际上 可以恢复覆盖的先前暂存但未提交的更改,但不是以用户友好的方式,也不是 100% 安全(至少我没有找到):转到 .git/objects ,搜索在您要恢复的git add 时创建的文件(61/3AF3... -> 对象 id 613AF3...),然后搜索git cat-file -p &lt;object-id&gt;(可能值得恢复几个小时的工作,但也值得一课)更频繁...)【参考方案2】:

你想要:

git rm --cached <added_file_to_undo>

推理:

刚接触这个的时候,我第一次尝试

git reset .

(撤消我的整个初始添加),只是为了得到这个(不是那么)有用的信息:

fatal: Failed to resolve 'HEAD' as a valid ref.

事实证明,这是因为 HEAD ref(分支?)直到第一次提交之后才存在。也就是说,如果你的工作流程和我一样,你会遇到和我一样的初学者问题:

    cd 到我伟大的新项目目录来试用 Git,新的热点 git init git add .

    git status

    ...很多废话...

    =>该死,我不想添加所有这些。

    谷歌“撤消 git add”

    => 找到堆栈溢出 - 耶

    git reset .

    => 致命:无法将“HEAD”解析为有效参考。

进一步证明,在邮件列表中有a bug logged 反对此无益。

正确的解决方案就在 Git 状态输出中(是的,我将其掩盖为“废话”)

...
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
...

解决方案确实是使用git rm --cached FILE

注意此处其他地方的警告 - git rm 会删除文件的本地工作副本,但如果您使用 --cached,则不会。这是git help rm 的结果:

--缓存 使用此选项仅从索引中取消暂存和删除路径。 工作树文件,无论是否修改,都会留下。

我继续使用

git rm --cached .

删除所有内容并重新开始。但是没有用,因为虽然add . 是递归的,但结果rm 需要-r 递归。叹息。

git rm -r --cached .

好的,现在我回到我开始的地方。下次我打算用-n做一个试运行,看看会添加什么:

git add -n .

在相信git help rm 关于--cached 不会破坏任何东西(如果我拼错了怎么办)之前,我把所有东西都拉到了安全的地方。

【讨论】:

哈。我遵循了同样的过程。除了我放弃并说rm -rf .gitgit init,因为我不相信git rm --cached 会保留我的工作副本。它稍微说明了 git 在某些地方仍然过于复杂。 git unstage 应该只是一个标准的命令,我不在乎我是否可以将它添加为别名。 对我来说 git 说git reset HEAD &lt;File&gt;... git rm --cached 实际上是正确的答案,如果它是 到存储库的初始导入。如果您尝试取消对文件的更改, git reset 是正确的答案。说这个答案是错误的人们正在考虑一个不同的问题。 这实际上会起作用,但仅在第一次提交时,该文件之前不存在,或者git add 命令添加了新文件,但不会更改现有文件。 只是展示了 git 是多么的不直观和复杂。而不是并行的“撤消”命令,您必须找出如何撤消它们。就像试图在快速的沙子中释放你的腿,然后让你的手臂卡住,然后让你的另一只手臂卡住......每个命令都应该通过 GUI 完成,带有选项的下拉菜单项......想想所有的 UI,我们已经获得了生产力的提高,但是我们有一个复古的命令行界面。它不像 git GUI 程序让这变得更直观。【参考方案3】:

如果你输入:

git status

Git 会告诉你暂存的内容等,包括如何取消暂存的说明:

use "git reset HEAD <file>..." to unstage

我发现 Git 在推动我在这种情况下做正确的事情方面做得很好。

注意:最近的 Git 版本 (1.8.4.x) 已更改此消息:

(use "git rm --cached <file>..." to unstage)

【讨论】:

消息会有所不同,具体取决于added 文件是否已被跟踪(add 仅将新版本保存到缓存中 - 此处将显示您的消息)。在其他地方,如果文件之前没有暂存,它将显示use "git rm --cached &lt;file&gt;..." to unstage 太棒了! git reset HEAD &lt;file&gt; 是唯一可以在您想取消暂存文件删除的情况下使用的方法 我的 git 版本 2.14.3 说 git reset HEAD 取消暂存。 自 Git v2.23 以来,消息再次发生了变化。现在显示git restore --staged &lt;file&gt;。有关更新,请参阅 my answer below。【参考方案4】:

澄清一下:git add 将更改从当前工作目录移动到 暂存区(索引)。

这个过程称为暂存。因此,stage 更改(更改的文件)最自然的命令是显而易见的:

git stage

git add 只是git stage 的一个更易于键入的别名

可惜没有git unstage 也没有git unadd 命令。相关的更难猜测或记住,但很明显:

git reset HEAD --

我们可以轻松地为此创建一个别名:

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

最后,我们有了新的命令:

git add file1
git stage file2
git unadd file2
git unstage file1

我个人使用更短的别名:

git a # For staging
git u # For unstaging

【讨论】:

“移动”?这表明它已从工作目录中消失。事实并非如此。 为什么很明显? 实际上,git stagegit add 的别名,这是历史命令,无论是在 Git 还是其他 SCM 上。它已于 2008 年 12 月在“Git 的 git 存储库”中添加,提交 11920d28da,如果我可以说的话。 我同意,Linus Torvalds 没有创建简单的命令,而是为不同的命令创建了一个新词,这很烦人。对于 simmetric,我的意思是:提交 - 取消提交;阶段-非阶段。或者可以用于许多命令的关键字 UNDO:git commit X - git UNDO commit x。很多单词都要背下来,这似乎很自然。那些不经常使用的很容易被遗忘......我们都在这个页面上【参考方案5】:

除了已接受的答案之外,如果您错误添加的文件很大,您可能会注意到,即使在使用“git reset”将其从索引中删除后,它似乎仍会占用@987654322 中的空间@目录。

这没什么好担心的;该文件确实仍在存储库中,但仅作为“松散对象”。它不会被复制到其他存储库(通过克隆、推送),并且空间最终会被回收——尽管可能不会很快。如果你着急,你可以跑:

git gc --prune=now

更新(以下是我试图消除一些可能由最受好评的答案引起的混淆):

那么,git add 真正的撤消是什么?

git reset HEAD &lt;file&gt;?

git rm --cached &lt;file&gt;?

严格来说,如果我没记错的话:

git add 无法撤消 - 一般而言是安全的。

让我们首先回顾一下git add &lt;file&gt; 的实际作用:

    如果&lt;file&gt;之前没有被跟踪git add将其添加到缓存中,并附上其当前内容。

    如果&lt;file&gt;已经被跟踪git add保存当前内容(快照、版本)到缓存。在 Git 中,此操作仍称为 add,(不仅仅是 update 它),因为文件的两个不同版本(快照)被视为两个不同的项目:因此,我们确实正在向缓存中添加一个新项目,最终将在以后提交。

鉴于此,这个问题有点模棱两可:

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

OP 的场景似乎是第一个(未跟踪的文件),我们希望“撤消”从跟踪的项目中删除文件(不仅仅是当前内容)。 如果是这种情况,那么运行git rm --cached &lt;file&gt;就可以了。

我们也可以运行git reset HEAD &lt;file&gt;。这通常更可取,因为它适用于两种情况:当我们错误地添加了已跟踪项目的版本时,它也会撤消。

但有两个注意事项。

首先:(如答案中所指出的)只有一种情况 git reset HEAD 不起作用,但 git rm --cached 起作用:一个新的存储库(没有提交)。但是,实际上,这实际上是一个无关紧要的案例。

第二:注意git reset HEAD 不能神奇地恢复以前缓存的文件内容,它只是从 HEAD 重新同步它。如果我们被误导的git add 覆盖了之前暂存的未提交版本,我们将无法恢复它。这就是为什么严格来说,我们无法撤消 [*]。

例子:

$ 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 commit -a 命令更新新内容,这并不是很关键。


*(编辑:以上内容实际上是正确的,但仍然可能有一些稍微复杂/复杂的方法来恢复已上演但未提交然后被覆盖的更改 - 请参阅 Johannes Matokic 和 iolsmit 的 cmets)

【讨论】:

严格来说,有一种方法可以恢复已被 git add 替换的已暂存文件。正如您提到的 git add 为该文件创建一个 git 对象,该对象不仅在完全删除文件时而且在被新内容覆盖时都将成为松散对象。但是没有命令可以自动恢复它。相反,必须手动识别和提取文件,或者使用仅为这种情况编写的工具(libgit2 将允许这样做)。但这只有在文件非常重要且很大并且无法通过编辑以前的版本来重建时才有效。 纠正自己:一旦找到松散的对象文件(使用元数据,如创建日期/时间)git cat-file 可用于恢复其内容。 另一种方法来恢复已暂存但未提交然后被覆盖的更改另一个git add 是通过git fsck --unreachable 列出所有无法访问的obj,然后您可以通过git show SHA-1_IDgit fsck --lost-found 进行检查,这将> 将悬空对象写入.git/lost-found/commit/.git/lost-found/other/,具体取决于类型。另见git fsck --help【参考方案6】:

撤消已添加的文件使用 Git 非常容易。要重置已添加的myfile.txt,请使用:

git reset HEAD myfile.txt

说明:

暂存不需要的文件后,要撤消,您可以执行git resetHead 是你在本地的文件头,最后一个参数是你的文件名。

我在下图中为您创建了更详细的步骤,包括在这些情况下可能发生的所有步骤:

【讨论】:

图片:"命令添加...""命令添加..." (present simple tense, third person) 图片:想要想要(这里不用俚语)【参考方案7】:
git rm --cached . -r

将以递归方式“取消添加”您从当前目录中添加的所有内容

【讨论】:

我不想取消添加所有内容,只需要一个特定的文件。 如果您之前没有任何提交,也很有帮助。在没有先前提交的情况下,git reset HEAD &lt;file&gt; 会说 fatal: Failed to resolve 'HEAD' as a valid ref. 不,这添加 删除您当前目录中的所有内容。与仅取消暂存更改非常不同。【参考方案8】:

Git 对每个可以想象的动作都有命令,但它需要广泛的知识才能把事情做好,因此它充其量是违反直觉的......

你之前做了什么:

更改了文件并使用了git add .git add &lt;file&gt;

你想要什么:

从索引中删除文件,但保留它的版本并在工作副本中保留未提交的更改:

 git reset HEAD <file>

将文件从 HEAD 重置为最后一个状态,撤消更改并将其从索引中删除:

 # Think `svn revert <file>` IIRC.
 git reset HEAD <file>
 git checkout <file>

 # If you have a `<branch>` named like `<file>`, use:
 git checkout -- <file>

这是必需的,因为 git reset --hard HEAD 不适用于单个文件。

从索引和版本控制中删除&lt;file&gt;,保留未版本控制的文件与工作副本中的更改:

 git rm --cached <file>

从工作副本和版本控制中完全删除&lt;file&gt;

 git rm <file>

【讨论】:

我无法理解 'git reset head ' 和 'git rm --cached 的区别。你能解释一下吗? @jeswang 文件要么对 git 是“已知的”(正在跟踪它们的变化。),要么它们没有被“版本化”。 reset head 撤消您当前的更改,但该文件仍被 git 监控。 rm --cached 将文件从版本控制中取出,因此 git 不再检查它的更改(并且还删除最终索引的当前更改,由先前的 add 告知 git),但更改的文件将保留在您的工作副本中,那是在你硬盘上的文件夹中。 不同之处在于git reset HEAD &lt;file&gt; 是临时的 - 该命令将仅应用于下一次提交,但git rm --cached &lt;file&gt; 将取消暂存,直到再次使用git add &lt;file&gt; 添加它。此外,git rm --cached &lt;file&gt; 意味着如果您将该分支推送到远程,任何拉动该分支的人都会从他们的文件夹中实际删除该文件。 正是我搜索到的git checkout -- &lt;file&gt;thanx!【参考方案9】:

运行

git gui

手动删除所有文件,或者选择所有文件并单击unstage from commit按钮。

【讨论】:

是的,我明白这一点。我只是想含蓄地建议你在你的回答中指出“你可以使用git-gui....”:) 它说,“git-gui:找不到命令”。我不确定这是否有效。 哇,这比做你不理解的命令行简单多了。 这绝对推荐给像我这样的初学者。感谢您写这篇文章! 谢谢。不想冒险所以不得不使用 GUI。【参考方案10】:

这个问题没有明确提出。原因是git add有两层含义:

    新文件添加到暂存区,然后使用git rm --cached file撤消。 将修改过的文件添加到暂存区,然后使用git reset HEAD file撤消。

如有疑问,请使用

git reset HEAD file

因为它在这两种情况下都做了预期的事情。

警告:如果您对已修改的文件(以前存在于存储库中的文件)执行git rm --cached file,则该文件将在@删除987654326@!它仍然存在于您的文件系统中,但如果其他人拉取您的提交,该文件将从他们的工作树中删除。

git status 会告诉您文件是新文件还是修改

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   my_new_file.txt
    modified:   my_modified_file.txt

【讨论】:

+1。此页面上大量高度赞成的答案和 cmets 对 git rm --cached somefile 的行为完全错误。我希望这个答案能在页面上占据显眼的位置,这样它可以保护新手免受所有虚假声明的误导。 这里最好的答案之一,遗憾的是它在列表中很低【参考方案11】:

根据许多其他答案,您可以使用git reset

但是:

我发现这篇很棒的小帖子实际上为 git unadd 添加了 Git 命令(嗯,一个别名):有关详细信息,请参阅 git unadd 或..

简单地说,

git config --global alias.unadd "reset HEAD"

现在可以

git unadd foo.txt bar.txt

替代/直接:

git reset HEAD foo.txt bar.txt

【讨论】:

这是一个很好的答案!【参考方案12】:

如果您处于初始提交状态并且无法使用 git reset,只需声明“Git 破产”并删除 .git 文件夹并重新开始

【讨论】:

一个提示是,如果您添加了远程源,请在删除文件夹之前复制您的 .git/config 文件。 @ChrisJohnsen 评论很到位。有时,您想提交除一个之外的所有文件:git add -A &amp;&amp; git rm --cached EXCLUDEFILE &amp;&amp; git commit -m 'awesome commit'(这也适用于之前没有提交的情况,回复Failed to resolve 'HEAD' 问题)【参考方案13】:

使用git add -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”(还原)、“1”(列表中的第一个条目还原显示)、“返回”以退出还原模式,以及“q”(退出):

$ 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)
$

【讨论】:

【参考方案14】:

当您开始一个新项目时,有一种方法可以避免这个令人烦恼的问题:

为您的新项目创建主目录。 运行git init。 现在创建一个 .gitignore 文件(即使它是空的)。 提交您的 .gitignore 文件。

如果你没有任何提交,Git 会让git reset 变得非常困难。如果您创建一个很小的初始提交只是为了拥有一个,之后您可以根据需要多次 git add -Agit reset 以确保一切正常。

此方法的另一个优点是,如果您以后遇到行尾问题并需要刷新所有文件,这很容易:

检查初始提交。这将删除您的所有文件。 然后再次检查您最近的提交。这将使用您当前的行尾设置检索文件的新副本。

【讨论】:

确认!在 git add 之后尝试了 git reset 。并且 git 抱怨 HEAD 损坏。按照你的建议,我可以毫无问题地来回 git add & reset :) 第二部分有效,但有点笨拙。如何处理行尾,取决于autocrlf 值...这在每个项目中都不起作用,具体取决于设置。 这个答案在发布时是合理的,但现在已经过时了;现在,git reset somefilegit reset 都在进行第一次提交之前工作。自从几个 Git 版本回来后,情况就是如此。 @MarkAmery,你可能是对的(如果你发布了断言的来源会很酷),但是用一两次干净的提交开始你的 repo 仍然有价值。【参考方案15】:

请注意,如果您未能指定修订,则必须包含分隔符。我的控制台中的示例:

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>

(Git 版本 1.7.5.4)

【讨论】:

我试过git reset &lt;path&gt;,没有分隔符就可以正常工作。我也在使用 git 1.9.0。也许它在旧版本中不起作用?【参考方案16】:

也许自从您发布问题以来,Git 已经进化了。

$> git --version
git version 1.6.2.1

现在,你可以试试:

git reset HEAD .

这应该是你要找的。​​p>

【讨论】:

当然,但是您有一个后续问题,即如何取消添加添加的 两个(或更多)文件中的一个。然而,“git reset”手册确实提到“git reset ”与“git add ”相反。【参考方案17】:

如上建议,从暂存区删除新文件(并且仅在新文件的情况下):

git rm --cached FILE

仅对意外添加的新文件使用 rm --cached。

【讨论】:

请注意--cached 是这里非常重要的部分。 -1;不,这不会取消暂存文件,它会暂存文件的删除(实际上并未将其从工作树中删除)。【参考方案18】:

2019 年更新

正如其他人在相关问题中指出的那样(请参阅here、here、here、here、here、here 和 here),您现在可以取消暂存单个文件

git restore --staged <file>

取消暂存所有文件(从 repo 的根目录):

git restore --staged .

注意事项

git restore 是在July 2019 中引入的,并在 2.23 版本中发布。 使用--staged 标志,它恢复索引的内容(这里询问的内容)。

当使用暂存的未提交文件运行 git status 时,现在是 Git 建议用于取消暂存文件的方法(而不是之前 v2.23 之前的 git reset HEAD &lt;file&gt;)。

【讨论】:

【参考方案19】:
git reset filename.txt

将从当前索引中删除一个名为 filename.txt 的文件(也称为“暂存区”,保存“即将提交”的更改),而不更改任何其他内容(工作目录不会被覆盖) .

【讨论】:

【参考方案20】:

要重置特定文件夹(及其子文件夹)中的每个文件,您可以使用以下命令:

git reset *

【讨论】:

实际上,这不会重置每个文件,因为 * 使用 shell 扩展并且它忽略点文件(和点目录)。 您可以运行git status 来查看剩余的内容并手动重置它,即git reset file【参考方案21】:

使用* 命令一次处理多个文件:

git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*

等等

【讨论】:

请注意 * 通常不会包含点文件或“点目录”,除非您明确指定 .*.*.prj【参考方案22】:

只需输入git reset,它就会恢复原状,就好像您自上次提交以来从未输入过git add .。确保你之前已经承诺过。

【讨论】:

碰巧的是,最后一次提交......但我特意询问的是要从提交中删除单个文件,而不是从提交中删除每个文件。【参考方案23】:

假设我创建了一个新文件,newFile.txt:

假设我不小心添加了文件,git add newFile.txt:

现在我想在提交之前撤消这个添加,git reset newFile.txt:

【讨论】:

假设我在第一张照片的意思是我什至没有做过“git.add”。另外,我根本不想要所有这些改变。我的意思是当我执行 git status 时,它不应该显示任何红色文件。我的意思是它应该是同步的,就好像自上次 git push 以来没有一个文件被改变一样。如何实现。 所以假设你只是第一步。并且您想摆脱所有使“newFile.txt”显示为红色的更改。 当我做 git status 的时候。我根本不应该看到任何变化。所有红色文件都应该恢复。 嗨,我认为您的问题是如何从当前树中删除未跟踪的文件。为此,您可以使用“git clean -f -d”。这也将删除未跟踪的目录。 如果您不想删除未跟踪的文件,请忽略“-f”标志。【参考方案24】:

对于特定文件:

git reset my_file.txt git checkout my_file.txt

对于所有添加的文件:

git 重置。 git 结帐。

注意:checkout 会更改文件中的代码并移至上次更新(提交)状态。 reset 不会更改代码;它只是重置标题。

【讨论】:

请解释git reset &lt;file&gt;git checkout &lt;file&gt;的区别。 reset 不会改变文件,只是把它从舞台上移开(=index,它被 git add 放到的地方) checkout 更改文件中的代码并移动到最后更新的状态。重置不会更改它只是重置标题的代码。例如,在推送和签出之前重置用于添加或提交的文件的重置使用用于回到 git add 之前的最后更新/提交的阶段。 reset = 从阶段中删除文件,但更改仍然存在。 checkout = 从存储库中获取更新的文件并将覆盖当前文件【参考方案25】:

要撤消git add,请使用:

git reset filename

【讨论】:

【参考方案26】:

还有交互模式:

git add -i

选择选项 3 取消添加文件。就我而言,我经常想要添加多个文件,并且在交互模式下,您可以使用这样的数字来添加文件。这将占用除 4 之外的所有内容:1、2、3 和 5

要选择一个序列,只需输入 1-5 即可从 1 到 5 全部取值。

Git staging files

【讨论】:

“我很惊讶没有人提到交互模式” - 他们做到了:***.com/a/10209776/1709587【参考方案27】:

此命令将取消隐藏您的更改:

git reset HEAD filename.txt

你也可以使用

git add -p 

添加部分文件。

【讨论】:

【参考方案28】:
git reset filename.txt  

将从当前索引(“即将提交”区域)中删除名为 filename.txt 的文件,而不更改任何其他内容。

【讨论】:

git reset [文件名] ex : git reset src/main/java/com/dao/ImportCsvDataDaoImpl.java【参考方案29】:

git add myfile.txt # 这会将你的文件添加到待提交列表中

与此命令完全相反的是,

git reset HEAD myfile.txt  # This will undo it.

所以,您将处于以前的状态。指定将再次处于未跟踪列表中(以前的状态)。

它将使用该指定文件重置您的头部。所以,如果你的头没有它的意思,它会简单地重置它。

【讨论】:

【参考方案30】:

在 Sourcetree 中,您可以通过 GUI 轻松完成此操作。 您可以检查 Sourcetree 使用哪个命令来取消暂存文件。

我创建了一个新文件并将其添加到 Git。然后我使用 Sourcetree GUI 取消了它。 结果如下:

取消暂存文件 [08/12/15 10:43] git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree reset -q -- path/to/file/filename.java

Sourcetree 使用reset 取消暂存新文件。

【讨论】:

是的,TortoiseGit 可以使用相同的技术,获取常见用例的 Git 命令。

以上是关于如何在提交之前撤消“git add”?的主要内容,如果未能解决你的问题,请参考以下文章

git add 后如何撤销暂存的文件?

通过拉取请求撤消合并?

如何撤消 git pull?

如何修复:错误:'<filename>' 没有提交检查致命:输入“git add”时添加文件失败。在命令提示符下

如何撤消 Github 中的先前提交 [重复]

如何撤消合并请求及其提交?