【问题标题】:How can I fix a missing blob in Git?如何修复 Git 中丢失的 blob?
【发布时间】:2014-09-01 18:48:10
【问题描述】:

因为我一直在各个地方之间同步我的 Git 存储库,所以我现在遇到了一个损坏的 Git 存储库。当我执行git log 时,我得到了正确的历史记录,但是当我执行git status 时,我得到了

fatal: unable to read 563e4c9abcd4114e08255db989f0f53426bdeff7

所以经过一番搜索后,我尝试了git fsck

Checking object directories: 100% (256/256), done.
missing blob 33244941016301570dccdcdc95e543910109d0a8
dangling blob 59f44441e6437ebc4d40182eb8a10d3e07fe367b
missing blob 5dc8ab1804acb58fc658bcd6152fbb246290c8ae
dangling blob 698c775f2599fad3d09906dead4dc67743a984bd
dangling blob 922003b8433bcad6ce9778a37628d738faa26389
dangling blob c33c0528bfee55b04d99de4580da49de4413329b
dangling blob e5107c118bde0edbe5dfb994cb6a50d235c3f06b
dangling blob 437573e539572454cb868ca5a0f5074b96d777ac
missing blob 468d1856336eaa1ce8006f38ce779c0d997c8d48
dangling blob 6fc9c88708d7d5ca455e68781472bdea119997eb
dangling blob 7225d0147fa566369ba3024324b527a7adeac094
dangling blob bb8125d15579fcf37925f09cd1883b15272f9f0d
missing blob c8095f49253ac3787a6f86943160eda2c78a6a28
dangling blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
dangling blob 0bdaed084e15add987ef86fe84f435d085475995
dangling blob 36ee13c9b334da090ea6b194606df8a2852b3b3a
missing blob 563e4c9abcd4114e08255db989f0f53426bdeff7   <= the one which results in the fatal error.
dangling blob 84f2f2a9d1d051e6418a787ca90e75446f712866
dangling blob c636d85269838efecbb496eda5a8cfd8ec753d69
dangling blob cb7a8494bfc86e894c0c6e268308ddc1dd6d713c
dangling blob d166fff9e1c85ab9f0f4f620119181c5f76c2a53
dangling blob d3b6f194df857412481a318d4275faeb6689e4a0
missing blob db9a6744bc0df03cf685296695bea6324f23e0ac
dangling blob def6a6a18457989c7d18825c7c1bbfeefc8b261d
and about 20 more..

从这里我有点迷路了。我 read something about 运行 git reflog expire --expire=now --all,但这对我没有任何作用。

我的存储库中的所有文件仍然存在并安全备份,所以这不是问题。不过,我想找回我的存储库历史记录。从这一点我可以采取哪些步骤?

【问题讨论】:

  • 小贴士:在尝试修复任何内容之前,先复制损坏的 repo。这样,如果你最终让事情变得更糟,你总是可以回去。此外,要查看潜在问题,您可以运行 git fsck --no-dangling。悬空物体不是问题。但是丢失的对象是。

标签: git blob git-branch corruption corrupt


【解决方案1】:

在尝试修复 "object file is empty" error 后,我得到了一个“丢失的 blob”(实际上我最终从文件系统中删除了目标文件 .git/objects/f7/880aa1d1a76bfff73f3d602e15b4bc829d6a07)。

为了解决这个问题,我按照以下步骤操作:

  1. 使用 Bash 脚本 found here 来检测包含此缺失 blob 的提交。将其放在存储库的根目录中,名称为find.sh

    #!/bin/sh
    obj_name="$1"
    shift
    git log "$@" --pretty=format:'%T %h %s' \
    | while read tree commit subject ; do
        if git ls-tree -r $tree | grep -q "$obj_name" ; then
            echo $commit "$subject"
        fi
    done
    

    然后运行它,将丢失的 blob 的 SHA-1 哈希作为参数传递:

    ./find.sh f7880aa1d1a76bfff73f3d602e15b4bc829d6a07
    
    629afc4 ESLint warning in layers' configuration file is fixed.
    

    629afc4 是提交的 SHA-1 的一部分(这是我尝试推送到远程存储库的最后一次提交)。

  2. 查找与此 blob 关联的文件:

    git ls-tree -r 629afc4 | grep f7880aa1d1a76bfff73f3d602e15b4bc829d6a07
    
    100644 blob f7880aa1d1a76bfff73f3d602e15b4bc829d6a07    src/config/layers.js
    

    在我的例子中是src/config/layers.js

  3. 检查文件的哈希是否与 Git 树中的哈希匹配:

    git hash-object src/config/layers.js
    
    f7880aa1d1a76bfff73f3d602e15b4bc829d6a07
    
  4. 如果是这样,那么我们可以将文件内容写入 blob:

    git hash-object -w src/config/layers.js
    

