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

发布于 2024-07-26 21:40:14 字数 145 浏览 7 评论 0原文

我运行了 git status ,它告诉我一切都是最新的,并且没有本地更改。

然后我连续做了几次改变,意识到我想扔掉一切,回到原来的状态。 这个命令会帮我做吗?

git reset --hard HEAD

I ran git status which told me everything was up to date and there were no local changes.

Then I made several consecutive changes and realized I wanted to throw everything away and get back to my original state. Will this command do it for me?

git reset --hard HEAD

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

假装不在乎 2024-08-02 21:40:14

要恢复对工作副本所做的更改,请执行以下操作:

git checkout .

或者等效地,对于 git version >= 2.23:

git restore .

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

git reset

要恢复已提交的更改:

git revert <commit 1> <commit 2>

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

git clean -f

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

git clean -fd

To revert changes made to your working copy, do this:

git checkout .

Or equivalently, for git version >= 2.23:

git restore .

To revert changes made to the index (i.e., that you have added), do this. Warning this will reset all of your unpushed commits to master!:

git reset

To revert a change that you have committed:

git revert <commit 1> <commit 2>

To remove untracked files (e.g., new files, generated files):

git clean -f

Or untracked directories (e.g., new or automatically generated directories):

git clean -fd
天邊彩虹 2024-08-02 21:40:14

注意:您可能还想运行

git clean -fd

as

git reset --hard

will not 删除未跟踪的文件,因为 git-clean 将从跟踪的根目录中删除不在 git 跟踪下的任何文件。 警告 - 请小心! 首先使用 git-clean 运行一次试运行,看看它会删除什么,这会很有帮助。

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

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

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

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

Note: You may also want to run

git clean -fd

as

git reset --hard

will not remove untracked files, where as git-clean will remove any files from the tracked root directory that are not under git tracking. WARNING - BE CAREFUL WITH THIS! It is helpful to run a dry-run with git-clean first, to see what it will delete.

This is also especially useful when you get the error message

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

Which can occur when doing several things, one being updating a working copy when you and your friend have both added a new file of the same name, but he's committed it into source control first, and you don't care about deleting your untracked copy.

In this situation, doing a dry run will also help show you a list of files that would be overwritten.

飘然心甜 2024-08-02 21:40:14

重新克隆

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ 删除本地非推送提交
  • ✅ 恢复您对跟踪文件所做的更改
  • ✅ 恢复您删除的跟踪文件
  • ✅ 删除 .gitignore 中列出的文件/目录(如构建文件)
  • ✅ 删除文件/未跟踪且不在 .gitignore 中的目录

Re-clone

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ Deletes local, non-pushed commits
  • ✅ Reverts changes you made to tracked files
  • ✅ Restores tracked files you deleted
  • ✅ Deletes files/dirs listed in .gitignore (like build files)
  • ✅ Deletes files/dirs that are not tracked and not in .gitignore
  • ???? You won't forget this approach
  • ???? Wastes bandwidth

Following are other commands I forget daily.

Clean and reset

git clean --force -d -x
git reset --hard
  • ❌ Deletes local, non-pushed commits
  • ✅ Reverts changes you made to tracked files
  • ✅ Restores tracked files you deleted
  • ✅ Deletes files/dirs listed in .gitignore (like build files)
  • ✅ Deletes files/dirs that are not tracked and not in .gitignore

Clean

git clean --force -d -x
  • ❌ Deletes local, non-pushed commits
  • ❌ Reverts changes you made to tracked files
  • ❌ Restores tracked files you deleted
  • ✅ Deletes files/dirs listed in .gitignore (like build files)
  • ✅ Deletes files/dirs that are not tracked and not in .gitignore

Reset

git reset --hard
  • ❌ Deletes local, non-pushed commits
  • ✅ Reverts changes you made to tracked files
  • ✅ Restores tracked files you deleted
  • ❌ Deletes files/dirs listed in .gitignore (like build files)
  • ❌ Deletes files/dirs that are not tracked and not in .gitignore

Notes

