我如何修复一个Git错误断开的树到树的链接?

niwlg2el  于 2023-02-02  发布在  Git
关注(0)|答案(4)|浏览(255)

我遇到一个事务中断,当我再次尝试时,对象为空或已损坏时出现错误,接着又问了一个问题,我删除了所有空文件,当我运行

git fsck --full

我得到这个错误:

Checking object directories: 100% (256/256), done.
Checking objects: 100% (48774/48774), done.
error: d193ccbc48a30e8961e9a2515a708e228d5ea16d: invalid sha1 pointer in cache-tree
error: df084ac4214f1a981481b40080428950865a6b31: invalid sha1 pointer in cache-tree
broken link from    tree 4bf4869299b294be9dee4ecdcb45d2c204ce623b
          to    tree df084ac4214f1a981481b40080428950865a6b31
broken link from    tree 4bf4869299b294be9dee4ecdcb45d2c204ce623b
          to    tree d193ccbc48a30e8961e9a2515a708e228d5ea16d
missing tree df084ac4214f1a981481b40080428950865a6b31
missing blob a632281618ca6895282031732d28397c18038e35
missing tree d193ccbc48a30e8961e9a2515a708e228d5ea16d
missing blob 70aa143b05d1d7560e22f61fb737a1cab4ff74c6
missing blob c21c0545e08f5cac86ce4dde103708a1642f23fb
missing blob 9f341b8a9fcd26af3c44337ee121e2d6f6814088
missing blob 396aaf36f602018f88ce985df85e73a71dea6f14
missing blob 87b9d1933d37cc9eb7618c7984439e3c2e685a11

如何解决此问题?
Git

elcex8rz

elcex8rz1#

有了Git 2.10(Q3 2016),你可以更好地了解那些断开链接的来源。

git fsck --name-objects

参见commit 90cf590commit 1cd772ccommit 7b35efdcommit 993a21b(2016年7月17日),作者为Johannes Schindelin ( dscho )
(由Junio C Hamano -- gitster --合并至commit 9db3979,2016年7月25日)

fsck:可选显示更多有用的信息为断开的链接

当报告提交/树/blob之间断开的链接时,如果能告诉用户如何访问对象,有时会很有帮助。
使用新的--name-objects选项,git-fsck将尝试执行以下操作:
用一种显示它们如何可达的方式来命名对象。
例如,当一些reflog被损坏并且丢失了不应该丢失的blob时,用户可能想要删除相应的reflog条目。
此选项可帮助用户查找该条目:git fsck --name-objects现在将报告如下内容:

broken link from    tree b5eb6ff...  (refs/stash@{<date>}~37:)
                to    blob ec5cf80...

如果这些断开的链接不是来自本地存储库,而是来自远程存储库,则fetching those pack objects can then solve the situation
另请参见"How to recover Git objects damaged by hard disk failure?"。
在Git 2.31(Q1 2021)中,修复了"git fsck --name-objects"(man),显然没有任何人使用过它,因为他有足够的动机去报告破损。
参见Johannes Schindelin ( dscho )commit e89f893commit 8c891ee(2021年2月10日)。
(由Junio C Hamano -- gitster --合并至commit 9e634a9,2021年2月17日)

fsck --name-objects:更仔细地分析世代号

签署人:约翰内斯·申德林
7b35efdfsck_walk():2016 - 07 - 17,Git v2.10.0-rc0--merge已在batch #7中列出)(fsck_walk():Optionally Name Objects on the Go,2016 - 07 - 17),fsck机器学会了对对象进行可选命名,这样就更容易看到存储库的哪个部分处于不良状态,比如说,对象何时丢失。
为了降低复杂性,这个机制使用解析器来确定给定提交名称的父提交的名称:解析任何~<n>后缀,并且从前缀连同~<n+1>形成父名称。
但是,这个解析器有一个错误:如果它发现后缀<n>是 * not * ~<n>,则它将把空字符串误认为前缀,而把<n>误认为世代号。
换句话说,它将生成~<bogus-number>的名称。
让我们来解决这个问题。
在Git 2.40(Q1 2023)中,"git hash-object"(man)现在检查生成的对象是否使用与git fsck "相同的代码格式良好。
参见第一版20f1x(2023年1月19日)和第一版27f1x的第一版21f1x、第一版22f1x、第一版23f1x、第一版24f1x、第一版25f1x、第一版26f1x(2023年1月18日)。
(由Junio C Hamano -- gitster --合并至commit abf2bb8,2023年1月30日)

