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


1912

我有一个运行的项目git init。经过几次提交后,我git status告诉我所有内容都是最新的,并且没有本地更改。

然后,我进行了几次连续更改,意识到我想扔掉所有东西并恢复到原始状态。这个命令会帮我吗?

git reset --hard HEAD

Answers:


3387

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

git checkout .

如果要还原对索引所做的更改(即已添加的内容),请执行此操作。警告这会将您所有未推送的提交重置为master!

git reset

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

git revert <commit 1> <commit 2>

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

git clean -f

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

git clean -fd

133
经过这么长的时间,git checkout path/to/file只会将本地更改恢复为path/to/file
Matijs

29
以下答案的+1还提到git clean -f(删除未跟踪的更改)和-fd(也删除未跟踪的目录)
ptdev 2012年

3
如果你也想清理你的未跟踪文件,阅读这stackoverflow.com/questions/61212/...
Surasin Tancharoen

9
git checkout .而且git reset [--hard HEAD]没有用,我必须做一个git clean -fd还原我的更改。
BrainSlugs83 2015年

7
git reset不会重置您的更改,git reset --hard而是这样做。
塞林

388

注意:您可能还想运行

git clean -fd

git reset --hard

删除未跟踪文件,其中为git的清洁会从跟踪的根目录不在下git的跟踪中删除任何文件。警告-请务必小心!首先使用git-clean进行空运行很有帮助,以查看它将删除什么。

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

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

这可能会在执行多项操作时发生,一种是在您和您的朋友都添加了同名的新文件时更新工作副本,但他先将其提交到了源代码管理中,并且您不必担心删除未跟踪的副本。

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


13
文件清理命令是“ git clean -f”。未跟踪的目录用“ git clean -d”删除
Jonathan Mitchell

35
git clean -fd(-d需要强制)
–lecteblake

14
-n或--dry-run是空运行的标志。
stephenbez 2014年

2
git clean -ffd如果在git仓库中有另一个git仓库。如果没有double f,它将不会被删除。
Trismegistos

147

重新克隆

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

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

清理并重置

git clean --force -d -x
git reset --hard
  • s删除本地非推送的提交
  • 还原对跟踪文件所做的更改
  • s恢复已删除的跟踪文件
  • s删除列出的文件/目录.gitignore(如构建文件)
  • s删除未跟踪且不在其中的文件/目录 .gitignore

清洁

git clean --force -d -x
  • s删除本地非推送的提交
  • 还原对跟踪文件所做的更改
  • s恢复已删除的跟踪文件
  • s删除列出的文件/目录.gitignore(如构建文件)
  • s删除未跟踪且不在其中的文件/目录 .gitignore

重启

git reset --hard
  • s删除本地非推送的提交
  • 还原对跟踪文件所做的更改
  • s恢复已删除的跟踪文件
  • s删除列出的文件/目录.gitignore(如构建文件)
  • s删除未跟踪且不在其中的文件/目录 .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 stashgit reset上述相同,但是您可以撤消它

很抱歉从以上答案中窃取。我经常使用此参考,主要是为我发布。
William Entriken '17

1
我很确定,第一个选项(Re-clone)实际上确实是“删除了本地的,非推送的提交” :)
Marandil

1
@styfle✅是它要做的事,❌是它没有做的事
William Entriken

3
@FullDecent有点让人迷惑。“❌不会删除本地非推送的提交”。这意味着它不会被删除。双重否定意味着它确实删除了吗?
styfle

1
关于-x标志git clean -f -d -x:如果指定了-x选项,还将删除忽略的文件。这可以,例如,是有用的从GIT文档删除所有构建products.-
亚历

82

