繁体   English   中英

修复损坏的 Git 存储库

[英]Repair corrupted Git repository

由于电源问题,我的 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...)

所以,正如你所看到的,我当前的分支非常糟糕,我似乎无法修复它。 我可以尝试修复什么?

我针对类似情况的解决方案是将.git/refs/heads/my-working-branch损坏对象的哈希替换为先前提交的哈希(可以在.git/logs/HEAD )。

这只是发生在我身上。 我在新文件夹中重新克隆存储库并手动移动我的最新更改。 技术含量低,但每次都有效。 希望你能记住你最近的变化。

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

(如果您还没有在您的磁盘上运行fsck ,您也应该这样做。)

对我来说最简单的解决方案:您应该在新文件夹中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/

对我来说,我在 OS X 中使用非 Apple SSD(不推荐)启用了 TRIM,并且显然导致了我的启动盘上的各种损坏。 因此,损坏的提交在历史中很深。

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

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

无论如何,我偶然发现了这种将分支推送到另一个本地 Git 存储库的酷策略 不幸的是,将存储../repo_copy../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并设置我的主分支,然后备份并运行,没有丢失任何东西!

另一种对我有用的替代方法是使用以下方法将 Git 头和索引重置为以前的状态:

git reset --keep

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

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

我遇到了同样的问题,并使用git-repair 执行了以下步骤

  • cp myrepo myrepo.bak
  • cd myrepo
  • git repair --force (先不force试试)

成功后,树被设置回上次工作提交。

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

我能够从以下位置恢复我的存储库:

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'

我按照从损坏的 Git 存储库恢复中找到的说明进行操作:

$ 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

它对我有用。

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

我是如何修复它的:

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

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

如果无法修复,有时检索内容会很有用。 以下命令将打印未损坏对象的所有内容。

$ git cat-file --batch-check --batch-all-objects 2>&1 | grep blob | grep -v empty | awk '{ print $1; }' -

我有一些损坏的文件并使用git-repair 修复它们

sudo apt install git-repair 
git repair

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM