git撤销reset - git撤销本地修改




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

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>
    

我使用命令错误地将文件添加到git:

git add myfile.txt

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

到目前为止有48个答案(有些已删除)。 除非您有一些新信息,否则请不要添加新的。


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

与此命令完全相反的是,

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

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

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


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

此过程称为分段 。 因此,最自然的命令来进行更改(更改文件)是显而易见的:

git stage

git add更容易为git stage输入别名

可惜没有git unadd也没有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已经发展了。

$> git --version
git version 1.6.2.1

现在,您可以尝试:

git reset HEAD .

这应该是你正在寻找的。


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

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

等等


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

git help rm

使用git 撤消已添加的文件非常简单,重置已添加的myfile.txt ,使用:

git reset HEAD myfile.txt

说明:

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

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


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

假设我意外添加了文件, git add newFile.txt

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


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

我创建了一个新文件并将其添加到git中。 然后我使用SourceTree gui取消了它。 这是结果:

Unstaging文件[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新文件。


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


对于已接受的答案的补充,如果您错误添加的文件很大,您可能会注意到,即使在使用' 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 会将其 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 lost irrevocably "version 2"
-version 1
+version 3

当然,如果我们只是按照通常的懒惰工作流程来执行'git add'仅用于添加新文件(案例1),并且我们通过commit, git commit -a命令更新新内容,这不是非常关键。

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


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

git reset <file>

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

您可以使用

git reset

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

在旧版本的Git中,上面的命令分别等同于git reset HEAD <file>git reset HEAD ,如果未定义HEAD (因为你还没有在你的repo中进行任何提交)或者模糊(因为你),它将会失败创建了一个名为HEAD的分支,这是一个你不应该做的愚蠢的事情。 但是在Git 1.8.2中已经改变了 ,所以在现代版本的Git中,你甚至可以在第一次提交之前使用上面的命令:

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


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

但:

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

只是,

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

现在你可以

git unadd foo.txt bar.txt

此命令将取消暂停您的更改:

git reset HEAD filename.txt

你也可以使用

git add -p 

添加部分文件。


要撤消git add use

git reset filename


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

git reset *

git gui

并手动删除所有文件或选择所有文件并单击“ 提交”按钮。


这是一种在开始新项目时避免这个棘手问题的方法:

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

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

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

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

git reset filename.txt

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


git reset filename.txt  

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





git-stage