如何在提交前撤消'git add'?

想要改善这篇文章吗? 提供此问题的详细答案,包括引文和为什么答案正确的解释。 答案不够详细的答案可能会被编辑或删除。

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

git add myfile.txt

我还没有运行git commit 。 有一种方法可以撤消此操作,以便这些文件不会包含在提交中?


#1楼

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

#2楼

如上所述,要从登台区域删除新文件(并且仅在新文件的情况下):

git rm --cached FILE

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


#3楼

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

git reset *

#4楼

此命令将取消存储您的更改:

git reset HEAD filename.txt

您也可以使用

git add -p 

添加文件的一部分。


#5楼

Git有可以想象到的每个动作的命令,但是它需要广泛的知识来使事情正确,因此,它充其量是违反直觉的。

您之前做了什么:

  • 更改文件并使用git add .git add <file>

你想要什么:

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

     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不适用于单个文件。

  • 从索引和版本控制中删除<file> ,保留未版本化的文件以及工作副本中的更改:

     git rm --cached <file> 
  • 从工作副本和版本中完全删除<file>

     git rm <file> 

#6楼

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

$> git --version
git version 1.6.2.1

现在,您可以尝试:

git reset HEAD .

这应该是您想要的。


#7楼

如果您正在执行初始提交,并且不能使用git reset ,则只需声明“ Git破产”并删除.git文件夹并重新开始


#8楼

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

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

等等


#9楼

git rm --cached . -r

将递归“取消添加”从当前目录添加的所有内容


#10楼

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

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

如有疑问,请使用

git reset HEAD file

因为在两种情况下都可以完成预期的操作。

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

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

#11楼

只需输入git reset它就会还原,就像您从未输入git add . 自上次提交以来。 确保您之前已作出承诺。


#12楼

还有交互模式:

git add -i

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

要选择一个序列,只需输入1-5即可将1取为5。

Git暂存文件


#13楼

在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-路径/到/文件/文件名.java

Sourcetree使用reset取消登台新文件。


#14楼

可以使用git removegit rm ,带有--cached标志。 尝试:

git help rm

#15楼

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

git reset <file>

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

您可以使用

git reset

没有任何文件名可以取消所有应有的更改。 当在合理的时间内有太多文件不能一一列出时,这可能会派上用场。

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

当您的历史记录中没有任何提交时,“ git reset”(没有选项或参数)会出错,但是现在它为您提供了一个空索引(以匹配您甚至没有参与的不存在的提交)。


#16楼

如果输入:

git status

Git会告诉您已登台的内容等,包括有关如何取消登台的说明:

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

我发现Git在这种情况下勉强我做正确的事情做得很好。

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

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

#17楼

需要说明的是: git add将更改从当前工作目录移动到暂存区 (索引)。

此过程称为暂存 。 所以最自然的命令阶段的变化(修改过的文件)是明显的:

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

#18楼

git reset filename.txt

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


#19楼

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

但:

我发现了这篇很棒的小文章,实际上为git unadd添加了Git命令(还有一个别名):有关详细信息,请参见git unadd

只是,

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

现在你可以

git unadd foo.txt bar.txt

#20楼

要撤消git add ,请使用:

git reset filename

#21楼

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

在此处输入图片说明

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

在此处输入图片说明

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

在此处输入图片说明


#22楼

最直观的解决方案之一是使用SourceTree

您只需从暂存和未暂存中拖放文件即可 在此输入图像描述


#23楼

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

与该命令完全相反的是,

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

因此,您将处于以前的状态。 指定将再次出现在未跟踪列表中(以前的状态)。

它将使用该指定文件重置您的头部。 因此,如果您的头没有它的意思,它将简单地将其重置。


#24楼

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

git reset HEAD myfile.txt

说明:

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

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

git reset HEAD文件


#25楼

git reset filename.txt  

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


#26楼

对于特定文件:

  • git reset my_file.txt
  • git checkout my_file.txt

对于所有添加的文件:

  • git reset。
  • git checkout。

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


#27楼

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

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

git gc --prune=now

更新 (以下是我的尝试,以消除因最不满意的答案而引起的一些混乱):

那么,哪个是git add的真正撤消

git reset HEAD <file>

要么

git rm --cached <file>

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

git add 无法撤消 -通常来说安全的。

让我们首先回顾一下git add <file>实际作用:

  1. 如果<file> 先前未被跟踪 ,则git add 会将其及其当前内容添加到缓存中

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

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

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

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

我们也可以运行git reset HEAD <file> 。 通常,这是可取的,因为它在两种情况下都可以工作:当我们错误地添加已跟踪项目的版本时,它也可以撤消操作。

但是有两个警告。

第一:(在答案中指出)只有一种情况,其中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),然后通过commit git commit -a命令更新新内容,这并不是很关键。


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


#28楼

你要:

git rm --cached <added_file_to_undo>

推理:

当我是新手时,我首先尝试

git reset .

(撤消我的整个初始添加),只是得到了此信息(不是这样),有帮助:

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

事实证明,这是因为HEAD ref(分支?)在第一次提交之后才存在。 也就是说,如果您的工作流程(例如我的)类似于以下内容,您将遇到与我相同的初学者问题:

  1. cd到我伟大的新项目目录中,尝试Git,新热点
  2. git init
  3. git add .
  4. git status

    ...很多废话

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

  5. 谷歌“撤消git添加”

    =>查找堆栈溢出-是

  6. git reset .

    =>致命:无法将“ HEAD”解析为有效的引用。

事实证明,在邮件列表中有一个针对此问题的日志记录一个错误

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

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

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

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

--cached使用此选项可取消登台并仅从索引中删除路径。 无论是否修改,都会保留工作树文件。

我继续使用

git rm --cached .

删除所有内容,然后重新开始。 不过没有用,因为在add . 是递归的,结果表明rm需要-r来递归。 叹。

git rm -r --cached .

好的,现在我回到了起点。 下次,我将使用-n进行空运行并查看将添加的内容:

git add -n .

在信任git help rm关于--cached不会破坏任何内容(以及我拼错的内容该怎么办)之前,我将所有内容压缩到一个安全的地方。


#29楼

当您开始一个新项目时,这是一种避免此烦恼的方法:

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

如果您没有任何提交,Git使得执行git reset真的很困难。 如果您只是为了拥有一个而创建一个微小的初始提交,那么您可以根据需要进行git add -Agit reset多次,以使所有操作正确。

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

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

#30楼

git gui

并手动删除所有文件,或者选择所有文件并单击从提交中取消登台按钮。


#31楼

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

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值