撤销 git merge --abort 后删除的git文件

10

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

步骤如下:

git pull
git status

Git告诉我有"合并冲突",没关系。然后我创建一个新文件并把它添加到git。

vi test.txt
git add test.txt

之后,中止合并:

git merge --abort

我在目录中、通过"git fsck"和"git reflog"都没有找到文件"test.txt"。有没有可能恢复这个文件?

4个回答

26

你尝试过使用 git fsck 吗?

可以参考这个 SO 问题: 恢复被 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

希望您能找回您正在寻找的文件。


2
让我在合并中止后免于丢失重要更改! - Vinayak Gadkari
2
这真是太好了。省下了我数小时的工作时间。谢谢! - TheAppMentor

4

非常抱歉我的英语不太好。

感谢第一条回复。我已经成功恢复了我的文件!!!开心 ^.^

我按照以下步骤进行了操作:

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可能会有重复的代码,你需要区分最后的代码。

你好!我在这里想说,你的线程和回答救了我的命。谢谢! - Pedro Vítor

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

这里的其他答案都是针对Linux的。我想在Windows上恢复所有已删除的文件,需要使用Windows批处理魔法来完成。

命令看起来像这样:

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 文件,然后你需要在恢复后将其映射到正确的文件上。


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