首页 文章

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

提问于
浏览
7746

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

git add myfile.txt

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


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

30 回答

  • 29

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

    enter image description here

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

    enter image description here

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

    enter image description here

  • 23

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

    与此命令完全相反的是,

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

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

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

  • 41

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

    • new file 添加到暂存区域,然后使用 git rm --cached file 撤消 .

    • modified 文件添加到暂存区域,然后使用 git reset HEAD file 撤消 .

    if in doubt, use

    git reset HEAD file
    

    因为它在两种情况下都做了预期的事情 .

    Warning: 如果对 modified (以前存储在存储库中的文件)的文件执行 git rm --cached file ,则该文件将在 git commit 上删除!它仍然存在于您的文件系统中,但如果有其他人提取您的提交,该文件将从其工作树中删除 .

    git status 将告诉您文件是 new file 还是 modified

    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
    
  • 12

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

    git reset <file>
    

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

    您可以使用

    git reset
    

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

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

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

  • 495

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

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

    等等

  • 14

    Git拥有可以想象的每一个动作的命令,但需要广泛的知识来使事情正确,因此它最好是反直觉的......

    What you did before:

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

    What you want:

    • 从索引中删除文件,但保留其版本并在工作副本中保留未提交的更改:
    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>
    
  • 8721

    我很惊讶没有人提到交互模式:

    git add -i
    

    选择选项3以取消添加文件 . 在我的情况下,我经常想要添加多个文件,使用交互模式,您可以使用这样的数字来添加文件 . 这将采取除4:1,2,3,5之外的所有

    要选择一个序列,只需输入1-5即可从1到5 .

    Git staging files

  • 78

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

  • 69

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

    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)

  • 89

    只需输入 git reset 它就会恢复原状,就像你上次提交时从未输入 git add . 一样 . 确保你之前已经承诺 .

  • 227

    要撤消git add use

    git reset filename

  • 54

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

    BUT:

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

    只是,

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

    现在你可以

    git unadd foo.txt bar.txt
    
  • 146

    也许自从你发布问题以来Git已经发展了 .

    $> git --version
    git version 1.6.2.1
    

    现在,您可以尝试:

    git reset HEAD .
    

    这应该是你正在寻找的 .

  • 7
    git rm --cached . -r
    

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

  • 21

    你要:

    git rm --cached <added_file_to_undo>
    

    推理:

    当我刚接触这个时,我首先尝试过

    git reset .
    

    (撤消我的整个初始添加),只是为了得到这个(不那么)有用的消息:

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

    事实证明,这是因为HEAD ref(branch?)直到第一次提交后才存在 . 那就是你如果你的工作流程像我一样,那么就和我一样遇到同样的初学者问题:

    • cd到我的新项目目录试用Git,新的热点

    • git init

    • git add .

    • git status

    ......很多废话卷轴......

    =>该死,我不想加上所有这些 .

    • google“undo git add”

    =>查找Stack Overflow - yay

    • git reset .

    =>致命:无法将'HEAD'解析为有效的参考号 .

    事实证明,在邮件列表中,这有点无益 .

    并且正确的解决方案就在Git状态输出中(是的,我把它作为'废话'掩盖了)

    ......
    #要提交的更改:
    #(使用“git rm --cached <file> ...”取消暂停)
    ...

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

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

    --cached使用此选项仅从索引中取消暂存和删除路径 . 将保留工作树文件,无论是否已修改 .

    我继续使用

    git rm --cached .
    

    删除所有内容并重新开始 . 虽然没有工作,因为虽然 add . 是递归的,但结果是 rm 需要 -r 才能递归 . 叹 .

    git rm -r --cached .
    

    好的,现在我'm back to where I started. Next time I'将使用 -n 进行干运行,看看会添加什么:

    git add -n .
    

    我把所有东西都拉到一个安全的地方,然后才相信 --cached 关于 --cached 没有破坏任何东西(如果我拼错它会怎么样) .

  • 8

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

    git reset HEAD filename.txt
    

    你也可以使用

    git add -p
    

    添加部分文件 .

  • 16

    For a specific file:

    git reset my_file.txt git checkout my_file.txt

    For all added files:

    git重置 . git checkout .

    注意: checkout 更改文件中的代码并移至上次更新(已提交)状态 . reset 不会更改代码;它只是重置 Headers .

  • 8
    git reset filename.txt
    

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

  • 70

    澄清: 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
    
  • 35

    要从暂存区域中删除新文件(仅在新文件的情况下),如上所述:

    git rm --cached FILE
    

    仅对意外添加的新文件使用rm --cached .

  • 58

    对于已接受的答案的补充,如果您错误添加的文件很大,那么它仍然占据了 .git 目录中的空间 . 这没什么好担心的,文件确实仍在存储库中,但只是作为"loose object",它不会被复制到其他存储库(通过克隆,推送),并且空间最终将被回收 - 尽管可能不是很不久 . 如果您感到焦虑,可以运行:

    git gc --prune=now
    

    更新(以下是我尝试清除最多投票答案可能引起的混淆):

    那么, git add 的真正 undo 是什么?

    git reset HEAD <file>

    要么

    git rm --cached <file>

    严格地说,如果我没弄错的话: none .

    git add cannot be undone - 一般来说安全 .

    让我们先回想一下 git add <file> 实际上做了什么:

    • 如果 <file>not previously trackedgit add adds it to the cache ,其当前内容 .

    • 如果 <file>already trackedgit add saves the current content (快照,版本)到缓存 . 在GIT中,这个动作仍被称为 add ,(不仅仅是更新它),因为文件的两个不同版本(快照)被视为两个不同的项目:因此,我们确实在缓存中添加了一个新项目,最终稍后提交 .

    鉴于此,问题有点含糊:

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

    OP的场景似乎是第一个(未跟踪文件),我们希望"undo"从被跟踪的项目中删除文件(而不仅仅是当前内容) . If 就是这种情况,然后可以运行 git rm --cached <file> .

    我们也可以运行 git reset HEAD <file> . 这通常是可取的,因为它适用于两种情况:当我们错误地添加已经跟踪的项目的版本时,它也会执行撤消操作 .

    但有两点需要注意 .

    第一:(在答案中指出)只有一种情况,其中 git reset HEAD 不起作用,但是 git rm --cached :新的存储库(没有提交) . 但是,实际上,这是一个几乎无关紧要的案例 .

    第二:请注意 git reset HEAD 无法神奇地恢复以前缓存的文件内容,它只是从HEAD重新同步它 . 如果我们被误导了 git add 覆盖了以前上演的未提交版本,我们可以't recover it. That'为什么,严格来说,我们无法撤消[*] .

    例:

    $ 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的评论)

  • 23

    如果您输入:

    git status
    

    git会告诉你什么是上演的,包括如何取消演出的说明:

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

    我发现git在推动我在这样的情况下做正确的事情方面做得非常好 .

    Note: Recent git versions (1.8.4.x) have changed this message:

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

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

    git reset HEAD myfile.txt
    

    Explain:

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

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

    git reset HEAD

  • 47

    git removegit rm 可用于此,带 --cached 标志 . 尝试:

    git help rm
    
  • 32

    git gui
    

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

  • 12

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

    git reset *
    
  • 1997

    在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 - path / to / file / filename.java

    SourceTree使用 reset 来取消暂存新文件 .

  • 8
    git reset filename.txt
    

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

  • 32

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

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

    • 为新项目创建主目录 .

    • 运行 git init .

    • 现在创建一个.gitignore文件(即使它是空的) .

    • 提交.gitignore文件 .

    如果你没有任何提交,Git会很难做 git reset . 如果你创建一个微小的初始提交只是为了拥有一个,之后你可以多次 git add -Agit reset 以便让一切正常 .

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

    • 查看初始提交 . 这将删除所有文件 .

    • 然后再次检查您最近的提交 . 这将使用您当前的行结束设置检索文件的新副本 .

相关问题