fix git-annex repair false positive
Avoid treating refs/annex/last-index or other refs that are not commit objects as evidence of repository corruption. The repair code checks to find bad refs by trying to run `git log` on them, and assumes that no output means something is broken. But git log on a tree object is empty. This was worth fixing generally, not as a special case, since it's certainly possible that other things store tree or other objects in refs. Sponsored-by: Max Thoursie on Patreon
This commit is contained in:
parent
d0b1ecf464
commit
0406c33f58
4 changed files with 39 additions and 12 deletions
|
@ -14,6 +14,8 @@ git-annex (10.20220323) UNRELEASED; urgency=medium
|
||||||
* rsync 3.2.4 broke backwards-compatability by preventing exposing
|
* rsync 3.2.4 broke backwards-compatability by preventing exposing
|
||||||
filenames to the shell. Made the rsync and gcrypt special remotes
|
filenames to the shell. Made the rsync and gcrypt special remotes
|
||||||
detect this and disable shellescape. Closes: #1010397
|
detect this and disable shellescape. Closes: #1010397
|
||||||
|
* repair: Avoid treating refs/annex/last-index or other refs that
|
||||||
|
are not commit objects as evidence of repository corruption.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Mon, 28 Mar 2022 14:46:10 -0400
|
-- Joey Hess <id@joeyh.name> Mon, 28 Mar 2022 14:46:10 -0400
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,11 @@ findUncorruptedCommit missing goodcommits branch r = do
|
||||||
- the commit. Also adds to a set of commit shas that have been verified to
|
- the commit. Also adds to a set of commit shas that have been verified to
|
||||||
- be good, which can be passed into subsequent calls to avoid
|
- be good, which can be passed into subsequent calls to avoid
|
||||||
- redundant work when eg, chasing down branches to find the first
|
- redundant work when eg, chasing down branches to find the first
|
||||||
- uncorrupted commit. -}
|
- uncorrupted commit.
|
||||||
|
-
|
||||||
|
- When the sha is not a commit but some other git object, returns
|
||||||
|
- true, but does not add it to the set.
|
||||||
|
-}
|
||||||
verifyCommit :: MissingObjects -> GoodCommits -> Sha -> Repo -> IO (Bool, GoodCommits)
|
verifyCommit :: MissingObjects -> GoodCommits -> Sha -> Repo -> IO (Bool, GoodCommits)
|
||||||
verifyCommit missing goodcommits commit r
|
verifyCommit missing goodcommits commit r
|
||||||
| checkGoodCommit commit goodcommits = return (True, goodcommits)
|
| checkGoodCommit commit goodcommits = return (True, goodcommits)
|
||||||
|
@ -337,16 +341,23 @@ verifyCommit missing goodcommits commit r
|
||||||
, Param (fromRef commit)
|
, Param (fromRef commit)
|
||||||
] r
|
] r
|
||||||
let committrees = map (parse . decodeBL) ls
|
let committrees = map (parse . decodeBL) ls
|
||||||
if any isNothing committrees || null committrees
|
-- git log on an object that is not a commit will
|
||||||
then do
|
-- succeed without any output
|
||||||
void cleanup
|
if null committrees
|
||||||
return (False, goodcommits)
|
then ifM cleanup
|
||||||
else do
|
( return (True, goodcommits)
|
||||||
let cts = catMaybes committrees
|
, return (False, goodcommits)
|
||||||
ifM (cleanup <&&> check cts)
|
)
|
||||||
( return (True, addGoodCommits (map fst cts) goodcommits)
|
else if any isNothing committrees
|
||||||
, return (False, goodcommits)
|
then do
|
||||||
)
|
void cleanup
|
||||||
|
return (False, goodcommits)
|
||||||
|
else do
|
||||||
|
let cts = catMaybes committrees
|
||||||
|
ifM (cleanup <&&> check cts)
|
||||||
|
( return (True, addGoodCommits (map fst cts) goodcommits)
|
||||||
|
, return (False, goodcommits)
|
||||||
|
)
|
||||||
where
|
where
|
||||||
parse l = case words l of
|
parse l = case words l of
|
||||||
(commitsha:treesha:[]) -> (,)
|
(commitsha:treesha:[]) -> (,)
|
||||||
|
|
|
@ -45,4 +45,4 @@ The bug is very easy to reproduce. This happens in a bigger repository of mine,
|
||||||
|
|
||||||
Using it daily, with small-sized repositories.
|
Using it daily, with small-sized repositories.
|
||||||
|
|
||||||
|
> [[fixed|done]] --[[Joey]]
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
[[!comment format=mdwn
|
||||||
|
username="joey"
|
||||||
|
subject="""comment 3"""
|
||||||
|
date="2022-05-04T15:06:31Z"
|
||||||
|
content="""
|
||||||
|
Thank you, your "Reproducible Example" worked for me to reproduce it!
|
||||||
|
Great work finding this and tracking down an easy way to reproduce it.
|
||||||
|
|
||||||
|
So the root of the problem is refs/annex/last-index,
|
||||||
|
which contains a tree object, not a commit object. That is unusual for a ref,
|
||||||
|
but git-annex has a good reason to record a tree's ref there.
|
||||||
|
|
||||||
|
Fixed
|
||||||
|
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue