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

我有一个在其中运行git init的项目。几次提交后,我执行了git status ,它告诉我一切都是最新的,并且没有本地更改。

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

git reset --hard HEAD

答案

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

git checkout .

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

git reset

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

git revert <commit 1> <commit 2>

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

git clean -f

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

git clean -fd

注意:您可能还想运行

git clean -fd

git reset --hard

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

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

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

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

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

重新克隆

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 stash与上面的git reset相同,但是您可以撤消它

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

查看 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 clean -f -d

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

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

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

从工作副本根目录运行。

简单地说

git stash

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

git stash apply

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

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

我搜索了类似的问题,

想要丢弃本地提交:

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

以下内容也是如此:

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。