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:
Joey Hess 2022-05-04 11:32:23 -04:00
parent d0b1ecf464
commit 0406c33f58
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 39 additions and 12 deletions

View file

@ -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
- be good, which can be passed into subsequent calls to avoid
- 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 missing goodcommits commit r
| checkGoodCommit commit goodcommits = return (True, goodcommits)
@ -337,16 +341,23 @@ verifyCommit missing goodcommits commit r
, Param (fromRef commit)
] r
let committrees = map (parse . decodeBL) ls
if any isNothing committrees || null committrees
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)
)
-- git log on an object that is not a commit will
-- succeed without any output
if null committrees
then ifM cleanup
( return (True, goodcommits)
, return (False, goodcommits)
)
else if any isNothing committrees
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
parse l = case words l of
(commitsha:treesha:[]) -> (,)