如何撤消 git reset --hard HEAD~1?

发布于 2024-07-04 02:43:41 字数 86 浏览 8 评论 0原文

是否可以撤消由以下命令引起的更改? 如果是这样,怎么办?

git reset --hard HEAD~1

Is it possible to undo the changes caused by the following command? If so, how?

git reset --hard HEAD~1

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

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

发布评论

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

评论(21

自由如风 2024-07-11 02:43:41

帕特·诺茨是正确的。 只要提交是在几天之内,您就可以取回提交。 git 仅在大约一个月左右后收集垃圾,除非您明确告诉它删除较新的 blob。

$ git init
Initialized empty Git repository in .git/

$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file1

$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file2

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1

$ cat file2
cat: file2: No such file or directory

$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

$ cat file2
added new file

您可以在示例中看到 file2 由于硬重置而被删除,但当我通过引用日志重置时又被放回原位。

Pat Notz is correct. You can get the commit back so long as it's been within a few days. git only garbage collects after about a month or so unless you explicitly tell it to remove newer blobs.

$ git init
Initialized empty Git repository in .git/

$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file1

$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file2

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1

$ cat file2
cat: file2: No such file or directory

$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

$ cat file2
added new file

You can see in the example that the file2 was removed as a result of the hard reset, but was put back in place when I reset via the reflog.

天煞孤星 2024-07-11 02:43:41

您要做的就是指定要恢复到的提交的 sha1。 您可以通过检查 reflog (git reflog) 来获取 sha1,然后执行

git reset --hard <sha1 of desired commit>

但不要等待太久...几周后 git 最终会看到该提交为未引用并删除所有 blob 。

What you want to do is to specify the sha1 of the commit you want to restore to. You can get the sha1 by examining the reflog (git reflog) and then doing

git reset --hard <sha1 of desired commit>

But don't wait too long... after a few weeks git will eventually see that commit as unreferenced and delete all the blobs.

盛装女皇 2024-07-11 02:43:41

答案隐藏在上面的详细响应中,您可以简单地执行以下操作:(

gt; git reset --hard HEAD@{1}

参见 git reflog show 的输出)

The answer is hidden in the detailed response above, you can simply do:

gt; git reset --hard HEAD@{1}

(See the output of git reflog show)

煮酒 2024-07-11 02:43:41

如果 Git 尚未进行垃圾收集,则可以恢复它。

使用 fsck 获取悬空提交的概述:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

使用 rebase 恢复悬空提交:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

It is possible to recover it if Git hasn't garbage collected yet.

Get an overview of dangling commits with fsck:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

Recover the dangling commit with rebase:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
云之铃。 2024-07-11 02:43:41

据我所知, --hard 将丢弃未提交的更改。 因为这些不被 git 跟踪。 但您可以撤消放弃的提交

$ git reflog

将列出:

b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....

其中 4bac331废弃的提交

现在只需将头移至该提交即可:

$ git reset --hard 4bac331

As far as I know, --hard will discard uncommitted changes. Since these aren't tracked by git. But you can undo the discarded commit.

$ git reflog

will list:

b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....

where 4bac331 is the discarded commit.

Now just move the head to that commit:

$ git reset --hard 4bac331
梅倚清风 2024-07-11 02:43:41

IRL 案例示例:

$ git fsck --lost-found

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a    <- it's this one

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <[email protected]>
Date:   Wed Aug 15 08:41:30 2012 +0200

    *MY COMMIT MESSAGE IS DISPLAYED HERE*

diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.

Example of IRL case:

$ git fsck --lost-found

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a    <- it's this one

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <[email protected]>
Date:   Wed Aug 15 08:41:30 2012 +0200

    *MY COMMIT MESSAGE IS DISPLAYED HERE*

diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.
七禾 2024-07-11 02:43:41

git reflog

  • 在列表中找到您的提交 sha,然后将其复制并粘贴到此命令中:

gitcherry-pick

git reflog

  • Find your commit sha in the list then copy and paste it into this command:

git cherry-pick <the sha>

幽蝶幻影 2024-07-11 02:43:41

如果您使用 JetBrains IDE(任何基于 IntelliJ 的东西),您甚至可以通过其“本地历史记录”功能恢复未提交的更改。

右键单击文件树中的顶级目录,在上下文菜单中找到“本地历史记录”,然后选择“显示历史记录”。 这将打开一个视图,可以在其中找到您最近的编辑,找到要返回的修订版本后,右键单击它并单击“恢复”。

If you are using a JetBrains IDE (anything IntelliJ based), you can recover even your uncommited changes via their "Local History" feature.

Right-click on your top-level directory in your file tree, find "Local History" in the context menu, and choose "Show History". This will open up a view where your recent edits can be found, and once you have found the revision you want to go back to, right click on it and click "Revert".

掐死时间 2024-07-11 02:43:41

如果您尚未对存储库进行垃圾收集(例如使用 git repack -d 或 git gc,但请注意垃圾收集也可以自动发生),那么您的提交仍然是那里——只是不再可以通过 HEAD 到达。

您可以尝试通过查看 git fsck --lost-found 的输出来查找您的提交。

较新版本的 Git 有一种称为“reflog”的东西,它是对 ref 所做的所有更改的日志(而不是对存储库内容所做的更改)。 因此,例如,每次您切换 HEAD 时(即每次您执行 git checkout 来切换分支时)都会被记录下来。 当然,您的 git reset 也操作了 HEAD,因此它也被记录下来。 您可以以与访问存储库的旧状态类似的方式访问引用的旧状态,即使用 @ 符号而不是 ~,例如 git 重置 HEAD@{1}

我花了一段时间才理解 HEAD@{1} 和 HEAD~1 之间的区别,所以这里有一点解释:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

所以,HEAD~1 意味着“在提交之前转到提交” HEAD 当前指向的位置”,而 HEAD@{1} 表示“转到 HEAD 在指向当前指向的位置之前所指向的提交”。

这将让您轻松找到丢失的提交并恢复它。

If you have not yet garbage collected your repository (e.g. using git repack -d or git gc, but note that garbage collection can also happen automatically), then your commit is still there – it's just no longer reachable through the HEAD.

You can try to find your commit by looking through the output of git fsck --lost-found.

Newer versions of Git have something called the "reflog", which is a log of all changes that are made to the refs (as opposed to changes that are made to the repository contents). So, for example, every time you switch your HEAD (i.e. every time you do a git checkout to switch branches) that will be logged. And, of course, your git reset also manipulated the HEAD, so it was also logged. You can access older states of your refs in a similar way that you can access older states of your repository, by using an @ sign instead of a ~, like git reset HEAD@{1}.

It took me a while to understand what the difference is between HEAD@{1} and HEAD~1, so here is a little explanation:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

So, HEAD~1 means "go to the commit before the commit that HEAD currently points at", while HEAD@{1} means "go to the commit that HEAD pointed at before it pointed at where it currently points at".

That will easily allow you to find your lost commit and recover it.

梦中楼上月下 2024-07-11 02:43:41

在回答之前,让我们添加一些背景知识,解释一下这个 HEAD 是什么。

首先什么是 HEAD?

HEAD 只是对当前提交(最新)的引用分支机构。
在任何给定时间只能有一个 HEAD。 (不包括 git worktree

HEAD 的内容存储在 .git/HEAD 中,它包含当前提交的 40 字节 SHA-1 。


分离的 HEAD

如果您不是最新的提交 - 意味着 HEAD 指向历史记录中的先前提交它被称为分离的HEAD

输入图像描述这里

在命令行上,它看起来像这样 - SHA-1 而不是分支名称,因为 HEAD 没有指向当前分支的尖端

在此处输入图像描述< /a>


关于如何从分离的 HEAD 中恢复的一些选项:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

这将检出指向所需提交的新分支。
此命令将签出给定的提交。
此时您可以创建一个分支并从此时开始工作。

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

您始终可以使用reflog< /code> 也是如此。
git reflog 将显示更新 HEAD 的任何更改,并检查所需的 reflog 条目会将 HEAD 设置回此提交。

每次修改 HEAD 时,reflog 中都会有一个新条目

git reflog
git checkout HEAD@{...}

这将使您回到所需的提交

在此处输入图像描述


git reset HEAD --hard< /strong>

将你的头“移”回所需的提交。

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • 注意:(自 Git 2.7 起
    您还可以使用 git rebase --no-autostash 。


git revert

“撤消”给定的提交或提交范围。
重置命令将“撤消”给定提交中所做的任何更改。
带有撤消补丁的新提交将被提交,而原始提交也将保留在历史记录中。

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

此架构说明了哪个命令执行什么操作。
正如你所看到的,reset && checkout 修改HEAD

输入图像描述这里

Before answering lets add some background, explaining what is this HEAD.

First of all what is HEAD?

HEAD is simply a reference to the current commit (latest) on the current branch.
There can only be a single HEAD at any given time. (excluding git worktree)

The content of HEAD is stored inside .git/HEAD and it contains the 40 bytes SHA-1 of the current commit.


detached HEAD

If you are not on the latest commit - meaning that HEAD is pointing to a prior commit in history its called detached HEAD.

enter image description here

On the command line it will look like this- SHA-1 instead of the branch name since the HEAD is not pointing to the the tip of the current branch

enter image description here


A few options on how to recover from a detached HEAD:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

This will checkout new branch pointing to the desired commit.
This command will checkout to a given commit.
At this point you can create a branch and start to work from this point on.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

You can always use the reflog as well.
git reflog will display any change which updated the HEAD and checking out the desired reflog entry will set the HEAD back to this commit.

Every time the HEAD is modified there will be a new entry in the reflog

git reflog
git checkout HEAD@{...}

This will get you back to your desired commit

enter image description here


git reset HEAD --hard <commit_id>

"Move" your head back to the desired commit.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • Note: (Since Git 2.7)
    you can also use the git rebase --no-autostash as well.


git revert <sha-1>

"Undo" the given commit or commit range.
The reset command will "undo" any changes made in the given commit.
A new commit with the undo patch will be commited while the original commit will remain in the history as well.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

This schema illustrate which command does what.
As you can see there reset && checkout modify the HEAD.

enter image description here

∝单色的世界 2024-07-11 02:43:41

在大多数情况下,是的。

根据运行命令时存储库所处的状态,git reset --hard 的效果范围可以从微不足道到撤消,甚至基本上不可能。

下面我列出了一系列不同的可能情况,以及如何从中恢复。

我所有的更改都已提交,但现在提交都消失了!

当您运行带参数的 git reset 时,通常会发生这种情况,如 git reset --hard HEAD~ 中所示。 别担心,这很容易恢复!

如果您刚刚运行了 git reset 并且此后没有执行任何其他操作,您可以使用这句话返回到原来的位置:

git reset --hard @{1}

这将重置您当前的分支,无论它在上次之前处于什么状态它已被修改(在您的情况下,对分支的最新修改将是您尝试撤消的硬重置)。

但是,如果您在重置后对分支进行了其他修改,则上面的一行代码将不起作用。 相反,您应该运行 git reflog 查看最近对分支所做的所有更改(包括重置)的列表。 该列表将如下所示:

7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit

在此列表中查找您想要“撤消”的操作。 在上面的示例中,它将是第一行,即“重置:移动到 HEAD~”。 然后复制该操作之前(下方)的提交表示。 在我们的例子中,这将是 master@{1} (或 3ae5027,它们都代表相同的提交),然后运行 ​​git reset --hard commit> 将当前分支重置回该提交。

我使用 git add 暂存了更改,但从未提交。 现在我的改变消失了!

恢复起来有点困难。 git 确实拥有您添加的文件的副本,但由于这些副本从未与任何特定提交绑定,因此您无法立即恢复所有更改。 相反,您必须在 git 数据库中找到各个文件并手动恢复它们。 您可以使用 git fsck 来完成此操作。

有关详细信息,请参阅对暂存区域中未提交的文件撤消 git reset --hard

我对工作目录中的文件进行了更改,但从未使用 git add 暂存,也从未提交。 现在我的改变消失了!

呃哦。 我不想告诉你这个,但你可能不走运。 git 不会存储您未添加或提交的更改,并且根据 文档git重置

--硬

重置索引和工作树。 以来工作树中跟踪文件的任何更改都将被丢弃。

可能可以通过以下方式恢复更改:某种磁盘恢复实用程序或专业的数据恢复服务,但在这一点上,这可能比它的价值更麻烦。

In most cases, yes.

Depending on the state your repository was in when you ran the command, the effects of git reset --hard can range from trivial to undo, to basically impossible.

Below I have listed a range of different possible scenarios, and how you might recover from them.

All my changes were committed, but now the commits are gone!

This situation usually occurs when you run git reset with an argument, as in git reset --hard HEAD~. Don't worry, this is easy to recover from!

If you just ran git reset and haven't done anything else since, you can get back to where you were with this one-liner:

git reset --hard @{1}

This resets your current branch whatever state it was in before the last time it was modified (in your case, the most recent modification to the branch would be the hard reset you are trying to undo).

If, however, you have made other modifications to your branch since the reset, the one-liner above won't work. Instead, you should run git reflog <branchname> to see a list of all recent changes made to your branch (including resets). That list will look something like this:

7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit

Find the operation in this list that you want to "undo". In the example above, it would be the first line, the one that says "reset: moving to HEAD~". Then copy the representation of the commit before (below) that operation. In our case, that would be master@{1} (or 3ae5027, they both represent the same commit), and run git reset --hard <commit> to reset your current branch back to that commit.

I staged my changes with git add, but never committed. Now my changes are gone!

This is a bit trickier to recover from. git does have copies of the files you added, but since these copies were never tied to any particular commit you can't restore the changes all at once. Instead, you have to locate the individual files in git's database and restore them manually. You can do this using git fsck.

For details on this, see Undo git reset --hard with uncommitted files in the staging area.

I had changes to files in my working directory that I never staged with git add, and never committed. Now my changes are gone!

Uh oh. I hate to tell you this, but you're probably out of luck. git doesn't store changes that you don't add or commit to it, and according to the documentation for git reset:

--hard

Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded.

It's possible that you might be able to recover your changes with some sort of disk recovery utility or a professional data recovery service, but at this point that's probably more trouble than it's worth.

冷夜 2024-07-11 02:43:41

如果你真的很幸运,就像我一样,你可以返回文本编辑器并点击“撤消”。

我知道这并不是一个真正正确的答案,但它节省了我半天的工作,所以希望它对其他人也能起到同样的作用!

If you're really lucky, like I was, you can go back into your text editor and hit 'undo'.

I know that's not really a proper answer, but it saved me half a day's work so hopefully it'll do the same for someone else!

Hello爱情风 2024-07-11 02:43:41

我知道这是一个旧线程......但由于许多人正在寻找撤消 Git 中的内容的方法,我仍然认为继续在这里提供提示可能是个好主意。

当您执行“git add”或在 git gui 中将任何内容从左上角移动到左下角时,文件的内容将存储在 blob 中,并且可以从该 blob 中恢复文件内容。

因此,即使文件未提交但必须已添加,也可以恢复该文件。

git init  
echo hello >> test.txt  
git add test.txt  

现在,blob 已创建,但它由索引引用,因此在我们重置之前不会使用 git fsck 列出它。 所以我们重置...

git reset --hard  
git fsck  

你会得到一个悬空的 blob ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

会给你文件内容“hello”回来

为了查找未引用的提交,我在某处找到了一个建议这一点的提示。

gitk --all $(git log -g --pretty=format:%h)  

我把它作为 git gui 中的一个工具,非常方便。

I know this is an old thread... but as many people are searching for ways to undo stuff in Git, I still think it may be a good idea to continue giving tips here.

When you do a "git add" or move anything from the top left to the bottom left in git gui the content of the file is stored in a blob and the file content is possible to recover from that blob.

So it is possible to recover a file even if it was not committed but it has to have been added.

git init  
echo hello >> test.txt  
git add test.txt  

Now the blob is created but it is referenced by the index so it will no be listed with git fsck until we reset. So we reset...

git reset --hard  
git fsck  

you will get a dangling blob ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

will give you the file content "hello" back

To find unreferenced commits I found a tip somewhere suggesting this.

gitk --all $(git log -g --pretty=format:%h)  

I have it as a tool in git gui and it is very handy.

枕梦 2024-07-11 02:43:41

我刚刚对错误的项目进行了硬重置。 拯救我生命的是 Eclipse 的本地历史。 据说 IntelliJ Idea 也有一个,您的编辑器也可以,值得检查一下:

  1. 有关本地历史记录的 Eclipse 帮助主题
  2. http: //wiki.eclipse.org/FAQ_Where_is_the_workspace_local_history_stored%3F

I've just did a hard reset on wrong project. What saved my life was Eclipse's local history. IntelliJ Idea is said to have one, too, and so may your editor, it's worth checking:

  1. Eclipse help topic on Local History
  2. http://wiki.eclipse.org/FAQ_Where_is_the_workspace_local_history_stored%3F
等你爱我 2024-07-11 02:43:41

制作了一个小脚本,以便更容易地找到正在寻找的提交:

git fsck --lost-found | grep 提交 | 切 -d ' ' -f 3 | xargs -i git show \{\} | xargs -i git show \{\} | xargs -i git show \{\} | egrep '^commit |Date:'

是的,使用 awk 或类似的东西可以使它变得相当漂亮,但它很简单,我只是需要它。 可能会为其他人节省 30 秒。

Made a tiny script to make it slightly easier to find the commit one is looking for:

git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'

Yes, it can be made considerably prettier with awk or something like it, but it's simple and I just needed it. Might save someone else 30 seconds.

·深蓝 2024-07-11 02:43:41

注意:这个答案仅在您使用像 IntelliJ 这样的 IDE 时才有效。

我最近遇到了类似的问题,我既没有暂存更改也没有提交更改。 有当地历史的选项。 我能够恢复 IntelliJ 本地历史记录中的更改 (ref) 。

希望它能帮助某人。

Note: this answer is only valid if you use IDEs like IntelliJ

I recently faced a similar issue where I neither staged my changes nor committed them. There is an option of local history. I was able to revert changes from the local history of IntelliJ (ref).

Hope it helps someone.

弃爱 2024-07-11 02:43:41

这救了我的命:
https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c

基本上你需要运行:

for blob in $(git fsck --lost-found | awk ‘$2 == “blob” { print $3 }’); do git cat-file -p $blob > $blob.txt; done

然后手动经历痛苦来重新 -以正确的结构组织您的文件。

要点:如果您没有完全 100% 理解它的工作原理,切勿使用 git reset --hard ,最好不要使用它。

This has saved my life:
https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c

Basically you need to run:

for blob in $(git fsck --lost-found | awk ‘$2 == “blob” { print $3 }’); do git cat-file -p $blob > $blob.txt; done

Then manually going through the pain to re-organise your files to the correct structure.

Takeaway: Never use git reset --hard if you dont completely 100% understand how it works, best not to use it.

夕色琉璃 2024-07-11 02:43:41

git reflog 并返回到最后一个 HEAD
6a56624 (HEAD -> master) HEAD@{0}: 重置: 移动到 HEAD~3
1a9bf73 HEAD@{1}:提交:在模型生成二进制文件中添加更改

git reflog and back to the last HEAD
6a56624 (HEAD -> master) HEAD@{0}: reset: moving to HEAD~3
1a9bf73 HEAD@{1}: commit: add changes in model generate binary

浅暮の光 2024-07-11 02:43:41

我的问题几乎相似。 在输入 git reset --hard 之前我有未提交的文件。

值得庆幸的是。 我设法跳过所有这些资源。 当我注意到我可以撤消(ctrl-z for windows/linux cmd-shift-z for mac)。

My problem is almost similar. I have uncommitted files before I enter git reset --hard.

Thankfully. I managed to skip all these resources. After I noticed that I can just undo (ctrl-z for windows/linux cmd-shift-z for mac). ???? I just want to add this to all of the answers above.

Note. Its not possible to undo unopened files.

情何以堪。 2024-07-11 02:43:41

git reset --hard - 您可以用来恢复一页,之后您可以再次从原点隐藏或提取所有内容

git reset --hard - you can use to revert one page and after that you can stash or pull everything from origin again

断舍离 2024-07-11 02:43:41

小型可执行文件,将所有内容放入 output.txt 文件中。 如果您不小心删除了所有尚未提交的文件(也在 git init 之后),则很有用:

#!/bin/bash

# Output file
output_file="output.txt"

# Re-create file
> "$output_file"

# Find all lost objects
for sha1 in $(git fsck --lost-found | grep 'blob' | awk '{print $3}'); do
    # write content
    echo "Content of $sha1:" >> "$output_file"
    git show "$sha1" >> "$output_file"
    echo -e "\n\n" >> "$output_file"
done

Small executable which put's all contents into a output.txt file. Useful if you accidentally deleted all files which weren't committed yet (also after a git init):

#!/bin/bash

# Output file
output_file="output.txt"

# Re-create file
> "$output_file"

# Find all lost objects
for sha1 in $(git fsck --lost-found | grep 'blob' | awk '{print $3}'); do
    # write content
    echo "Content of $sha1:" >> "$output_file"
    git show "$sha1" >> "$output_file"
    echo -e "\n\n" >> "$output_file"
done
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文