如何在Git中放弃未暂存的更改?

6208

我如何抛弃工作副本中未在索引中的更改?


16
git-clean 只会从工作树中删除未被跟踪的文件。详见 https://git-scm.com/docs/git-clean。 - Yega
36
为了澄清Asenar上面的评论,git-clean -df可能会很危险。它会删除本地未被跟踪的文件(例如由.gitignore覆盖的文件)。请仔细阅读以下所有内容,并考虑使用git checkout .代替。 - jacanterbury
26
"git clean -df"警告!我尝试过这个命令,丢失了一些关键文件夹,无法恢复...痛苦! - Gabe Karkanis
72
执行 git status 命令会提供建议,告诉你如何操作!执行 git checkout -- . 命令即可。 - Paulo
28
从2019年7月开始,git status 建议使用 git restore 命令来达到相同的目的,这是一个新的命令。请参考我的2019更新 - prosoitos
显示剩余6条评论
41个回答

66

我发现这篇文章很有帮助,可以解释何时使用哪个命令:http://www.szakmeister.net/blog/2011/oct/12/reverting-changes-git/

有几种情况:

  1. 如果您尚未将文件加入暂存区,则使用git checkout。Checkout "更新工作树中的文件以匹配索引中的版本"。 如果文件尚未被暂存(也就是没有添加到索引中)……这个命令将基本上将文件还原为您最后提交的内容。

    git checkout -- foo.txt

  2. 如果您已经将文件加入暂存区,则使用git reset。Reset会更改索引以匹配某次提交。

    git reset -- foo.txt

我怀疑使用git stash是一个流行的选择,因为它比较安全。如果您在使用git reset时意外删除了太多内容,您随时可以回退到git stash保存的版本。Reset默认是递归的。

请查看上面的文章获取更多建议。


52

如果你不想保留未暂存的更改(尤其是暂存的更改是新文件),我发现这很方便:

git diff | git apply --reverse

48
当你键入“git status”命令时,会显示提示信息:(使用“git checkout --…”放弃工作目录中的更改)
例如:git checkout -- .

1
因为它不能帮助快速丢弃所有文件而被踩。三个点表示您需要列出所有文件。如果您需要一次性丢弃大量文件,例如在合并操作之后,您已经将所有想要保留的修改都暂存了下来,则这种情况尤其糟糕。 - usr-local-ΕΨΗΕΛΩΝ
3
当然,正确的命令是"git checkout -- .",只有一个点。在注释中,三个点是语法上的东西,表示还有很多其他选项可以使用。 - Josef.B

46

如果出现问题,您可以使用git stash将其还原。与此处其他答案类似,但此答案还会删除所有未提交的文件和未提交的删除操作:

git add .
git stash
如果您确认一切都没问题,那么就丢掉这个存档:
git stash drop

来自Bilal Maqsood的答案用git clean对我也有效,但是使用存储区更加控制 - 如果我不小心做了什么,我仍然可以找回我的更改。

更新

我认为还有1个更改(不知道为什么以前这对我起作用):

git add . -A而不是git add .

没有-A,删除的文件将不会被提交到暂存区。


45

git checkout -f


man git-checkout:

-f, --force

切换分支时,即使索引或工作树与HEAD不同也继续进行。这可用于丢弃本地更改。

从索引中检出路径时,不会因合并条目失败而失败;相反,未合并的条目将被忽略。


3
这将放弃索引中的更改!! (而原帖要求保留它们。) - Robert Siemer

39

我没有丢弃任何更改,而是将我的远程重置为原点。注意-此方法是完全恢复您的文件夹与存储库相同。

所以我这样做是为了确保它们不会在我git reset时停留(稍后-不包括Origin / branchname上的gitignores)

注意:如果您想保留尚未跟踪但不在GITIGNORE中的文件,则可能希望跳过此步骤,因为它将擦除这些未跟踪的文件(感谢@XtrmJosh)。

git add --all
然后我
git fetch --all

然后我重置为原点

git reset --hard origin/branchname

这将使它回到原点。就像重新克隆分支一样,同时在本地保留所有被Git忽略的文件。

根据下面用户评论的更新: 重置到当前用户所在的分支。

git reset --hard @{u}

这是我的首选选项,但你为什么要先添加所有更改呢?据我所知,这只会修改 Git 文件中的目录列表,而使用 git reset --hard,这些更改在任何情况下都将丢失,同时目录仍将被删除。 - XtrmJosh
我不用Mac或Linux,GitHub Windows PowerShell有时会在重置后留下文件。我认为这是因为git reset将存储库中的所有文件设置为其原始状态。如果它们没有被添加,它们就不会被触及。然后桌面客户端会捕捉到“嘿,这个文件在这里需要提交”。 - Nick
有道理。我不使用Windows,所以没有遇到过这个问题(至少在过去几个月里没有使用Windows,之前也记不清了——那是一个巨大的令人遗憾的模糊期)。在你的主要答案中注明这个原因可能值得一提 :) - XtrmJosh
我也在 Mac 上遇到了这个问题。如果文件没有被跟踪,有时候 git reset 不会对其进行操作。我无法确定具体的原因,但当出现这种情况时,如果我执行 reset 操作,而且仍然有一个或两个未提交的文件,我会添加 --all 参数并再次执行 reset --hard。 - Nick
3
我喜欢的一种很不错的变体是 git reset --hard @{u},它将分支重置到当前远程跟踪分支所在的位置。 - user2221343
显示剩余3条评论

36

尝试了以上所有解决方案,但仍无法摆脱新的未暂存文件。

使用 git clean -f 删除这些新文件 - 但务必小心! 注意强制选项。


34

要永久丢弃更改:

git reset --hard

要将更改保存到以后再处理:

git stash

25

只需使用:

git stash -u

完成。容易。

如果您真的关心您的存储库栈,那么您可以继续使用 git stash drop。但在那时,最好使用以下方法(来自Mariusz Nowak):

git checkout -- .
git clean -df

然而,我最喜欢的是git stash -u,因为它可以在一个命令中"丢弃"所有跟踪和未跟踪的更改。但是git checkout -- .只会丢弃已跟踪的更改,而git clean -df只会丢弃未跟踪的更改... 而且输入这两个命令太麻烦了(far too much work) :)


注意:git stash -u 将很快(Git 2.14.x/2.15,2017年第三季度)有所改进:https://dev59.com/LGkv5IYBdhLWcg3wkBka#46027357 - VonC
如果我理解 OP 的问题正确的话,索引文件应该被保留。只有未暂存的更改应该被删除。因此,在我看来应该使用 git stash -k 命令。 - snap

23

简单来说

git stash

这将会移除您所有的本地更改。您也可以通过说

git stash apply 

或者 git stash pop


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