如何在 Git 中恢复丢失的提交?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10099258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 13:25:26  来源:igfitidea点击:

How can I recover a lost commit in Git?

git

提问by Elias7

First, got "your branch is ahead of origin/master by 3 commits" then my app has reverted to an earlier time with earlier changes.

首先,得到“您的分支领先于 origin/master 3 次提交”,然后我的应用程序已恢复到较早的时间,并进行了较早的更改。

How can I get what I spent the last 11 hours doing back?

我怎样才能收回我过去 11 个小时所做的事情?

回答by Amber

git reflogis your friend. Find the commit that you want to be on in that list and you can reset to it (for example:git reset --hard e870e41).

git reflog是你的朋友。在该列表中找到您想要的提交,您可以重置它(例如:)git reset --hard e870e41

(If you didn't commit your changes... you might be in trouble - commit early, and commit often!)

(如果您没有提交更改……您可能会遇到麻烦 - 尽早提交,并经常提交!)

回答by CodeWizard

Before answering, let's add some background, explaining what this HEADis.

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

First of all what is HEAD?

First of all what is HEAD?

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

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

The content of HEADis stored inside .git/HEADand it contains the 40 bytes SHA-1 of the current commit.

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



detached HEAD

detached HEAD

If you are not on the latest commit - meaning that HEADis pointing to a prior commit in history it's called detached HEAD.

如果您不在最新的提交上——这意味着它HEAD指向历史中的先前提交,则称为detached HEAD.

Enter image description here

在此处输入图片说明

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

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

Enter image description here

在此处输入图片说明

Enter image description here

在此处输入图片说明



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

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



git checkout

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

git reflog

You can always use the reflogas well.
git reflogwill display any change which updated the HEADand checking out the desired reflog entry will set the HEADback to this commit.

您也可以随时使用reflog
git reflog将显示更新HEAD并检出所需引用日志条目的任何更改将设置HEAD回此提交。

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

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

git reflog
git checkout HEAD@{...}

This will get you back to your desired commit

这会让你回到你想要的提交

Enter image description here

在此处输入图片说明



git reset --hard <commit_id>

git reset --hard <commit_id>

"Move" your HEAD back to the desired commit.

“移动”你的 HEAD 回到所需的提交。

# 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-autostashas well.


git revert <sha-1>

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 committed while the original commit will remain in the history as well.

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

# Add a 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 illustrates which command does what.
As you can see there, reset && checkoutmodify the HEAD.

这个模式说明了哪个命令做什么。
如您所见,reset && checkout修改HEAD.

Enter image description here

在此处输入图片说明

回答by Atri

Another way to get to the deleted commit is with the git fsckcommand.

获取已删除提交的另一种方法是使用git fsck命令。

git fsck --lost-found

This will output something like at the last line:

这将输出类似于最后一行的内容:

dangling commit xyz

We can check that it is the same commit using reflogas suggested in other answers. Now we can do a git merge

我们可以检查它是否与reflog其他答案中建议的提交相同。现在我们可以做一个git merge

git merge xyz

Note:
We cannot get the commit back with fsckif we have already run a git gccommand which will remove the reference to the dangling commit.

注意:如果我们已经运行了一个命令来删除对悬空提交的引用,
我们将无法恢复提交。fsckgit gc