Test case for confirming all the above (use bash or 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'

See also

  • git revert to make new commits that undo prior commits
  • git checkout to go back in time to prior commits (may require running above commands first)
  • git stash same as git reset above, but you can undo it
做个少女永远怀春 2024-08-02 21:40:14

如果您想恢复所有更改并与当前远程主控保持同步(例如,您发现主控 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.

If you want to revert all changes AND be up-to-date with the current remote master (for example you find that the master HEAD has moved forward since you branched off it and your push is being 'rejected') you can use

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.
小兔几 2024-08-02 21:40:14

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

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

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

从工作副本根目录运行。

After reading a bunch of answers and trying them, I've found various edge cases that mean sometimes they don't fully clean the working copy.

Here's my current bash script for doing it, which works all the time.

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

Run from working copy root directory.

墟烟 2024-08-02 21:40:14

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

Look into git-reflog. It will list all the states it remembers (default is 30 days), and you can simply checkout the one you want. For example:

$ 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
避讳 2024-08-02 21:40:14

只需执行 -

git stash

它将删除所有本地更改。 您也可以稍后通过执行来使用它 -

git stash apply 

simply execute -

git stash

it will remove all your local changes. and you can also use it later by executing -

git stash apply 
薄荷→糖丶微凉 2024-08-02 21:40:14

前方危险:(请阅读评论。执行我的答案中提出的命令可能会删除比您想要的更多的文件)

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

git clean -f -d

DANGER AHEAD: (please read the comments. Executing the command proposed in my answer might delete more than you want)

to completely remove all files including directories I had to run

git clean -f -d
老娘不死你永远是小三 2024-08-02 21:40:14

如果您位于顶级项目目录中,请尝试此操作:

git restore .

如果不是,请使用:

git restore :/

如果您想恢复子集的本地更改:

  • 使用顶级路径规范魔术恢复所有工作树文件: git restore :/
  • 恢复全部当前目录下的文件: git Restore .
  • 文件类型(例如所有 C 源文件): git Restore '*.c'

详细信息请参见git 恢复文档

要删除未跟踪的文件:git clean -f

Try this if you are in top project directory:

git restore .

If not then use:

git restore :/

If you would like to revert local changes for a subset:

  • restore all working tree files with top pathspec magic: git restore :/
  • restore all files in the current directory: git restore .
  • file type (e.g. all C source files): git restore '*.c'

For details see git restore documentation.

To remove untracked files: git clean -f

私野 2024-08-02 21:40:14

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

然后使用 git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ec 恢复更改。

I met a similar problem.
The solution is to use git log to look up which version of the local commit is different from the remote. (E.g. the version is 3c74a11530697214cbcc4b7b98bf7a65952a34ec).

Then use git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ec to revert the change.

ぃ弥猫深巷。 2024-08-02 21:40:14

我搜索了类似的问题,

想要扔掉本地提交:

  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 点。

I searched for a similar issue,

Wanted to throw away local commits:

  1. cloned the repository (git clone)
  2. switched to dev branch (git checkout dev)
  3. did few commits (git commit -m "commit 1")
  4. but decided to throw away these local commits to go back to remote (origin/dev)

So did the below:

git reset --hard origin/dev

Check:

git status  

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

now local commits are lost, back to the initial cloned state, point 1 above.

星軌x 2024-08-02 21:40:14

最简单的解决方案在我看来:

如何放弃所有本地更改并将文件重置为当前分支上的最后一次提交?

# Execute on the root of the working tree...

# Discard all changes to tracked files
git checkout .

# Remove all untracked files 
git clean -fd

注意:被忽略的文件将不受影响

Simplest solution imo:

How to discard all local changes and reset the files to the last commit on my current branch?

# Execute on the root of the working tree...

# Discard all changes to tracked files
git checkout .

# Remove all untracked files 
git clean -fd

Note: ignored files will remain unaffected

浪推晚风 2024-08-02 21:40:14

两个简单的步骤

git fetch origin
git reset --hard origin/master

,或者如果您的 git 使用 main 而不是 master,请使用以下命令:

git reset --hard origin/main

Two simple steps

git fetch origin
git reset --hard origin/master

or if your git uses main instead master use this:

git reset --hard origin/main
断肠人 2024-08-02 21:40:14

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

$ 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

Try this for revert all changes uncommited in local branch

$ git reset --hard HEAD

But if you see a error like this:

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

You can navigate to '.git' folder then delete index.lock file:

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

Finaly, run again the command:

$ git reset --hard HEAD
神也荒唐 2024-08-02 21:40:14

在这里添加另一个选项。

我指的是标题:恢复本地更改。
它还可以应用于未暂存提交的更改。

在这种情况下,您可以使用:

git restore <file>

返回到之前的状态。

Adding another option here.

I'm referring to the title: Revert local changes.
It can also apply to changes that weren't staged for commit.

In this case you can use:

git restore <file>

To go back to previous state.

断爱 2024-08-02 21:40:14

您可能不一定想要/需要将您的工作/文件隐藏在工作目录中,而是简单地完全删除它们。 命令 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

You may not necessarily want/need to stash your work/files in your working directory but instead simply get rid of them completely. The command git clean will do this for you.

Some common use cases for doing this would be to remove cruft that has been generated by merges or external tools or remove other files so that you can run a clean build.

Keep in mind you will want to be very cautious of this command, since its designed to remove files from your local working directory that are NOT TRACKED. if you suddenly change your mind after executing this command, there is no going back to see the content of the files that were removed. An alternative which is safer is to execute

git stash --all

which will remove everything but save it all in a stash. This stash can then later be used.

However, if you truly DO want to remove all the files and clean your working directory, you should execute

git clean -f -d

This will remove any files and also any sub-directories that don't have any items as a result of the command. A smart thing to do before executing the git clean -f -d command is to run

git clean -f -d -n

which will show you a preview of what WILL be removed after executing git clean -f -d

So here is a summary of your options from most aggressive to least aggressive


Option 1: Remove all files locally(Most aggressive)

git clean -f -d

Option 2: Preview the above impact(Preview most aggressive)

git clean -f -d -n

Option 3: Stash all files (Least aggressive)

git stash --all
柳若烟 2024-08-02 21:40:14

如果您只想删除所有更改,请使用 git checkout 。
这是更快、更简单的一种。

If you just want to delete all the changes, go for git checkout .
It's the faster and simpler one.

逆蝶 2024-08-02 21:40:14

这里的众多答案,包括已接受的答案,总是让我质疑我应该运行哪些命令。

许多人都有警告,尽管多次访问这个问题,但我永远不记得我应该运行哪个组合,或者更重要的是不应该运行哪个组合。

因此,当我下周重新讨论这个主题时,我将把这个问题留给自己。

git restore .
git clean -f
git clean -fd

对于大多数情况,您可以简单地组合命令,但正如我在解释中指出的那样,某些情况需要您先删除文件,然后删除保存它们的目录。

 git restore . && git clean -fd

说明:

命令 git restore . 对当前分支执行签出到当前目录。 这将撤消对任何文件所做的任何更改。 更具体地说,该命令会将跟踪文件中的所有更改恢复到当前目录和子目录中最后提交的状态。

命令 git clean -f 会删除恢复后所有新添加的(未跟踪的)文件。 此命令将永久删除文件且无法撤消。

命令 git clean -fd 会删除恢复后所有新添加的目录。 此命令将永久删除目录及其文件,并且无法撤消。

注意:我不是 git 专家,只是多年来每天、每天专业使用 git 的人。 我建议您查阅文档。

话虽如此,-fd 应该处理-f,但也有例外,它会爆炸。 根据我的经验,执行所有三个命令都有效。 这有点像调用 Directory.Delete(path, recursive=true) ,它应该删除所有文件,但有时出于某种原因(取决于您的操作系统),您必须在删除目录之前先删除每个文件。

另一个注意事项:接受的答案和其他答案中的误导性警告:接受的答案关于 git reset 的警告(“警告这将重置所有未推送的提交到 master!”)可能会产生误导。 不带任何参数的 git reset 默认为 git reset --mixed HEAD,它只影响暂存区域(索引),而不影响工作树或提交历史记录。 git reset 不会恢复提交或影响分支历史记录,除非与提交引用(如 git reset --hard)结合使用,这确实可以更改提交本地存储库中的历史记录。

The multitude of answers here, including the accepted answer, always leaves me questioning which commands I should run.

Many have warnings, and despite visiting this question many times, I can never remember which combination I should, or more importantly should not, run.

So, I am leaving this here for myself when I revisit the topic next week.

git restore .
git clean -f
git clean -fd

For most scenarios you can simply combine the commands, but as I point out in my explanation some cases require you delete files first, then the directories that hold them.

 git restore . && git clean -fd

Explanation:

The command git restore . performs a checkout on the current branch to the current directory. This will undo any changes made to any files. More specifically, the command will revert all changes in tracked files to their last committed state in the current directory and subdirectories.

The command git clean -f removes any newly added (untracked) files since the restore. This command permanently deletes files and cannot be undone.

The command git clean -fd removes any newly added directories since the restore. This command permanently deletes directories and their files and cannot be undone.

Note: I am not a git expert, just someone who uses git professionally, every day, all day, for many years. I advise you to consult the documenation.

With that said -fd should take care of -f but there are exceptions where it blows up. In my experience, executing all three commands works. It is kind of like calling Directory.Delete(path, recursive=true) which should delete all files but sometimes for whatever reason (depending on your OS) you must delete each file first before deleting the directory.

Another Note: Misleading Warning in Accepted Answer And Other Answers: The accepted answer's warning regarding git reset ("Warning this will reset all of your unpushed commits to master!") might be misleading. git reset without any arguments defaults to git reset --mixed HEAD, which only affects the staging area (index) and not the working tree or commit history. git reset does not revert commits or affect the branch history unless combined with a commit reference (like git reset --hard <commit>), which indeed can change the commit history in the local repository.

森林散布 2024-08-02 21:40:14

很头疼,你可以尝试:

git stash --all
git stash apply 

这将丢弃历史记录中的所有本地更改,并将文件保留在文件夹内。

It's a headache, you can try:

git stash --all
git stash apply 

This will discard all local changes from the history and keep the files inside the folder.

天赋异禀 2024-08-02 21:40:14

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

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

问题解答:

  • 如何在 git 历史记录中保留或不保留更改的情况下恢复个人更改

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

This question is more about broader repository reset / revert, but in case if you're interested in reverting individual change - I've added similar answer in here:

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

Answers to questions:

  • How to revert individual change with or without change preserving in git history

  • How to return back to old version to restart from same state

撕心裂肺的伤痛 2024-08-02 21:40:14

使用 git 版本“2.37.1”,

我使用以下命令将所有本地更改(尚未提交)恢复到以前的状态(在本地更改之前):

git checkout -p

文档片段:

< code>您可以使用 git checkout -p 有选择地放弃当前工作树中的编辑

来自 man git-checkout

<前><代码> -p, --patch
之间的差异中交互式地选择帅哥。
(或索引,如果未指定)和工作树。 被选中的
然后将 hunk 反向应用于工作树(如果
<树型> 已指定,索引)。

**这意味着你可以使用 git checkout -p 有选择地丢弃
从当前工作树进行编辑。** 请参阅“交互模式”
git-add(1) 部分了解如何操作 --patch 模式。

请注意,此选项默认使用无覆盖模式(另请参见
--overlay),目前不支持覆盖模式。

Using git version "2.37.1"

I reverted all my local changes ( not yet committed ) to previous state ( prior to my local changes ) by using the following command :

git checkout -p

Documentation snippet :

you can use git checkout -p to selectively discard edits from your current working tree

From man git-checkout

  -p, --patch
       Interactively select hunks in the difference between the <tree-ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree-ish> was specified, the index).

       **This means that you can use git checkout -p to selectively discard
       edits from your current working tree.** See the “Interactive Mode”
       section of git-add(1) to learn how to operate the --patch mode.

       Note that this option uses the no overlay mode by default (see also
       --overlay), and currently doesn’t support overlay mode.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文