我错误地使用以下命令将文件添加到Git:
git add myfile.txt
我还没有运行git commit
命令。我该如何撤销这个操作,以便这些更改不会被提交?
git reset <file>
这将从当前索引中移除文件(即“即将提交”列表),而不会改变其他任何内容。
git reset
git reset HEAD <file>
和git reset HEAD
,如果HEAD
未定义(因为您尚未在存储库中进行任何提交)或模糊不清(因为您创建了一个名为HEAD
的分支,这是一件愚蠢的事情,您不应该这样做),则会失败。然而,这在Git 1.8.2中发生了改变,所以在现代版本的Git中,即使在进行第一次提交之前,您也可以使用上述命令:
文档:git reset"git reset"(没有选项或参数)在您的历史记录中没有任何提交时曾经报错,但现在它会给您一个空的索引(以匹配您甚至不在的不存在的提交)。
git add
覆盖了之前已暂存但未提交的版本,我们就无法恢复它。我在下面的回答中尝试澄清这一点。 - leonbloygit reset HEAD *.ext
是一条 Git 命令,其中 ext
是你想要取消添加的文件的扩展名。例如,如果你想要取消添加所有扩展名为 .bmp
和 .zip
的文件,那么就可以写成 *.bmp
和 *.zip
。请注意,这个命令不会删除文件,只是将它们从 Git 的暂存区中移除。 - boulder_rubygit rm --cached
),这意味着您正在准备进行一个将删除该文件的提交。 另一方面,git reset HEAD <filename>
会将文件从HEAD复制到索引中,以便下一次提交不会显示对该文件进行任何更改。 - Wildcardgit reset -p
命令,就像 git add -p
一样。太棒了! - donquixotegit add
时创建的文件(如61/3AF3...
-> 对象id为613AF3...
),然后运行git cat-file -p <object-id>
(这可能值得恢复数小时的工作,但也教会我们要经常提交)... - Peter Schneider您想要:
git rm --cached <added_file_to_undo>
推理:
当我刚开始接触这个领域时,我首先尝试了
git reset .
我想撤销我最初的添加,结果收到了这个(不太)有用的消息:
fatal: Failed to resolve 'HEAD' as a valid ref.
这是因为 HEAD 引用(分支?)直到第一次提交之后才存在。换句话说,如果你像我一样的工作流程是这样的,你会遇到和我一样的初学者问题:
git init
git add .
git status
... 屏幕滚动了一大堆 ...
=> 哎呀,我不想把所有文件都加入进去。
搜索“撤销 git add”
=> 找到 Stack Overflow - 好耶
git reset .
=> fatal: Failed to resolve 'HEAD' as a valid ref.
进一步地,邮件列表上记录了关于其不友好的 bug。
而正确的解决方案则在 Git status output 中(是的,我忽略了它):
解决方案是使用... # 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
不会破坏任何内容之前,我将所有东西都压缩到一个安全的位置(如果我拼错了会怎么样)。
git reset HEAD <File>...
命令。 - drahnrgit add
命令添加新文件时,而不是对已有文件进行更改。 - naught101如果您输入:
git status
Git会告诉你哪些文件已暂存等信息,还会提供如何取消暂存的指导:
use "git reset HEAD <file>..." to unstage
我发现Git在这种情况下会很好地引导我做正确的事情。
注意:最近的Git版本(1.8.4.x)已更改了此消息:
(use "git rm --cached <file>..." to unstage)
add
的文件已经被跟踪(add
只是将新版本保存到缓存中),那么显示的消息将会不同 - 这里会显示你的消息。否则,如果文件之前没有被暂存,则会显示使用"git rm --cached <file>..."取消暂存
。 - leonbloygit reset HEAD <file>
这个命令可以使用。 - Jelle De Loeckergit reset HEAD
以取消暂存。 - SilverWolf澄清一下: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
git restore --staged path/fo/file
来实现此目的。 - Mikko Rantalainengit
,并带有自定义别名+git gui
和gitk
。例如,我有git stage
和git unstage
。 - Mikko Rantalainen除了已接受的答案,如果您误添加的文件非常大,即使使用“git reset
”从索引中删除它,您可能仍然会注意到它似乎仍占用 .git
目录中的空间。
这并不是什么可担心的事情;该文件确实仍在存储库中,但仅作为“松散对象”。它不会被复制到其他存储库(通过克隆、推送),并且空间最终将被回收 - 尽管可能不会很快。如果您感到焦虑,可以运行:
git gc --prune=now
git add
撤消是什么?
git reset HEAD <file>
?git rm --cached <file>
?git add
是无法安全地撤消的。git add <file>
实际上做了什么:<file>
之前没有被跟踪过,则git add
会将其添加到缓存中,并保存当前内容。<file>
已经被跟踪过,则git add
会将当前内容(快照、版本)保存到缓存中。在Git中,这个动作仍然被称为“添加”,因为一个文件的两个不同版本(快照)被视为两个不同的项目:因此,我们确实向缓存中添加了一个新项目,以便稍后提交。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 commit -a
命令更新新内容时,这并不是非常关键的。当然,如果我们在暂存更改后未提交就被覆盖,则有一些略微狡猾/复杂的方法可以恢复更改-请参阅Johannes Matokic和iolsmit的评论。git cat-file
恢复其内容。 - Johannes Matokic.git/lost-found/commit/
或.git/lost-found/other/
。
另请参见git fsck --help
。 - iolsmitgit add
覆盖它?
如果我创建了一个名为 a.txt
的文件,并将 '1' 作为其内容,那么 git add
如何使其具有 '2' 或其他内容?只是想要一个解释。 - Filip Savicecho 1 > a.txt
后跟着git add a.txt
- 不要立即提交 - echo 2 > a.txt
后跟着git add a.txt
;现在提交,例如git commit -m“create unreachable blob”
并运行git fsck --unreachable
。 - iolsmitGit拥有几乎每个操作所需的命令,但为了正确操作需要广泛的知识,因此它在最好的情况下也是不符合直觉的...
你之前做了什么:
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>
reset head
可以撤销您当前的更改,但该文件仍然受git监视。rm --cached
将文件从版本控制中移除,因此git不再检查它是否有更改(并且还会删除之前add
命令告诉git索引的任何更改),但更改后的文件将保留在您的工作副本中,即在您的硬盘驱动器上的文件夹中。 - sjasgit reset HEAD <file>
的区别在于它是临时的,该命令仅应用于下一次提交,但git rm --cached <file>
将取消暂存状态,直到再次使用git add <file>
添加。另外,git rm --cached <file>
意味着如果您将该分支推送到远程,从该分支提取的任何人都将实际从其文件夹中删除该文件。 - DrewTgit checkout -- <file>
。 - Vladimir Chgit rm --cached . -r
此命令将递归地“取消添加”当前目录中添加的所有内容。
git reset HEAD <file>
命令会提示 fatal: Failed to resolve 'HEAD' as a valid ref.
该命令可用于撤销文件的更改。 - Priya Ranjan Singh运行
git gui
手动删除所有文件,或者选择所有文件并点击 从提交中移除 按钮。
git-gui
...” :) - Alexander Suraphelgit: 'gui' is not a git command. See 'git --help'.
- abdulwasey20问题表述不够清晰,原因是因为 git add
有两种含义:
git rm --cached file
撤销。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
git rm --cached somefile
命令的行为都是彻底错误的。我希望这个回答能够在页面上得到显著的位置,以便保护新手免受所有虚假声明的误导。 - Mark Amery
HEAD
或head
的答案现在可以使用@
代替HEAD
。请参见此答案(最后一节)了解为什么可以这样做。 - user456814