题 如何将Git托管项目中的所有本地更改还原到以前的状态?


我有一个项目,我跑了 git init。 经过几次提交,我做到了 git status 它告诉我一切都是最新的,没有本地变化。

然后我做了几个连续的更改,并意识到我想把所有东西扔掉,然后回到原来的状态。这个命令会为我做吗?

git reset --hard HEAD

1549
2017-07-18 07:52


起源




答案:


如果要还原对工作副本所做的更改,请执行以下操作:

git checkout .

如果要还原对索引所做的更改(即已添加的更改),请执行此操作。 警告这会重置你掌握的所有未提交的提交!

git reset

如果要还原已提交的更改,请执行以下操作:

git revert <commit 1> <commit 2>

如果要删除未跟踪的文件(例如,新文件,生成的文件):

git clean -f

或未跟踪的目录(例如,新的或自动生成的目录):

git clean -fd

2821
2017-07-18 07:57



fwiw经过这么长时间, git checkout path/to/file 只会将本地更改还原为 path/to/file - Matijs
下面的答案+1也提到git clean -f(删除未跟踪的更改)和-fd(也删除未跟踪的目录) - ptdev
如果您还想清理未跟踪的文件,请阅读此内容 stackoverflow.com/questions/61212/... - Surasin Tancharoen
git checkout . 和 git reset [--hard HEAD] 不行,我不得不做 git clean -fd 恢复我的更改。 - BrainSlugs83
git reset 不会重置您的更改, git reset --hard 那样做。 - Cerin


注意:您可能还想运行

git clean -fd

git reset --hard

 删除未跟踪的文件,其中git-clean将从被跟踪的根目录中删除不在git跟踪下的任何文件。警告 - 小心这个!首先使用git-clean进行干运行是有帮助的,看看它会删除什么。

当您收到错误消息时,这也特别有用

~"performing this command will cause an un-tracked file to be overwritten"

当你和你的朋友都添加了一个同名的新文件时,可能会发生这种情况,一个是正在更新工作副本,但他首先将它提交到源代码控制中,而你不关心删除未经跟踪的副本。

在这种情况下,执行干运行还将帮助显示将被覆盖的文件列表。


334
2017-07-20 05:37



文件清理命令是“git clean -f”。使用“git clean -d”删除未跟踪的目录 - Jonathan Mitchell
git clean -fd(-d需要强制) - electblake
-n或--dry-run是干运行的标志。 - stephenbez
git clean -ffd如果你的git存储库中有另一个git存储库。没有双f,它将不会被删除。 - Trismegistos


如果您想恢复所有更改并且与当前远程主控器保持同步(例如,您发现主HEAD已向前移动,因为您将其分支并且您的推送被'拒绝')您可以使用

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.

59
2018-04-22 20:48





看看git-reflog。它将列出它记住的所有状态(默认为30天),您只需签出所需的状态即可。例如:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d

47
2017-07-19 12:16



感谢一吨威廉,感谢git reflog。我在我的树恢复到旧版本,不知道如何以检索最近。你的git reflog救了我。再次感谢。 - palaniraja
救了我的!就我而言,我的冒险经历 git rebase -i 出了问题(最后由于编辑错误而删除了一些提交)。感谢这个提示,我恢复了良好的状态! - paneer_tikka
30天默认是什么意思? - Mohe TheDreamy
@MoheTheDreamy我的意思是有时间限制。最终,当他们的年龄越过该限制垃圾收集器会删除不可达的引用。默认情况曾经是(可能仍然是)30天。因此可能无法使用较旧的参考文献。 - William Pursell


再克隆

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  •  删除本地,非推送提交
  •  还原对已跟踪文件所做的更改
  •  恢复您删除的跟踪文件
  •  删除列出的文件/目录 .gitignore (比如构建文件)
  •  删除未跟踪但未跟踪的文件/目录 .gitignore
  •  你不会忘记这种方法
  •  浪费带宽

以下是我每天忘记的其他命令。

清洁并重置

git clean -f -d -x
git reset --hard
  •  不删除本地,未推送的提交
  •  还原对已跟踪文件所做的更改
  •  恢复您删除的跟踪文件
  •  删除列出的文件/目录 .gitignore (比如构建文件)
  •  删除未跟踪但未跟踪的文件/目录 .gitignore

清洁

git clean -f -d -x
  •  不删除本地,未推送的提交
  •  不会还原您对跟踪文件所做的更改
  •  不会还原您删除的跟踪文件
  •  删除列出的文件/目录 .gitignore (比如构建文件)
  •  删除未跟踪但未跟踪的文件/目录 .gitignore

