【问题标题】:How can I recover a lost commit in Git?如何在 Git 中恢复丢失的提交?
【发布时间】:2019-06-15 12:29:48
【问题描述】:

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

我如何才能找回过去 11 小时所做的事情?

【问题讨论】:

标签: git


【解决方案1】:

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

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

【讨论】:

  • 看看git log HEAD@{1}。如果这看起来是正确的一系列提交,那么您可以git reset HEAD@{1}
  • 仅当代码被暂存(使用 git add)时,它们才会保存在 git 中,并且可以使用 git fsck --lost-found 之类的命令轻松找到。
  • 在变基时不小心放弃了我应该保留的提交。这完全让我免于重做几个小时的工作。
  • 这救了我的命。
  • 这拯救了我的理智:D
【解决方案2】:

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

First of all what is HEAD?

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

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


detached HEAD

如果您不是最新的提交 - 这意味着 HEAD 指向历史上的先前提交,它被称为 detached HEAD

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


关于如何从分离的 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
git reflog 将显示更新 HEAD 的任何更改,并且检查所需的 reflog 条目会将 HEAD 设置回此提交。

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

git reflog
git checkout HEAD@{...}

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


git reset --hard &lt;commit_id&gt;

“移动”你的 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.
  • 注意:(Since Git 2.7) 您也可以使用git rebase --no-autostash

git revert &lt;sha-1&gt;

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

# 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>

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

【讨论】:

  • 这为我节省了很多时间。我使用“git reflog --date=iso”查看每个条目的日期/时间,因为没有时间戳我无法确定。
  • 对我来说,在git reset --hard &lt;commit_id&gt; 中,删除HEAD 有效! +1 用于图形表示!!。
  • 顺便提一下:如果您知道分支名称:git reflog &lt;branchname&gt; 会非常有用,因为您只看到一个分支的变化。
  • 很好的解释。我倾向于在我希望它放在那里的分支上使用git cherry-pick &lt;dangling-commit-hash&gt;
【解决方案3】:

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

git fsck --lost-found

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

dangling commit xyz

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

git merge xyz

注意:
如果我们已经运行了git gc 命令,我们将无法使用fsck 取回提交,该命令将删除对悬空提交的引用。

【讨论】:

  • 如果您最近没有指出有问题的提交,这是唯一有效的答案,例如当您获取一个分支然后意外地在其他地方重置该分支时。
【解决方案4】:

试试这个, 这将显示一段时间内记录在 git 中的所有提交

git reflog

找到你想要的提交

git log HEAD@{3}

git log -p HEAD@{3}    

然后检查它是否正确:

git checkout HEAD@{3}

这将为该提交创建一个分离的头部。如果需要,添加并提交任何更改

git status 
git add
git commit -m "temp_work" 

现在,如果想将提交恢复到分支,比如说 master,您需要将此分支开关命名为 master,然后合并到 master。

git branch temp
git checkout master
git merge temp

这里还有一个 Git 教程网站上专门针对 reflog 的链接: Atlassian Git Tutorial

【讨论】:

    【解决方案5】:

    这件事就发生在我身上,所以我正在写一些对我来说是救命稻草的东西。我的回答与@Amber 的回答非常相似。

    首先,我做了一个git reflog 并搜索了该特定提交的哈希,然后复制了该哈希并从该分支执行了一个git cherry-pick &lt;hash&gt;。这将丢失提交的所有更改带到了我当前的分支,并恢复了我对 GIT 的信心。

    祝你有美好的一天!

    【讨论】:

      【解决方案6】:

      如果您无法通过 git reflog 找到您的提交,并且碰巧您使用的是 IntelliJ IDE,您可以 right click on your project root folder -&gt; Local History -&gt; Show History 并从那里恢复您的更改。

      我把git rebasegit push -f 搞砸了,这确实救了我,因为提交是从本地和远程存储库中删除的。

      希望能拯救别人的一天

      干杯

      【讨论】:

        【解决方案7】:

        可悲的是 git 太不可靠了 :( 我刚刚失去了两天的工作:(

        最好在提交之前手动备份任何内容。我只是做了“git commit”,而 git 只是破坏了我所有的更改,什么也没说。

        我吸取了教训 - 下次先备份,然后再提交。永远不要相信 git。

        【讨论】:

        • 你能看一下基本的 git 教程吗? :) 例如:product.hubspot.com/blog/git-and-github-tutorial-for-beginners 我不想冒犯你,但你没有做对。你可以相信 git。你只需要学会使用它。 :)
        • 我已经使用 git 多年了。这是 git 中的一个错误,与用户空间无关:我照常进行了 git commit,但它破坏了我所有的东西,所以我看不到我的所有更改。 git log 给出了注释并且 git 回到了更改之前的状态。 Git 甚至没有报告任何内容。我猜 git 在提交过程中崩溃了。
        • 除非nano 崩溃,否则我永远不会失去工作。你可能有一个我们没有的问题,或者你可能在不知情的情况下就搞砸了,我已经做过很多次了;D
        • 此外,如果 git 在提交过程中崩溃,它不会恢复您的所有更改——最坏的情况是它会创建一个您可以恢复的损坏提交。确定你没有git stash;git stash drop
        • git 是世界范围内的行业标准版本控制工具。从大型公司到学生,每个人都在使用它。你真的认为每个人都会使用一个漏洞百出的工具,以至于它不能做它应该做的唯一事情吗?
        猜你喜欢
        • 1970-01-01
        • 2015-06-28
        • 1970-01-01
        相关资源
        最近更新 更多