执行这些步骤帮助我消​​除了错误并修复了损坏的本地存储库。解决方法见this article

【讨论】:

  • 非常感谢。这真的很有帮助。
  • 为我工作。在我的情况下,文件在那里但为空,所以最后一个命令没有做任何事情。我不得不删除文件(例如rm -f .git/objects/f7/880aa1d1a76bfff73f3d602e15b4bc829d6a07)并再次运行git hash-object -w 命令。
  • 我在尝试将单个文件恢复到之前提交的状态后进入了这种状态,所以我确切地知道我需要什么文件并跳到第 4 步。我不知道发生了什么,但它有效,谢谢!
【解决方案2】:

接受的答案或任何变体对我都不起作用,因为 git fsck 没有显示丢失的 blob 也没有

$ git ls-tree -r HEAD | grep <missing blob hash id>

返回任何东西。

对我有用的是我使用的一个小技巧。我分享它以防有人遇到它。

我将 repo 克隆到一个新位置并将其签出到我正在处理的分支。我搁置了当前损坏的 repo 中的更改(因为我有一些我不能丢失的更改),然后将 .git 文件夹从新克隆的 repo 复制到旧 repo。然后我运行了git pull,然后运行了。

【讨论】:

    【解决方案3】:

    接受的答案帮助我解决了问题。

    但是,如果丢失的 blob 是当前目录中的文件,我建议更快地修复(这是我的情况)。

    这意味着,由于某种原因,文件未被 git 正确索引,并导致 missing blob

    要查找缺少的 04da887681cecfd6cd59a928008b0e52ffe2a2bf 的 blob,您可以转到 .git 目录,然后启动:

    find . -type f -print -exec git hash-object {} \; | grep -B1 04da887681cecfd6cd59a928008b0e52ffe2a2bf
    

    这将遍历您的数据以查找未编入索引的文件。 如果它找到了一些东西,你现在就有了要索引的文件:

    ./myfile.php
    04da887681cecfd6cd59a928008b0e52ffe2a2bf
    

    然后,您可以将其索引为:git hash-object -w ./myfile.php

    如果它没有找到该文件,这意味着它可能是该文件的先前版本,或者一个已丢失的文件。

    【讨论】:

      【解决方案4】:

      我知道这是一个相当老的问题,但我刚才遇到了同样的问题,其他 SO 答案都没有对我有用,这里提供的答案也没有。

      阅读你的问题,我从你的第一句话中得到了一个想法:

      因为我一直在不同地方之间同步我的 git 存储库,所以我现在遇到了一个损坏的 git 存储库。

      我正在使用 USB 记忆棒进行同步。这样我就可以在我的任何设备上的工作目录中 git pull &lt;path/to/usb/repo&gt; master 从 USB 记忆棒中提取,并“推送”到 USB 记忆棒我将目录更改为 USB 记忆棒存储库并使用 git pull &lt;path/to/working/directory&gt; master。直到今天它工作了好几次。在我的一个工作目录中执行 git pull &lt;path/to/usb/repo&gt; master 时,我得到了

      errror: git upload-pack: git-pack-objects died with error.
      fatal: git upload-pack: aborting due emote: fatal: unable to read 8f6d079cdb5243f5a2d1000e31967f4c361b7966
      remote: aborting due to possible repository corruption on the remote side.
      

      在我的 USB 存储库中执行 git fsck 时,我得到了 missing blob ......(对不起,我没有复制它,但它只是丢失了 2 个 blob)。总而言之,我的问题和你的很相似。阅读您的文章,我得到了以下想法:

      TL;DR: 最后我做了 Windows scan and fix 的事情,如图所示 here,实际上每次我插入我的任何 USB 记忆棒时都会弹出它并且从未执行任何操作我发现很有用 - 直到现在。它实际上解决了整个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-23
        • 2017-01-02
        • 2019-06-15
        • 2016-06-15
        相关资源
        最近更新 更多