代码之家  ›  专栏  ›  技术社区  ›  asgerhallas

git:“损坏的松散对象”

  •  265
  • asgerhallas  · 技术社区  · 14 年前

    每当我从遥控器中拔出时,我都会得到以下关于压缩的错误。当我运行手动压缩时,我得到相同的结果:

    $ git gc
    error: Could not read 3813783126d41a3200b35b6681357c213352ab31
    fatal: bad tree object 3813783126d41a3200b35b6681357c213352ab31
    error: failed to run repack
    

    有人知道该怎么办吗?

    我从cat文件中得到:

    $ git cat-file -t 3813783126d41a3200b35b6681357c213352ab31
    error: unable to find 3813783126d41a3200b35b6681357c213352ab31
    fatal: git cat-file 3813783126d41a3200b35b6681357c213352ab31: bad file
    

    从Git fsck我得到这个(不知道它是否真的相关):

    $ git fsck
    error: inflate: data stream error (invalid distance too far back)
    error: corrupt loose object '45ba4ceb93bc812ef20a6630bb27e9e0b33a012a'
    fatal: loose object 45ba4ceb93bc812ef20a6630bb27e9e0b33a012a (stored in .git/objects/45/ba4ceb93bc812ef20a6630bb27e9e0b33a012a) is corrupted
    

    有人能帮我破译这个吗?

    21 回复  |  直到 6 年前
        1
  •  55
  •   Simon E. pbs    9 年前

    似乎有损坏的树对象。你需要从别人那里得到那个东西。希望他们有一个完整的版本。

    如果你无法通过猜测哪些文件应该存在来从其他人那里找到有效的版本,那么你可以重新构建它。您可能希望查看对象的日期和时间是否与其匹配。可能是相关的斑点。您可以从这些对象推断树对象的结构。

    看看 Scott Chacon's Git Screencasts 关于Git内部。这将向你展示Git是如何在引擎盖下工作的,以及如果你真的被卡住了,不能从别人那里得到这个物体,如何继续做这项侦查工作。

        2
  •  304
  •   ANeves    8 年前

    我也有同样的问题(不知道为什么)。

    此修复程序要求访问存储库的未损坏远程副本,并将保持本地工作副本的完整性。

    但它也有一些缺点:

    • 您将丢失未被推送的任何提交的记录,并且必须重新提交它们。
    • 你会丢失所有藏品。

    修复

    从repo上面的父目录执行这些命令(将“foo”替换为项目文件夹的名称):

    1. 创建损坏目录的备份:
      cp -R foo foo-backup
    2. 将远程存储库的新克隆到新目录:
      git clone git@www.mydomain.de:foo foo-newclone
    3. 删除损坏的.git子目录:
      rm -rf foo/.git
    4. 将新克隆的.git子目录移动到foo:
      mv foo-newclone/.git foo
    5. 删除临时新克隆的其余部分:
      rm -rf foo-newclone

    在Windows上,您需要使用:

    • copy 而不是 cp -R
    • rmdir /S 而不是 rm -rf
    • move 而不是 mv

    现在foo有了它的原版 .git 子目录返回,但所有本地更改仍然存在。 git status , commit , pull , push 等等。按他们应该的方式重新工作。

        3
  •  190
  •   Simon E. pbs    9 年前

    您最好的选择可能是简单地从远程回购(如Github或其他)中重新克隆。不幸的是,您将丢失任何未提交的提交和隐藏的更改,但是您的工作副本应该保持完整。

    首先备份本地文件。然后,从工作树的根开始执行此操作:

    rm -fr .git
    git init
    git remote add origin [your-git-remote-url]
    git fetch
    git reset --mixed origin/master
    git branch --set-upstream-to=origin/master master  
    

    然后根据需要提交任何更改的文件。

        4
  •  106
  •   Felipe Pereira FamiliarPie    8 年前

    在一台虚拟机上工作,在我的笔记本里,电池没电了,出现了这个错误;

    错误:对象文件.git/objects/ce/theref为空错误:对象 file.git/objects/ce/theref为空致命:松散的object theref (存储在.git/objects/ce/theref中)已损坏

    我设法让回购只需两个命令就可以重新工作 不会丢掉我的工作 (已修改的文件/未提交的更改)

    find .git/objects/ -size 0 -exec rm -f {} \;
    git fetch origin
    

    之后我跑了一个 git status ,回购很好,我做了一些修改(等待承诺,现在就做…)。

    Git版本1.9.1

    记住备份所有您记得的更改,以防此解决方案不起作用,需要更激进的方法。

        5
  •  38
  •   declan    8 年前

    我在写提交消息时计算机崩溃了。重新启动之后,工作树就像我离开它时一样,我能够成功地提交我的更改。

    但是,当我试图逃跑时 git status 我得到了

    error: object file .git/objects/xx/12345 is empty
    fatal: loose object xx12345 (stored in .git/objects/xx/12345 is corrupt
    

    与大多数其他答案不同,我没有试图恢复任何数据 . 我只需要git停止抱怨空对象文件。

    概述

    “对象文件”是Git对您关心的真实文件的散列表示。Git认为它应该有哈希版本的 some/file.whatever 存储在 .git/object/xx/12345 修复错误的过程主要是找出“松散对象”应该表示哪个文件。

    细节

    可能的选择似乎是

    1. 删除空文件
    2. 使文件进入Git可接受的状态

    方法1:删除对象文件

    我尝试的第一件事就是移动对象文件

    mv .git/objects/xx/12345 ..
    

    那不起作用-Git开始抱怨链接断了。接近2。

    方法2:修复文件

    莱纳斯·托瓦尔兹对 how to recover an object file 这为我解决了问题。这里总结了关键步骤。

    $> # Find out which file the blob object refers to
    $> git fsck
    broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
               to    blob xx12345
    missing blob xx12345
    
    $> git ls-tree 2d926
    ...
    10064 blob xx12345  your_file.whatever
    

    这将告诉您空对象应该是什么文件的散列值。现在你可以修理它了。

    $> git hash-object -w path/to/your_file.whatever
    

    做完这个之后,我检查了一下 .git/objects/xx/12345 它不再是空的,吉特也不再抱怨了。

        6
  •  12
  •   Arthur    13 年前

    尝试

    git stash
    

    这对我很有用。它藏着你没有承诺的任何东西,这就解决了问题。

        7
  •  6
  •   Jago    9 年前

    garbage collection 解决了我的问题:

    git gc --aggressive --prune=now
    

    完成需要一段时间,但每个松散对象和/或损坏的索引都已修复。

        8
  •  4
  •   halfer    10 年前

    我刚刚经历了这个-我的机器在写入git repo时崩溃了,它变得损坏了。我把它修好如下。

    我先看看我有多少承诺没有推动远程回购,因此:

    gitk &
    

    如果你不使用这个工具,它是非常方便的-据我所知,在所有操作系统上都可用。这表明我的遥控器缺少两个提交。因此,我单击了指示最新远程提交的标签(通常是 /remotes/origin/master )为了得到散列(散列长度为40个字符,但为了简洁起见,我在这里使用了10个字符——这通常都有效)。

    这里是:

    14c0fcc9b3型

    然后,我单击以下提交(即远程程序没有的第一个提交)并在那里获取哈希:

    04D44C3298

    然后,我使用这两种方法为这个提交创建一个补丁:

    git diff 14c0fcc9b3 04d44c3298 > 1.patch
    

    然后我对另一个丢失的提交也做了同样的处理,即我使用了提交之前的哈希和提交本身的哈希:

    git diff 04d44c3298 fc1d4b0df7 > 2.patch
    

    然后我移动到一个新目录,从远程克隆了repo:

    git clone git@github.com:username/repo.git
    

    然后,我将补丁文件移到新文件夹中,并应用它们,并用它们确切的提交消息提交它们(这些消息可以粘贴在 git log gitk 窗口):

    patch -p1 < 1.patch
    git commit
    
    patch -p1 < 2.patch
    git commit
    

    这为我恢复了一些东西(注意对于大量提交,可能有一种更快的方法来完成)。不过,我很想知道损坏的repo中的树是否可以修复,答案是它可以。如果修复的repo如上所述可用,请在损坏的文件夹中运行此命令:

    git fsck 
    

    你会得到这样的结果:

    error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
    error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
    error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
    

    要进行修复,我将在损坏的文件夹中执行此操作:

    rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
    cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
    

    也就是说,删除损坏的文件并用一个好的文件替换它。你可能要做几次。最后会有一个你可以跑的地方 fsck 没有错误。您可能会在报告中有“悬空提交”和“悬空blob”行,这是您在此文件夹中重新设置和修改的结果,可以。垃圾收集器将在适当的时候将它们移除。

    因此(至少在我的情况下)一个损坏的树并不意味着未完成的提交将丢失。

        9
  •  3
  •   Rebecca Dessonville    9 年前

    我也收到了一个损坏的松散对象错误。

    ./objects/x/x
    

    我通过进入损坏对象的目录成功地修复了它。我看到分配给那个对象的用户是 我的Git用户的。我不知道是怎么回事,但我运行了一个 chown git:git 在那个文件上,然后它又工作了。

    这可能是解决某些人问题的一个潜在方法,但并非所有问题都必须解决。

        10
  •  2
  •   Dean Rather    12 年前

    我的(Windows)机器决定重新启动后,出现了这个错误。 幸好我的远程回购是最新的,所以我刚刚做了一个新的git克隆。

        11
  •  2
  •   Community CDub    7 年前

    我遵循了这里的许多其他步骤;Linus关于如何查看Git树/对象并查找缺少的内容的描述特别有用。 git-git recover corrupted blob

    但最后,对于我来说,由于部分磁盘故障导致树对象松动/损坏,并且树对象不太容易恢复/不被该文档覆盖。

    最后,我移动了冲突 objects/<ha>/<hash> 让开,用 git unpack-objects 使用来自最新克隆的包文件。它能够恢复丢失的树对象。

    仍然给我留下了很多悬空的斑点,这可能是打开以前存档的东西的副作用,并在其他问题中解决。 here

        12
  •  2
  •   Ertuğrul Altınboğa    10 年前

    对于@user1055643缺少最后一步的回答:

    $ rm -fr .git
    $ git init
    $ git remote add origin your-git-remote-url
    $ git fetch
    $ git reset --hard origin/master
    $ git branch --set-upstream-to=origin/master master  
    
        13
  •  1
  •   Simonluca Landi    11 年前

    运行 git stash; git stash pop 解决了我的问题

        14
  •  1
  •   Christian Hujer    8 年前

    对我来说,这是因为在执行 git push

    消息如下:

    $ git status
    error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
    error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
    fatal: loose object c238824eb3fb602edc2c49fccb535f9e53951c74 (stored in .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74) is corrupt
    

    我尝试过 git fsck 但那没有帮助。 因为车祸发生在 Git推送 很明显,它是在客户机端的重写过程中发生的,在服务器更新之后发生的。我环顾四周,发现 c2388 在我的例子中是一个提交对象,因为在 .git/refs . 所以我知道我能找到 C23 88 当我查看历史记录时(通过Web界面或第二个克隆)。

    在第二个克隆上我做了一个 git log -n 2 c2388 确定 C23 88 . 然后我手动修改 .git/refs/heads/master .git/refs/remotes/origin/master 成为 C23 88 而不是 C23 88 。 然后我可以做一个 git fetch 。 这个 Git获取 在空对象上发生冲突时失败了几次。我把这些空东西都搬走了,直到 Git获取 成功。这治愈了知识库。

        15
  •  1
  •   mcginn    8 年前

    我是这样解决的: 我决定简单地将未损坏的对象文件从备份的克隆复制到我的原始存储库。这同样有效。(顺便说一下:如果在.git/objects/中找不到该对象的名称,那么它可能是为了节省空间而被[打包][打包]。)

        16
  •  1
  •   Tyler Gauch    6 年前

    只需运行 git prune 帮我解决了这个问题

        17
  •  0
  •   konyak    11 年前

    我在我的光秃秃的远程git repo中也遇到了同样的问题。经过大量的故障排除后,我发现我的一个同事提交了一个commit,其中.git/对象中的一些文件的权限是440(r--r------)而不是444(r--r--r--)。在要求同事在bare git repo中使用“chmod 444-r对象”更改权限后,问题得到了解决。

        18
  •  0
  •   Thomas Lobjoie    10 年前

    我们刚拿到案子。问题是损坏文件的所有权是根目录而不是我们的普通用户。这是由于有人在服务器上完成了“sudo-su--”之后所做的提交操作造成的。

    首先,确定损坏的文件:

    $> git fsck --full
    

    您应该收到这样的答案:

    fatal: loose object 11b25a9d10b4144711bf616590e171a76a35c1f9 (stored in .git/objects/11/b25a9d10b4144711bf616590e171a76a35c1f9) is corrupt
    

    进入损坏文件所在的文件夹并执行以下操作:

    $> ls -la
    

    检查损坏文件的所有权。如果情况不同,只需返回回购的根目录并执行以下操作:

    $> sudo chown -R YOURCORRECTUSER:www-data .git/
    

    希望有帮助!

        19
  •  0
  •   naught101 Ari B. Friedman    9 年前

    我就是遇到这样的问题。我的特定问题是由系统崩溃导致的,系统崩溃破坏了最近的提交(因此也破坏了主分支)。我没有推挤,想重新承诺。在我的特定案例中,我可以这样处理:

    1. 备份 .git/ : rsync -a .git/ git-bak/
    2. 检查 .git/logs/HEAD ,并找到具有有效提交ID的最后一行。对于我来说,这是第二次最近提交。这很好,因为我仍然有文件的工作目录版本,所以我想要的每个版本都有。
    3. 在该提交处创建分支: git branch temp <commit-id>
    4. 用工作目录中的文件重新执行中断的提交。
    5. git reset master temp 将主分支移动到步骤2中所做的新提交。
    6. git checkout master 并检查它是否与 git log
    7. git branch -d temp .
    8. git fsck --full ,现在可以安全地删除fsck发现的任何损坏的对象。
    9. 如果一切都很好,试着推。如果能成功的话,

    这对我很有用。我怀疑这是一个相当常见的场景,因为最近的提交是最有可能被破坏的,但是如果您再丢失一个,您可能仍然可以使用这样的方法,并小心地使用 git cherrypick 以及重新登录 .git/日志/头 .

        20
  •  0
  •   gareth    7 年前

    当我遇到这个问题时,我备份了我最近的更改(因为我知道我所做的更改),然后删除了它在.git/location中抱怨的文件。然后我拉了一下。不过要小心,这可能对你不起作用。

        21
  •  -6
  •   Ovidiu Matan    8 年前

    只需删除.git文件夹并重新添加即可。这个简单的解决方案对我很有效。