我错误地使用以下命令将文件添加到了Git:
git add myfile.txt
我还没有跑步git commit
。有一种方法可以撤消此操作,以便这些文件不会包含在提交中?
git checkout
不会从提交索引中删除分段的更改。它只会将未暂存的更改还原到上一次提交的修订版-顺便说一句,这也不是我想要的,我想要这些更改,我只希望它们在以后的提交中。
我错误地使用以下命令将文件添加到了Git:
git add myfile.txt
我还没有跑步git commit
。有一种方法可以撤消此操作,以便这些文件不会包含在提交中?
git checkout
不会从提交索引中删除分段的更改。它只会将未暂存的更改还原到上一次提交的修订版-顺便说一句,这也不是我想要的,我想要这些更改,我只希望它们在以后的提交中。
Answers:
您可以git add
在提交之前先撤消
git reset <file>
这会将其从当前索引(“即将提交”列表)中删除,而无需进行其他任何更改。
您可以使用
git reset
没有任何文件名可以取消所有应有的更改。当在合理的时间内有太多文件不能一一列出时,这可能会派上用场。
在旧版本的Git中,上述命令分别等同于git reset HEAD <file>
和git reset HEAD
,如果HEAD
未定义(因为您尚未在存储库中进行任何提交)或模棱两可(因为您创建了一个名为HEAD
,这是一个愚蠢的事你不应该这样做)。这是在Git的1.8.2改变,虽然如此,在Git中的现代版本,您可以让您的第一次提交使用上面的命令,即使事先:
当您的历史记录中没有任何提交时,“ git reset”(无选项或参数)会出错,但是现在它为您提供了一个空索引(以匹配您甚至没有提交的不存在的提交)。
git add
覆盖了以前暂存的未提交版本,我们将无法恢复它。我试图在下面的答案中澄清这一点。
git reset HEAD *.ext
这里ext
是您要unadd该扩展名的文件。对我来说是*.bmp
&*.zip
git rm --cached
则意味着您正在准备进行删除该文件的提交。 git reset HEAD <filename>
另一方面,会将文件从HEAD复制到索引,以便下次提交时不会显示对该文件所做的任何更改。
git reset -p
类似git add -p
。这太棒了!
git add
要恢复时创建的文件(61/3AF3...
- >对象ID 613AF3...
),然后git cat-file -p <object-id>
(恢复几个小时的工作可能值得,但值得一提的是,可以更频繁地
你要:
git rm --cached <added_file_to_undo>
推理:
当我是新手时,我首先尝试
git reset .
(撤消我的整个初始添加),只是得到了此信息(不是这样),有帮助:
fatal: Failed to resolve 'HEAD' as a valid ref.
事实证明,这是因为HEAD ref(分支?)在第一次提交之后才存在。也就是说,如果您的工作流程(例如我的)类似于以下内容,您将遇到与我相同的初学者问题:
git init
git add .
git status
...很多废话
=>该死,我不想添加所有这些内容。
谷歌“撤消git添加”
=>查找堆栈溢出-是
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
不破坏任何东西(如果我拼错了怎么办)之前,我将所有东西都拉到了安全的地方。
rm -rf .git
,git init
否则因为我不信任git rm --cached
保留我的工作副本。它说明了git在某些地方仍然过于复杂。git unstage
应该只是一个标准的标准命令,我不在乎是否可以将其添加为别名。
git reset HEAD <File>...
git add
命令添加了新文件,但是对现有文件没有更改。
如果输入:
git status
Git会告诉您已登台的内容等,包括有关如何取消登台的说明:
use "git reset HEAD <file>..." to unstage
我发现Git在这种情况下勉强我做正确的事情做得很好。
注意:最新的Git版本(1.8.4.x)更改了此消息:
(use "git rm --cached <file>..." to unstage)
add
已跟踪ed文件(add
唯一已将新版本保存到缓存的文件-此处将显示您的消息)。在其他地方,如果文件先前未暂存,则将显示use "git rm --cached <file>..." to unstage
git reset HEAD <file>
一个也是唯一一个将在个案工作要unstage删除文件
git reset HEAD
说不定。
澄清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 stage
是的别名git add
,这是Git和其他SCM上的历史命令。我可以说,它已于2008年12月在commit的“ Git的git存储库”中添加为11920d28da。
除了已接受的答案之外,如果您错误添加的文件很大,您可能会注意到,即使使用' 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中,此操作仍称为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),然后通过提交来更新新内容,那么这并不是很关键。 git commit -a
命令。
*(编辑:以上内容实际上是正确的,但是仍然可能有一些稍作修改/令人费解的方法来恢复已上演但未提交但随后被覆盖的更改-请参阅Johannes Matokic和iolsmit的评论)
git cat-file
可以恢复其内容。
git add
是通过git fsck --unreachable
将列出所有可达OBJ,然后你就可以通过检查git show SHA-1_ID
或者git fsck --lost-found
是意志>写悬空物体进入.git/lost-found/commit/
或者.git/lost-found/other/
,根据类型。另请参阅git fsck --help
使用Git 撤消已经添加的文件非常容易。要进行重置myfile.txt
(已添加),请使用:
git reset HEAD myfile.txt
说明:
暂存不需要的文件后,可以撤消git reset
。Head
是本地文件的头,最后一个参数是文件名。
我已为您在下图中创建了更详细的步骤,包括在这些情况下可能发生的所有步骤:
git rm --cached . -r
将递归“取消添加”从当前目录添加的所有内容
git reset HEAD <file>
说fatal: Failed to resolve 'HEAD' as a valid ref.
跑
git gui
并手动删除所有文件,或者选择所有文件并单击从提交中取消登台按钮。
git-gui
....” :)
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>
reset head
撤消当前更改,但git仍在监视该文件。rm --cached
从版本控制中删除文件,因此git不再检查它的更改(并且还删除了最终索引的当前更改,由先前告诉git add
),但是更改后的文件将保留在您的工作副本中,即在您的文件夹中在硬盘上。
git reset HEAD <file>
临时的-该命令将仅应用于下一次提交,但git rm --cached <file>
将取消登台,直到使用再次添加为止git add <file>
。同样,这git rm --cached <file>
意味着如果您将该分支推送到远程,拉该分支的任何人都会从其文件夹中实际删除该文件。
这个问题没有明确提出。原因是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
。我希望这个答案能在页面上占据一个突出的位置,以防止新手被所有错误的陈述所误导。
用于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)
$
git remove
或git rm
可用于带有--cached
标志。尝试:
git help rm
git rm --cached ...
将从git repo中删除文件。它们仍将存在于您的计算机上,但这与取消暂存文件更改非常不同。对于任何对此绊脚石的人来说,这不是一个有效的答案。
当您开始一个新项目时,这是一种避免此烦恼的方法:
git init
。Git真的很难做 git reset
如果您没有任何提交,。如果创建一个微小的初始提交只是为了有一个起见,之后,你可以git add -A
和git reset
尽可能多的时间,你才能得到一切权利要。
此方法的另一个优点是,如果以后遇到行尾麻烦并且需要刷新所有文件,则很容易:
autocrlf
值...取决于设置,这并非在每个项目中都有效。
git reset somefile
现在git reset
两者都可以在进行第一次提交之前工作。自从几个Git版本发布以来就是这种情况。
自您发布问题以来,Git也许已经发展了。
$> git --version
git version 1.6.2.1
现在,您可以尝试:
git reset HEAD .
这应该是您想要的。
请注意,如果您未能指定修订版本,则必须包含分隔符。我的控制台示例:
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 rm --cached FILE
rm --cached仅用于意外添加的新文件。
--cached
是这里非常重要的部分。
对于特定文件:
- git reset my_file.txt
- git checkout my_file.txt
对于所有添加的文件:
- git reset。
- git checkout。
注意:检出会更改文件中的代码,并移至上次更新(提交)状态。重置不会更改代码;它只是重置标题。
git reset <file>
和git checkout <file>
。
还有交互模式:
git add -i
选择选项3取消添加文件。就我而言,我经常想添加多个文件,并且在交互模式下,您可以使用像这样的数字来添加文件。除了4:1、2、3和5外,这将占用所有其他内容
要选择一个序列,只需输入1-5即可将1取为5。
要撤消git add
,请使用:
git reset filename
git reset filename.txt
将从当前索引的“即将提交”区域中删除一个名为filename.txt的文件,而不进行任何其他更改。
git add myfile.txt
#这会将您的文件添加到待提交列表中
与该命令完全相反的是,
git reset HEAD myfile.txt # This will undo it.
因此,您将处于以前的状态。指定将再次出现在未跟踪列表中(以前的状态)。
它将使用该指定文件重置您的头部。因此,如果您的头没有它的意思,它将简单地将其重置。
在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
新文件。
git reset filename.txt
将从当前索引的“即将提交”区域中删除一个名为filename.txt的文件,而不进行任何其他更改。
HEAD
或者head
现在可以使用@
代替HEAD
代替。请参阅此答案(最后一部分),以了解为什么可以这样做。