恢复 git merge --abort 后删除的 git 文件

问题描述 投票:0回答:4

我丢失了在“合并冲突”阶段添加到 git 的文件。

一步一步:

git pull
git status

Git 通知我“合并冲突”,没关系。然后我创建一个新文件并将其添加到 git。

vi test.txt
git add test.txt

之后,中止合并:

git merge --abort

我既没有在目录中找到文件“test.txt”,也没有通过“git fsck”或“git reflog”找到文件。可以恢复文件吗?

git git-merge git-pull
4个回答
25
投票

您尝试过什么

git fsck

看到这个问题:恢复已添加到索引但随后通过 git Reset 删除的文件


一般答案是:您键入的指令序列已将文件从跟踪(以及从磁盘)中删除,无法保证可以检索文件的内容。

但是,

git
有很多安全机制,其中之一是:如果在存储库中的某个地方输入了一些数据,那么它在两周之前不会被删除。

git
有垃圾回收机制,见
git help gc


如果您确实在某个时刻运行了

git add test.txt
,并且此操作是最近的,那么应该仍然存在一些存储在 git 中的文件内容的痕迹:

git fsck --full --unreachable --no-reflog

git
的说法,文件就是
blob
:

git fsck --full --unreachable --no-reflog | grep blob

这应该会给你一个内部 git 哈希值列表:

unreachable blob 08bf360988858a012dab3af4e0b0ea5f370a2ae8
unreachable blob 21bf7ea93f9f9cc2b3ecbed0e5ed4fa45c75eb89
unreachable blob 08c12ef37075732cf4645269ab5687ba6ba68943
...

请注意,

git add file.txt
存储文件的内容,而不是文件的名称 ...

如果您记得文件中的特定字符串,您可以尝试使用

git grep <string> <hash>
:

缩小您的研究范围
$ git fsck --full --unreachable --no-reflog | grep blob | awk '{ print $3 }' > list.txt
$ cat list.txt | while read blob; do
  if git grep -q "string" $blob; then
    echo $blob
  fi
done

然后您可以使用以下命令查看 blob 的全部内容:

git show $blob

并希望找到您正在寻找的文件。


4
投票

抱歉我的英语不好。

谢谢回复#1。我恢复了我的文件!!!快乐^.^

我确实喜欢这样:

git fsck --full --unreachable --no-reflog | grep blob | awk '{ print $3 }' > ~/Downloads/git.txt

然后我用我记得的不同关键字保存文件和命名文件夹:

    # execute it in your git project
    cat ~/Downloads/git.txt | while read blob; do
      if git grep -q "keyword in your lost content" $blob; then
        echo $blob; git show $blob > ~/Downloads/git-above-keyword/$blob.ts
      fi
    done

如果您丢失了更多内容,您应该使用不同的关键字多次执行上述命令。你会得到很多关键字文件夹。

我打开另一个 vscode 并打开每个关键字文件夹,将每个 $bold.ts 代码复制到我的项目文件中。请小心,因为 $bold.ts 可能有重复代码,您应该区分最后一个代码。


2
投票

在编辑这个答案之前我并不知道(另一个解决方案正确地指向

git fsck
)。

如果您遇到同样的情况,您应该制作

git commit
而不是
git merge --abort

正如 @Muneer Bits 所说,我建议你阅读一些 git 基础知识。 官方网站包含大量文档和示例。您甚至可以通过交互式教程在线尝试。 关键是,如果您的工作已提交或隐藏,您就不会丢失它。 我强烈建议您阅读 git 一直输出的建议(除非您有旧版本,在这种情况下您也应该升级)。这些提示应该告诉您首先通过添加文件来标记提交已解决,然后通过执行 git commit 来完成合并。

合并提交只是两个父级的特殊提交。这意味着它们需要在某个时刻提交,无论是自动(如果没有冲突)还是手动。当您中止合并时,您将所有更改恢复(重置)到合并之前的状态。因此你失去了所做的每一项更改。

可能的解决方案(取决于您的工作流程):

git pull #merge conflict, solve it manually git add modified_files_for_merging git commit touch test.txt git add test.txt git commit

请注意,合并并未中止。

还要注意,拉取时合并并不总是最好的解决方案。您还可以

使用 rebase

进行拉取。但我强烈建议您在尝试冒险的工作之前先熟悉一下 git。并且,一如既往,您最终选择的解决方案将取决于您的工作流程。


0
投票

命令如下所示:

git fsck --full --unreachable --no-reflog >log.txt for /F "tokens=1,2,3 delims= " %a in (log.txt) do if %b == blob git show %c >%c.txt

如果批量使用,记得将
%

替换为

%%
它将恢复一堆.txt 文件,恢复后您需要将其映射到正确的文件。

© www.soinside.com 2019 - 2024. All rights reserved.