如果您想还原所有更改并与当前的远程主服务器保持最新(例如,您发现主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.

origingit reset --hard origin/master(有效)中指定似乎很重要-没有它(即git reset --hard),似乎什么都没有改变。
杰克,

我进行了一些本地更改,并且无法通过执行git reset --hard origin / master的任何命令来摆脱它们,它也能够提取主设备的更改
Abhishek Ringia

50

查看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

感谢一吨威廉,为git reflog。我将树重置为旧版本,并且不确定如何恢复到最新版本。您的git reflog救了我。再次感谢。
palaniraja 2011年

1
也救了我!以我为例,我的冒险之旅git rebase -i出错了(由于编辑错误,结束了一些提交工作)。多亏了这个技巧,我才恢复了良好的状态!
paner_tikka

您默认的30天是什么意思!?
Mohe TheDreamy

@MoheTheDreamy我的意思是有时间限制。最终,当垃圾收集器的使用期限超过该限制时,垃圾收集器将删除它们。默认设置为30天(可能仍然是30天)。因此,较旧的参考可能不可用。
威廉·珀塞尔

36

提前危险:(请阅读注释。执行我的答案中提出的命令可能会删除比您想要的更多的东西)

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

git clean -f -d

13
为了减轻任何人的痛苦,我刚刚经历了:这也将删除.gitignore -d文件!
兰顿

对不起,如果给您造成任何麻烦。当时,我只是尝试还原和删除该文件夹中的所有内容。我不记得确切的情况,但是“ -d”是唯一对我有用的东西。我希望我不会给您带来太多的痛苦:-)
Tobias Gassmann

1
没有伤害。我有备份,但是可能需要免责声明;)
兰顿

35

阅读了一堆答案并尝试使用它们之后,我发现了各种极端情况,这意味着有时它们无法完全清除工作副本。

这是我当前执行此操作的bash脚本,该脚本始终有效。

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

从工作副本根目录运行。


10
最后一个命令给了我error: pathspec 'HEAD' did not match any file(s) known to git.
0xC0000022L

1
当我取出“-”时,它对我有用。 git checkout HEAD
小丑2015年

4
git reset --hard恢复已跟踪的文件(已暂存或未暂存),git clean -f -d删除未跟踪的文件,那git checkout -- HEAD为什么我们需要它?
v.shashenko

我们不需要双连字符。必须是错字。
Farax '16

35

只需执行-

git stash

它将删除您所有的本地更改。您还可以稍后通过执行-

git stash apply 

3
使用git stash pop会自动为您删除最隐蔽的更改
Arrow Cen

8
git stash drop删除最新的隐藏状态而不适用于工作副本。
deerchao

git stash apply不会添加新创建的文件
Ravistm

27

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

然后使用git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ec还原更改。


16

我搜索了类似的问题,

想要丢弃本地提交:

  1. 克隆了存储库(git clone)
  2. 切换到开发分支(git checkout dev)
  3. 很少提交(git commit -m“ commit 1”)
  4. 但是决定放弃这些本地提交以返回到远程(origin / dev)

以下内容也是如此:

git reset --hard origin/dev

校验:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

现在,本地提交丢失,回到初始克隆状态,即上面的第1点。


1
谢谢,那是唯一对我有用的东西-“ git reset --hard origin”
Nisim Naim

很高兴知道它有所帮助。
Manohar Reddy Poreddy

7

您可能不一定要/不需要将工作/文件存放在工作目录中,而只是完全摆脱它们。该命令git clean将为您执行此操作。

这样做的一些常见用例是删除由合并或外部工具生成的碎片,或删除其他文件,以便您可以运行干净的构建。

请记住,您将对此命令非常谨慎,因为该命令旨在从本地工作目录中删除未跟踪的文件。如果您在执行此命令后突然改变主意,则无法返回查看已删除文件的内容。一种更安全的选择是执行

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

尝试此操作以还原本地分支中所有未提交的更改

$ git reset --hard HEAD

但是,如果您看到这样的错误:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

您可以导航到“ .git”文件夹,然后删除index.lock文件:

$ cd /directory/for/your/project/.git/
$ rm index.lock

最后,再次运行命令:

$ git reset --hard HEAD

0

这个问题更多的是关于更广泛的存储库重置/恢复,但是如果您有兴趣恢复单个更改,请在此处添加类似的答案:

https://stackoverflow.com/a/60890371/2338477

问题答案:

  • 如何在git历史记录中保留或不保留更改的情况下还原单个更改

  • 如何返回旧版本以从相同状态重新启动

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.