重启

git reset --hard
  •  不删除本地,未推送的提交
  •  还原对已跟踪文件所做的更改
  •  恢复您删除的跟踪文件
  •  删除列出的文件/目录 .gitignore (比如构建文件)
  •  不删除未跟踪但未删除的文件/目录 .gitignore

笔记

用于确认以上所有内容的测试用例(使用bash或sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

也可以看看

  • git revert 进行撤消先前提交的新提交
  • git checkout 回到之前的提交(可能需要首先运行上面的命令)
  • git stash 与...一样 git reset 上面,但你可以撤消它

41
2018-03-20 12:37



很抱歉从上面的答案窃取。我经常使用这个参考,主要是为我发布。 - William Entriken
我很确定,这是第一个选择(再克隆)实际上是“删除本地,非推送提交”:) - Marandil
红色X和绿色复选标记是什么意思?红色X会否定旁边的句子吗? - styfle
@styfle是什么这样做,是一些它不能做 - William Entriken
@FullDecent读起来很混乱。 “不删除本地的,未推送的提交”。这意味着它不会删除。双重否定意味着它确实删除了? - styfle


DANGER AHEAD :(请阅读评论。执行我的答案中建议的命令可能会删除超出您想要的内容)

彻底删除所有文件,包括我必须运行的目录

git clean -f -d

34
2017-09-11 07:10



为了节省任何人我刚刚经历的痛苦:这也将删除.gitignore-d文件! - landons
对不起,如果我给你带来任何麻烦。那时候我只是试图恢复和删除该文件夹中的一切。我不记得确切的情况,但“-d”是唯一对我有用的东西。我希望我没有给你带来太大的痛苦:-) - Tobias Gassmann
又何妨呢。我有备份,但是这可能是权证免责声明;) - landons


在阅读了大量答案并尝试它们之后,我发现了各种边缘情况,这意味着有时候它们并没有完全清理工作副本。

这是我目前使用的bash脚本,它始终有效。

#!/bin/sh
git reset --hard
git clean -f -d
git checkout -- HEAD

从工作副本根目录运行。


34
2018-06-04 07:25



最后一个命令给我 error: pathspec 'HEAD' did not match any file(s) known to git. - 0xC0000022L
当我拿出“ - ”时,它对我有用。 git checkout HEAD - Jester
git reset --hard 恢复跟踪的文件(暂存与否), git clean -f -d 删除未跟踪的文件, git checkout -- HEAD 为什么我们需要这个呢? - v.shashenko
我们不需要双连字符。一定是个错字。 - Farax


简单地说

git stash

它将删除你所有的本地chages。你也可以稍后说

git stash apply 

29
2018-04-24 12:18



使用 git stash pop 会自动删除最重要的藏匿变化 - Arrow Cen
git stash drop 删除最新的隐藏状态而不适用于工作副本。 - deerchao


我遇到了类似的问题。 解决方案是使用 git log 查找哪个版本的本地提交与远程不同。 (例如,版本是 3c74a11530697214cbcc4b7b98bf7a65952a34ec)。

然后用 git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ec 恢复变化。


26
2017-08-28 07:34





您可能不一定希望/需要在工作目录中存储您的工作/文件,而只是完全摆脱它们。命令 git clean 会为你做这件事。

执行此操作的一些常见用例是 删除cruft 由合并或外部工具生成或删除其他文件,以便您可以运行干净的构建。

请记住,您将需要非常谨慎地使用此命令,因为它旨在从本地工作目录中删除未跟踪的文件。如果您在执行此命令后突然改变主意,则无法返回查看已删除文件的内容。更安全的替代方案是执行

git stash --all 

这将删除所有东西,但保存所有东西。之后可以使用此藏匿处。

但是,如果您确实要删除所有文件并清理工作目录,则应执行

git clean -f -d

这将删除任何文件以及由于该命令而没有任何项目的任何子目录。在执行之前要做的聪明事 git clean -f -d 命令是运行

git clean -f -d -n

这将显示执行后将删除的内容的预览 git clean -f -d

所以这里是您从最具侵略性到最具侵略性的选项的摘要


选项1:在本地删除所有文件(最具攻击性)

git clean -f -d

选项2:预览上述影响(预览最具攻击性)

git clean -f -d -n

选项3:存储所有文件(最不积极的)

`git stash --all` 

6
2018-06-14 22:31