你如何撤销最后一次 git add 操作?

204

git 中,是否有可能取消暂存(未提交)的最后一次更改?假设当前分支中有许多文件,其中一些被暂存,一些未被暂存。假设某个愚蠢的程序员不小心执行了以下操作:

git add -- .

...而不是:

git checkout -- .

这位程序员现在能否通过一些神奇的 git 命令取消暂存他最近的更改?还是说他本来就应该在试验之前进行提交?


呵呵。不过这个问题和答案还是很有用的。 - steveha
2
可能是撤销提交前的'git add'的重复问题。 - Jim Fell
我相信这不是重复的问题。另一个问题中的 OP 正在寻找一种方法来撤销或从提交中删除这些文件。而我只想精确地撤销最后一次 git add 命令添加的更改,特别是对于已经有暂存更改并且需要被撤销的文件。虽然不能说另一个问题与此无关。 - Septagram
2
也许他在进行实验之前应该先接受过承诺。 - android.weasel
@android.weasel 是的,那是很多年前的事了... - Septagram
10个回答

311
你可以使用 git reset 命令。这会“取消暂存”你上一次提交之后添加的所有文件。
如果你只想取消暂存某些文件,请使用 git reset -- <file 1> <file 2> <file n> 命令。
同时,也可以通过使用 git reset -p 命令来取消暂存某些文件中的更改。

3
好的,我会尽力进行翻译。下面是翻译的结果:太难过了。我想我的操作方式可能出了问题。因为你提到了“-p”开关,所以我接受了这个答案。谢谢! :) - Septagram
生成(对我来说)错误:致命错误:无法将“HEAD”解析为有效的引用。我还没有提交任何东西(新存储库),只是执行了git add .并后悔了。我不想重置整个添加,只想重置一个目录。git reset -- dir/. 会生成上述错误。 - Francis Davey
啊,我明白我的问题了。我还没有让HEAD指向任何东西,所以git reset失败了(因为它是在HEAD上操作的)。 - Francis Davey

45

您无法撤销最近的git add,但是可以撤销自上次提交以来所有的add操作。在不带提交参数的情况下使用git reset将重置索引(取消已暂存的更改):

git reset

2
"你无法撤销最新的git add操作": 哇,这很令人惊讶,也可能很痛苦。有没有权威的来源证实这一点?此外,它应该是这样的一个好理由吗?谢谢! - Andrew Moylan
@AndrewMoylan:嗯,没有自动的方法来实现。您可以始终“重置”单个文件,或使用“reset -p”取消暂存特定代码块。 - knittl

16

那么对于问题:

这位程序员现在能否使用某种神奇的git命令取消刚刚添加的更改?

真正的答案是不行,你不能只取消上一次的git add

如果我们将问题解释为以下情况:

初始文件:

void foo() {

}

main() {
    foo();
}

首先进行更改,然后跟随git add命令:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

接着执行 git add 命令的第二个更改:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

在这种情况下,git reset -p 无法帮助,因为其最小粒度是行。 git 不知道中间状态的情况:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}
任何更多。

2
我使用加号是因为作为一个新的Git用户,这是一个非常重要的区别,突出了我的朋友所描述的“具有良好的提交卫生”...根据我的个人经验,它被描述为“拼车”(不好!)。 - benc

6
你可以使用 git reset 命令(参见文档)来实现。

4

您可以使用

git reset

撤销最近添加的本地文件
 git reset file_name

撤销特定文件的更改

3

当使用git时,有以下提示:

  1. 如果文件不在仓库中,请使用“git rm --cached <file>...”取消暂存。它会取消暂存文件,但不会将其删除。
  2. 如果文件在仓库中,并且您将其添加为修改文件,请使用“git reset HEAD <file>...”取消暂存。它会保留文件,取消暂存。

据我所知,您无法撤消“git add --”操作,但可以按照上述方法取消暂存一系列文件。


3
如果您想将所有已添加的文件从git中删除以进行提交
git reset

如果您想要删除单独文件,请按以下步骤操作:
git rm <file>

2
  • Remove the file from the index, but keep it versioned and left with uncommitted changes in working copy:

    git reset head <file>
    
  • Reset the file to the last state from HEAD, undoing changes and removing them from the index:

    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>
    

    This is needed since git reset --hard HEAD won't work with single files.

  • Remove <file> from index and versioning, keeping the un-versioned file with changes in working copy:

    git rm --cached <file>
    
  • Remove <file> from working copy and versioning completely:

    git rm <file>
    

0
我建议使用以下命令:
git rm -r --cached 或 git rm --cached 这将撤销你的
git add <your_dir_or_your_file>

返回,同时保持文件不变。


0
根据难度的大小和规模,您可以创建一个临时分支并将当前工作提交到该分支中。
然后切换到原始分支并检出适当的文件以从临时提交中获取。
至少您将拥有当前和先前状态的永久记录可供使用(直到您删除该临时分支为止)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接