如何在Git中恢复丢失的存储库?

2467

我经常使用git stashgit stash pop来保存和恢复我的工作树中的更改。昨天,我在我的工作树中有一些已经被存储和弹出的更改,然后我又对我的工作树进行了更多的更改。我想回去查看昨天存储的更改,但git stash pop似乎删除了所有相关提交的引用。

我知道,如果我使用git stash,那么.git/refs/stash包含用于创建存储的提交的引用。而.git/logs/refs/stash包含整个存储。但是,在git stash pop之后,这些引用都没有了。我知道提交仍然在我的仓库中,但是我不知道它是什么。

是否有一种简单的方法来恢复昨天的存储提交引用?


105
未来注意事项:如果你不想在每次使用git stash pop时丢失你的储藏,你可以使用git stash apply代替。它做的与pop相同,但不会删除已应用储藏的引用。 - Kevin
16
在这里尝试了一切,都找不到已经弹出的藏匿点。非常感激 IntelliJ 的 https://www.jetbrains.com/help/idea/local-history.html - Ruan Mendes
另请参阅如何恢复隐藏的未提交更改 - mfaani
5
建议:对于任何你不愿意丢失的内容,避免使用 git stash。如果值得保存,那么就值得进行完整的提交(可能在单独的临时分支上)。使用 git commit,你的“stash”将更容易跟踪。首先,你可以包括提交信息。但更重要的是,即使你重置/删除了分支,你的更改也会在本地 reflog 中访问。详情请见 even if you reset/delete the branch - Brent Bradburn
我同意Brent的观点,不过你可以使用git stash push -m“我的存储消息…”为你的git存储条目添加消息,以更好地组织它们。 - James Hooper
非常感谢您提出这个问题,以及回答它的人。虽然这种情况并不经常发生在我身上,但在过去两周内,我的肌肉记忆竟然让我输入了 git stash clear 命令来清除杂乱的存储区。这个帖子帮助我恢复了存储区的提交。 - Aman
25个回答

5

根据以下步骤恢复:

  1. 确定已删除的存储哈希码:

    gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

  2. 挑选Stash:

    git cherry-pick -m 1 $stash_hash_code

  3. 如有冲突,请使用以下命令解决:

    git mergetool

此外,如果您正在使用Gerrit,则可能遇到提交消息方面的问题。在执行下一步操作之前,请先将更改Stash起来:

  1. 使用硬重置返回至上一个提交版本,然后重新提交此更改。
  2. 您还可以将更改Stash起来,然后进行变基并重新提交。

@miva2,你的编辑删除了这个问题中最正确答案的链接。在评论中添加链接:https://dev59.com/NXVD5IYBdhLWcg3wGXlI#91795 - Abhijeet

1

通过大致了解文件名和位置,可以使用 grep 命令在悬空提交中查找丢失的储藏文件。

for i in $(git fsck --no-reflogs | awk '/dangling commit/ {print $3}'); do
  if git log -5 --name-only -u $i | grep -q "<path-to-files>/.*<partial-file-name>.*"; then
    echo "found something in commit $i";
  fi;
done

1

如果目标是获取在另一个分支中首先被存储然后弹出的未提交更改,但是这些更改既适用于当前分支也适用于之前的分支,则以下方法可以实现:

  1. branch_a 中进行更改
  2. git stash
  3. branch_a 创建 branch_b
  4. git stash apply

然后将未提交的更改恢复到 branch_a

  1. git checkout branch_a
  2. git merge branch_b
  3. git reset HEAD~1

0
您可以按照以下步骤进行操作:
1. 使用以下命令列出所有无法访问的提交记录 git fsck --unreachable 2. 使用以下命令显示无法访问的提交记录哈希值 git show [哈希值]
3. 复制所有日志,您可以看到像无法访问的 blob、commit、tree 等日志。
4. 使用具有提交记录哈希值的日志应用 git stash git stash apply [替换哈希值]

0

Github桌面版

如果您使用Github桌面版储存了您的更改,并且意外地删除了储存的更改,那么您可以运行以下命令来搜索悬空的储存提交(基于此答案):

注意:如果使用Windows,请使用Git Bash运行命令(Git Bash已与git安装一起安装)

git log --graph --oneline --decorate --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' ) | grep 'GitHub_Desktop'

你将会得到一个类似的提交列表:
| *   b7f1b023 On main: !!GitHub_Desktop<main>
| * 7e949012 On main: !!GitHub_Desktop<main>
| * 7de9b9ca On main: !!GitHub_Desktop<main>

获取列表中第一个的提交。在上面的例子中,它将是b7f1b023,然后运行以下命令:
git stash apply b7f1b023

这将恢复您的更改。如果没有恢复成功,您可以尝试输出中的其他提交。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接