修复损坏的Git存储库

时间:2011-11-25 15:36:36

标签: git corruption

由于电源问题,我的Git存储库在几次硬重启后损坏了,现在我无法修复它(我在最后一次电源故障时正在暂存一些文件):

$ git status
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git fsck
fatal: failed to read object 24377c609184c192f3f3c1733bac7115c1080758: Invalid argument
$ git branch -a
(...works, lists branches...)
$ git checkout someotherbranch
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git log
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git log someotherbranch
(...works, shows commits...)

所以,正如你所看到的,我目前的分支已经搞砸了,我似乎无法修复它。我可以尝试修复此问题吗?

10 个答案:

答案 0 :(得分:34)

我对类似情况的解决方案是用.git/refs/heads/my-working-branch中的受损对象的哈希值替换前一次提交的哈希值(可以在.git/logs/HEAD中找到)。

答案 1 :(得分:16)

这恰好发生在我身上。我将存储库重新放入新文件夹中,并手动移动我的最新更改。技术含量低,但每次都有效。希望你能记住你最后的改变。

答案 2 :(得分:9)

对我来说,我在OS X中使用非Apple SSD(不推荐使用)启用了TRIM,并且显然在我的启动盘上造成了各种损坏。所以腐败的提交在历史的深处。

我不太关心修复我的存储库,除了我有一些本地分支太过实验性而无法推送到远程存储库,我想在这些分支中挽救这些工作。

理论上,由于这是一个本地存储库,我觉得Git应该能够使用origin恢复/修复自己。为什么这不可能?

无论如何,我偶然发现了this cool strategy to push a branch to another local Git repository。不幸的是,将存储库克隆到../repo_copy然后将其用作本地远程会导致以下错误:

! git push --force local_remote HEAD
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument
error: failed to push some refs to '/Users/steve/Dev/repo_copy'

所以我开始使用一个空的存储库,然后将分支推送到它工作正常。因此,对于我git log没有结束的任何本地分支:

....
    Fixing cukes
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument

我只是检查一下然后做git push --force local_remote HEAD。我做的最后一件事是:

! cd ~/Dev/repo_copy
! git remote add origin git@github.com:sdhull/my_repo.git  # real remote

然后我进入了git config -e并设立了我的主分支,然后又恢复了运行,没有任何损失!

答案 3 :(得分:7)

尝试备份存储库,然后运行git reset --hard HEAD@{1}以返回上一个HEAD,看看是否有效。它可能只是当前HEAD已损坏。

(如果您还没有,还应该在磁盘上运行fsck。)

答案 4 :(得分:3)

对我来说最简单的解决方案:您可以在新文件夹中git clone,然后将干净的new_folder / .git替换为旧文件夹(损坏的文件夹)。它适用于我!

git clone ...(remote) new_folder
mv old_folder/.git  old_folder/.git_old
cp -R new_folder/.git  old_folder/

答案 5 :(得分:2)

我能够从:

恢复我的存储库
zsh(broken)% git log master
error: object file .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395 is empty
error: object file .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395 is empty
fatal: loose object 7fcab8648a989d9bb3f5246e6be7220395493395 (stored in .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395) is corrupt
zsh(broken)% cat .git/refs/heads/master
7fcab8648a989d9bb3f5246e6be7220395493395
e311726c4eb970f4d4f504ad86248d322855018f da9c14d03e4849394087b61ff6272399937f7cce Nikolay Orliuk <virkony@gmail.com> 1379583764 +0300    commit: plan: timings

按照@Nash Bridges的说法将master重置为prev commit da9c14d03e4849394087b61ff6272399937f7cce

zsh(broken)% echo da9c14d03e4849394087b61ff6272399937f7cce > .git/refs/heads/master
zsh(broken)% git log --oneline -1 master
da9c14d plan: timings
zsh(broken)% git fsck
Checking object directories: 100% (256/256), done.
error: object file .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5 is empty
error: object file .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5 is empty
fatal: loose object 0eace931fdc851da254e9522596d1517d0ed51c5 (stored in .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5) is corrupt

创建一个新的空存储库,从破解中获取master

zsh(broken)% mkdir ../recover && cd ../recover && git init
Initialized empty Git repository in /home/nikolay/talks/y/recover/.git/
zsh(recover)% git fetch ../broken master
remote: Counting objects: 44, done.
remote: Compressing objects: 100% (44/44), done.
remote: Total 44 (delta 20), reused 0 (delta 0)
Unpacking objects: 100% (44/44), done.
From ../broken
 * branch            master     -> FETCH_HEAD
zsh(recover)% git reset --hard FETCH_HEAD
HEAD is now at da9c14d plan: timings
zsh% git fsck
Checking object directories: 100% (256/256), done.

要恢复到master的路上的更改:

zsh(recover)% rm -rf * && cp -a ../broken/* ./
zsh(recover)% git add -u && git commit -m 'prepare for publishing'

答案 6 :(得分:2)

另一个对我有用的选择是使用以下方法将Git头和索引重置为之前的状态:

git reset --keep

我也尝试了以下命令,但它们对我不起作用,但它们可能适合你:

git reset --mixed
git fsck --full
git gc --auto
git prune --expire now
git reflog --all

答案 7 :(得分:1)

我按照 Recovering from a corrupt Git repository 中的说明进行了操作:

$ cd /tmp/
$ git clone good-host:/path/to/good-repo
$ cd /home/user/broken-repo
$ echo /tmp/good-repo/.git/objects/ > .git/objects/info/alternates
$ git repack -a -d
$ rm -rf /tmp/good-repo

它对我有用。

答案 8 :(得分:1)

我遇到了同样的问题,并使用git-repair

执行了以下步骤
  • cp myrepo myrepo.bak
  • cd myrepo
  • git repair --force(首先在没有force的情况下尝试)

成功完成后,树被设置回最后一个工作提交。

然后我做了meld myrepo myrepo.bak,将更改从损坏的存储库的工作树应用到固定的存储库。

答案 9 :(得分:0)

当我更换分支时,Windows 出现蓝屏。启动备份,所有文件都已损坏,git 无法识别存储库。

我是如何修复它的:

  1. 我从远程克隆了一个新副本。
  2. 将 .git/index 和 .git/HEAD 文件复制到损坏的 .git 存储库中。
  3. git 终于认出了 repo,所以我做了一个硬结帐。
  4. 成功

注意:如果您有未提交的更改,此方法将覆盖它们。