Reputation: 3402
I was trying to merge my master
branch with another one called pull-stage
, but Git throws me this error:
error: inflate: data stream error (invalid distance too far back)
error: corrupt loose object '5a63450f4a0b72abbc1221ccb7d9f9bfef333250'
fatal: loose object 5a63450f4a0b72abbc1221ccb7d9f9bfef333250 (stored in .git/objects/5a/63450f4a0b72abbc1221ccb7d9f9bfef333250) is corrupt
How can I solve this issue?
I have reviewed other posts, but with no successful results:
Upvotes: 5
Views: 3930
Reputation: 1323145
As documented in your links, you need to get back the corrupted data from another source (for instance, by cloning first your repository locally and getting data from there).
But what to get back is now (Git 2.40, Q1 2023) more precise:
With Git 2.40 (Q1 2023), even in a repository with promisor remote, it is useless to attempt to lazily attempt fetching an object that is expected to be commit, because no "filter" mode omits commit objects.
Take advantage of this assumption to fail fast on errors.
See commit 7e2ad1c, commit 9e59b38, commit ae285ac, commit acd6f0d (14 Dec 2022) by Jonathan Tan (jhowtan
).
(Merged by Junio C Hamano -- gitster
-- in commit 1f9b02b, 05 Jan 2023)
object-file
: emit corruption errors when detectedHelped-by: Jeff King
Signed-off-by: Jonathan Tan
Instead of relying on errno being preserved across function calls, teach
do_oid_object_info_extended()
to itself report object corruption when it first detects it.
There are 3 types of corruption being detected:
- when a replacement object is missing
- when a loose object is corrupt
- when a packed object is corrupt and the object cannot be read in another way
Note that in the RHS of this patch's diff, a check for ENOENT that was introduced in 3ba7a06 ("A loose object is not corrupt if it cannot be read due to EMFILE", 2010-10-28, Git v1.7.4-rc0 -- merge) is also removed.
The purpose of this check is to avoid a false report of corruption if the errno contains something like EMFILE (or anything that is not ENOENT), in which case a more generic report is presented.
Because, as of this patch, we no longer rely on such a heuristic to determine corruption, but surface the error message at the point when we read something that we did not expect, this check is no longer necessary.Besides being more resilient, this also prepares for a future patch in which an indirect caller of
do_oid_object_info_extended()
will need such functionality.
So you will get:
unable to open loose object <sha1>
loose object <sha1> (stored in </path/to/object>) is corrupt
replacement <sha1> not found for <sha1>
packed object <sha1> (stored in <pack_name>) is corrupt
Therefore:
commit
: don't lazy-fetch commitsSigned-off-by: Jonathan Tan
When parsing commits, fail fast when the commit is missing or corrupt, instead of attempting to fetch them.
This is done by inliningrepo_read_object_file()
and setting the flag that prevents fetching.This is motivated by a situation in which through a bug (not necessarily through Git), there was corruption in the object store of a partial clone.
In this particular case, the problem was exposed when "git gc
"(man) tried to expire reflogs, which callsrepo_parse_commit()
, which triggers fetches of the missing commits.(There are other possible solutions to this problem including passing an argument from "
git gc
" togit reflog
(man) to inhibit all lazy fetches, but I think that this fix is at the wrong level - fixing "git reflog
" means that this particular command works fine, or so we think (it will fail if it somehow needs to read a legitimately missing blob, say, a.gitmodules
file), but fixingrepo_parse_commit()
will fix a whole class of bugs.)
Upvotes: 0
Reputation: 741
I had the same error recently, after a crash of the virtualbox guest I was running git in. I did the following, and it fixed my specific issue. Please backup your tree before attempting this.
delete the loose object rm .git/object/5a/63450f4a0b72abbc1221ccb7d9f9bfef333250
edit logs/refs/head/, and find the commit id before the last one.
edit refs/head/, and use the old commit id
this should allow you to get back to standard git operation (but the last commit will be lost).
Upvotes: 1