2011-11-25 261 views
32

由于电源问题,我的git存储库在几次硬重启之后遭到破坏,现在我无法修复它(我在最后一次电源故障时正在暂存一些文件)修复损坏的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...) 

所以,正如你所看到的,我目前的分支是相当搞砸了,我似乎无法修复它。任何ideea我可以尝试修复这个问题?

+1

是这个服务器回购吗?那里是否存在可用于恢复的本地克隆/回购? – prusswan

+1

这是我的本地git回购...我在另一台机器上有一个克隆,我可以用它来恢复一切(也许有一些提交失败),但我宁愿修复这个回购如果可能... – Unknown

+0

这是值得一提的工作文件夹的内容可能仍然可以恢复。做'git diff> diff.patch',然后你可以像这样使用它来修补一个新的克隆:'git patch -p1 datashaman

回答

5

尝试对存储库进行备份,然后运行git reset --hard [email protected]{1}以返回到之前的HEAD并查看是否有效。它可能只是当前的HEAD已损坏。

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

+1

$ git reset --hard HEAD @ {1} 检出文件:100%(5724/5724),完成。 致命:无法读取对象3d18855708b0f127d40c13c679559d7679228b69:无效的参数 – Unknown

+0

该死的。 'git reflog'工作吗? –

+1

没有,同样的事情:($ git的引用日志 致命的:无法读取对象3d18855708b0f127d40c13c679559d7679228b69:无效的参数 – Unknown

31

我对类似情况的解决方案是与以前的承诺哈希更换损坏的对象的散列.git/refs/heads/my-working-branch(其中可以在.git/logs/HEAD中找到)。

+1

仍然使存储库处于损坏状态,但是这允许恢复它。 – ony

+5

我不确定我明白这是什么 –

+0

哇。这是有效的......我的头部已经被破坏到^^^ @^@^@ ...'或者类似的东西。 –

9

对我来说,我已经在OSX中使用非Apple SSD(这是不推荐的)启用TRIM,并且显然在我的启动盘上导致了各种损坏。所以腐败的承诺在历史中很深刻。

我不在乎修复我的回购,除非我有几个本地分支机构太过实验性,无法打开推送到远程回购,我想打捞这些分支的工作。

理论上,因为这是一个本地回购,我觉得git应该能够使用原点来恢复/修复自己。为什么这不可能?

在我对面this cool strategy to push a branch to another local git repo.偶然不幸的是,克隆回购为../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 [email protected]:sdhull/my_repo.git # real remote 

然后我进去git config -e和设置我的主分支进行了备份,并与没有丢失运行!如果您想了解关于此方法的更多详细信息,请在评论中告诉我。干杯!

14

这只是发生在我身上。我在新文件夹中重新登录存储库并手动移动我的最新更改。低科技但每次都有效。希望你能记住你最后的变化。

+4

您可以简单地将破损的回购库中的'.git'文件夹替换为您所回收的文件夹。这样你就不需要手动移动你的改变。只需注意分支。您可能必须存储并检出正确的分支。 –

3

我能够从恢复我的回购:

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 <[email protected]> 1379583764 +0300 commit: plan: timings 

通过重置master到上一个承诺da9c14d03e4849394087b61ff6272399937f7cce方说@Nash桥:

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. 

恢复thos这是对的方式来master E会变更:

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

我跟着指示找到here

$ 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 

为我工作

1

对我来说,最简单的办法:你可以在一个git克隆新文件夹,然后将干净的new_folder/.git替换为旧文件夹(损坏的文件夹)。这对我来说很有效 !

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

干杯!

1

这为我工作的另一种方法是使用到GIT头和指数恢复到以前的状态:

git reset --keep

我也尝试下面的命令,但他们并没有为我工作,但他们可能为你:

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