hash-object:使用fsck进行对象检查

签署人:杰夫·金
c879daa("Make hash-object more robust against malformed objects",2011 - 02 - 05,Git v1.7.5-rc0--merge)开始,我们已经对将要编写的对象做了一些基本的检查,方法是通过我们常用的树、提交和标签解析器来运行它们。
这些解析器捕捉到一些问题,但是它们远不如fsck函数那样仔细(fsck函数有意义;解析器被设计为快速且宽容的,仅当输入不可理解时才保释)。
我们最好在写对象时进行更彻底的fsck检查。
在写的时候这样做要比写垃圾以后才发现fsck抱怨它,或者transfer.fsckObjects的主机拒绝它要好得多(在它上面构建了更多的历史之后!)。
这显然是一个用户可见的行为更改,本系列前面的测试更改显示了影响的范围。
但我认为这是可以的:

  • hash-object的文档已经模糊了我们可以做哪些检查,说--literally将允许任何垃圾[...],否则可能无法通过标准对象解析或git-fsckman)检查"。

所以我们已经被记录在案的行为所覆盖。

  • 用户通常不会运行hash-object。

测试中有很多地方需要更新,因为创建垃圾对象是Git测试不成比例的任务。

  • 很难想象会有人认为这种新行为更糟糕。

我们拒绝的任何对象都将是用户未来的潜在问题。
而且如果他们真的想制造垃圾,--literally已经是他们需要的逃生舱口了。
注意,这里的更改实际上是在index_mem()中,它处理hash-object传递的HASH_FORMAT_CHECK标志。
"git-replace --edit"(man)也使用该标志对结果进行健全性检查。
用更彻底的检查来覆盖这一点似乎也是一件好事。
除了更彻底之外,还有一些其他的好处:

  • 我们去掉了一些有问题的对象结构的堆栈分配。

目前看来,这些在实践中不会引起任何问题,但它们巧妙地违反了其余代码所做的一些假设(例如,我们放在堆栈上的"struct commit"和零初始化将没有来自alloc_comit_index()的正确索引。

  • 同样,这些已解析的对象结构也是一些小内存泄漏的来源
  • 得到的消息要好得多。

例如:

[before]
$ echo 'tree 123' | git hash-object -t commit --stdin
error: bogus commit object 0000000000000000000000000000000000000000
fatal: corrupt commit

[after]
$ echo 'tree 123' | git.compile hash-object -t commit --stdin
error: object fails fsck: badTreeSha1: invalid 'tree' line format - bad sha1
fatal: refusing to create malformed object
pengsaosao

pengsaosao2#

我修复这个“断开链接”错误的方法是这里列出的sehe的答案,它回答了一个关于如何修复一个无法找到〈insert sha1 code here〉错误的问题。
正如Adam所说,从另一个存储库/克隆中恢复对象。
1.在“完整”Git数据库上:

git cat-file -p a47058d09b4ca436d65609758a9dba52235a75bd > tempfile

1.以及在接收端:

git hash-object -w tempfile

一个重要的补充是,在步骤1和2之间,直接将文件从一个位置转移到另一个位置是很重要的。根据我的经验,使用Git push和pull来移动临时文件是行不通的。

bjp0bcyl

bjp0bcyl3#

git gc --aggressive将清除不必要的文件并优化本地存储库。
您可以使用以下命令验证问题是否已解决:

git fsck --full
fcwjkofz

fcwjkofz4#

我也有类似的问题broken link from tree,导致某些git命令出现错误fatal: bad tree object
但通过运行以下命令修复了该问题:

修复问题

  1. git stash clear([可选]只是删除可能由于重定基或其他原因而损坏的存储)
  2. git reflog expire --expire-unreachable=now --all(删除悬空提交)
  3. git gc --prune=now(类似地也删除提交)

检查是否已修复

  1. git fsck --full --name-objects(检查完整性,并且不应返回悬空提交或错误树)
    之后,错误消息fatal: bad tree object消失了!:tada:

相关问题