$ git add foo
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# new file: foo
#
# Untracked files:
# (use "git add ..." to include in what will be committed)
# [...]#
$ git status
# On branch master
# Untracked files:
# (use "git add ..." to include in what will be committed)
# [...]
# foo
nothing added to commit but untracked files present (use "git add" to track)
$
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 add
,用这将把它从当前索引(即将提交的列表)中删除,而不会改变其他东西。
你可以使用
不加任何文件名来解除所有应得的修改。当有太多的文件无法在合理的时间内逐一列出时,这个方法就会很方便。
在旧版本的Git中,上述命令分别等同于
git reset HEAD
和git reset HEAD
,如果HEAD
未定义(因为你的仓库中还没有任何提交)或不明确(因为你创建了一个名为HEAD
的分支,这是一件你不应该做的蠢事),则会失败。这一点在Git 1.8.2中有所改变,所以在现代版本的Git中,你甚至可以在做出第一次提交之前使用上述命令。你想。
推理。
当我刚开始接触这个的时候,我第一次尝试了
(撤销我最初的全部添加),却得到了这个(不是很有用的)信息。
原来,这是因为head ref(分支?)在第一次提交后才存在。 也就是说,如果你的工作流程和我一样,你会遇到和我一样的初学者问题。
git init
git status
... 很多废话滚动的...
=> 妈的,我不想把这些都加进去。
=>。 找到Stack Overflow - 耶
git reset .
。=> fatal: Fatal: Failed to resolve 'HEAD' 作为一个有效的 ref。
进一步发现,在邮件列表中,有'的[bug记录][1]针对这个无益的问题。
而正确的解决方案就在Git状态输出中(是的,我把它当作'废话)。
解决办法确实是使用
git rm --cached FILE
。请注意其他地方的警告 -
git rm
会删除文件的本地工作副本,但如果你使用--缓存则不会。 这里是git help rm
的结果。我继续使用
来删除所有的东西并重新开始。 不过没能成功,因为虽然
add .
是递归的,但原来rm
需要-r
才能递归。 叹了口气。好了,现在我'又回到了开始的地方。 下次我'要用
-n
来做一次干货,看看会增加什么。在相信 "git help rm "关于"--缓存 "不会破坏任何东西之前,我把所有东西都压缩到了一个安全的地方(如果我拼错了怎么办)。
[1]: http://kerneltrap.org/mailarchive/git/2008/2/13/846664/thread
如果你输入
Git 会告诉你什么是暂存,等等,包括如何解除暂存的说明。
我发现在这种情况下,Git能很好地促使我做正确的事情。
注意:最近的Git版本(1.8.4.x)改变了这个信息:
澄清一下。
git add
将当前工作目录中的更改移到staging区域(索引)。这个过程叫做staging。 所以最自然的命令就是stage变化(修改的文件)。
git add
只是git stage
的一个更容易输入的别名。可惜没有 "git unstage "或 "git unadd "命令。 相关的比较难猜或者说难记,但是很明显。
我们可以很容易地为此创建一个别名。
最后,我们还有新的命令。
我个人用的是更短的别名。
除了公认的答案之外,如果你错误添加的文件很大,你可能会注意到,即使用'
git reset
'从索引中删除了它,它似乎仍然占据了.git
目录的空间。这没什么好担心的。 该文件确实还在版本库中,但只是作为一个"松散对象"。 它不会被复制到其他仓库(通过克隆、推送),空间最终会被回收--虽然可能不会很快。 如果你很着急,可以运行。
更新 (以下是我试图澄清一些可能由最高票数的答案引起的混乱)。
那么,"git add "的真正*undo是什么?
git reset HEAD <file>
?还是
git rm --cached <file>
?严格来说,如果我没有弄错的话。 严格来说,如果我没记错的话,没有.
git add
不能撤销 - 安全地,一般来说。让我们先回顾一下
git add <file>
的实际作用。如果
<file>
之前没有被跟踪,git add
就会将其与当前内容一起添加到缓存中**。如果
<file>
已经被跟踪,git add
将当前内容(快照、版本)保存到缓存中。 在Git中,这个操作仍然叫做添加,(而不是单纯的更新),因为一个文件的两个不同版本(快照)被视为两个不同的项目。 因此,我们确实是在缓存中添加了一个新的项目,并将在以后提交。有鉴于此,这个问题略显含糊。
OP'的情况似乎是第一种(未追踪的文件),我们希望用"undo" 从跟踪的项目中删除文件(不只是当前内容)。 如果是这种情况,那么运行
git rm --cached <file>
就可以了。而且我们还可以运行
git reset HEAD <file>
。 一般来说,这是比较好的,因为它在两种情况下都能用。 当我们错误地添加了一个已经被跟踪的项目的版本时,它也会进行撤销。但是有两个注意事项。
首先。 只有一种情况下(正如答案中所指出的),"git reset HEAD "不起作用,但 "git rm --cached "起作用。 一个新的版本库(没有提交)。 但实际上,这只是一个无关紧要的情况。
第二种情况。 要知道,
git reset HEAD
并不能神奇地恢复之前缓存的文件内容,它只是从HEAD重新同步。 如果我们误入歧途的git add
覆盖了之前暂存的未提交的版本,我们就无法恢复。 这就是为什么严格来说,我们不能撤销[*]。例如:{{{5439876}}。
当然,如果我们只是按照通常的懒惰工作流程进行'git add' 只用于添加新文件(情况1),我们通过提交,
git commit -a
命令更新新内容。使用Git可以很容易地撤销一个已经添加的文件。 要重置已经添加的
myfile.txt
,请使用。解释:
当你暂存了不需要的文件后,要撤销,你可以执行
git reset
。Head
是你在本地的文件头,最后一个参数是你的文件名。我在下图中为你创建了更详细的步骤,包括在这些情况下可能发生的所有步骤。
[![git reset HEAD file][1]][1]
[1]: https://i.stack.imgur.com/9JgGD.jpg
将"取消添加"。 从当前目录中递归添加的所有内容。
运转
并手动删除所有文件,或选择所有文件并点击取消提交按钮。
Git的命令涵盖了所有可以想象到的操作,但它需要大量的知识才能正确地进行操作,正因为如此,它最多也是反直觉的......
**你之前做了什么:***
git add .
,或git add <file>
。你想要什么:
git reset head
<!-- language: lang-bash -->
想想
svn revert <file>
IIRC。git reset HEAD git checkout
如果你有一个
<branch>
的名字,比如<file>
,就用。git checkout -- <file>。
这是很有必要的,因为
git reset --hard HEAD
对单个文件不起作用。<file>
,保留未版本的文件和工作副本中的变化。git rm --cached
<file>
。git rm
这个问题没有明确提出来。 原因是
git add
有两层意思。git rm -缓存文件
撤销。添加一个修改过的文件到暂存区,然后用
git reset HEAD file
撤销。如果有疑问,使用
因为在这两种情况下,它都会做预期的事情。
警告:如果你对一个被**修改过的文件(一个之前存在于版本库中的文件)执行 "git rm --cached file",那么这个文件将在 "git commit "时被删除!它仍然存在于你的文件系统中,但如果其他人拉你的提交,这个文件将从他们的工作树中删除。 它仍然存在于你的文件系统中,但如果其他人拉你的提交,该文件将从他们的工作树中删除。
git status
会告诉你这个文件是新文件还是修改。如果你正在进行首次提交,而你又不能使用
git reset
,只需声明"Git破产"。 并删除.git
文件夹,然后重新开始。根据许多其他答案,你可以使用
git reset
。但是:
我发现了这个很棒的小贴子,它实际上为 "git unadd "添加了Git命令(嗯,一个别名)。 详情请看[git unadd][2]。
简单地说。
现在你可以
[1]: https://www.kernel.org/pub/software/scm/git/docs/git-reset.html [2]: https://blog.pivotal.io/labs/labs/git-unadd
使用 "git add -i "从即将到来的提交中删除刚刚添加的文件。 例如
添加你不想要的文件。
进入交互式添加撤销你的添加(在git这里输入的命令是"r"。 (revert),"1" (revert列表中的第一个条目显示),'return'。 退出还原模式,以及"q"。 (退出)。
就是这样!这就是你的证据。 这就是你的证据,显示"foo"。 又回到了未被追踪的列表中。
git remove
或git rm
可用于此,使用--cached
标志。试试吧。当你开始一个新的项目时,这里有一个方法可以避免这个令人烦恼的问题。
git init
。如果你没有任何提交,Git 会让你很难做
git reset
。 如果你只是为了有一个小的初始提交,那么之后你就可以随意地进行 "git add -A "和 "git reset",以使一切都正确。这种方法的另一个好处是,如果你以后遇到行末问题,需要刷新所有文件,那很容易。
请注意,如果你没有指定修订版,那么你必须包含一个分隔符。 我的控制台中的例子。
(Git版本1.7.5.4)
也许在你发布问题后,Git已经进化了。
现在,你可以试试。
这应该是你要找的。
要按照上面的建议,从暂存区中删除新文件(而且只在有新文件的情况下)。
只对意外添加的新文件使用rm -缓存。
要重置特定文件夹(及其子文件夹)中的每个文件,您可以使用以下命令。
使用
*
命令一次处理多个文件。等等。