diff --git a/CHANGELOG b/CHANGELOG index 6f53e3e1ac..4178427d62 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,8 @@ git-annex (10.20220323) UNRELEASED; urgency=medium * rsync 3.2.4 broke backwards-compatability by preventing exposing filenames to the shell. Made the rsync and gcrypt special remotes 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 Mon, 28 Mar 2022 14:46:10 -0400 diff --git a/Git/Repair.hs b/Git/Repair.hs index 3e5c3fced0..7d47f84614 100644 --- a/Git/Repair.hs +++ b/Git/Repair.hs @@ -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:[]) -> (,) diff --git a/doc/bugs/git_annex_repair_failed__58___missing_objects.mdwn b/doc/bugs/git_annex_repair_failed__58___missing_objects.mdwn index ac11a3a2be..687a81e903 100644 --- a/doc/bugs/git_annex_repair_failed__58___missing_objects.mdwn +++ b/doc/bugs/git_annex_repair_failed__58___missing_objects.mdwn @@ -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. - +> [[fixed|done]] --[[Joey]] diff --git a/doc/bugs/git_annex_repair_failed__58___missing_objects/comment_3_317bee33fe675a5abb6fe65540a33d25._comment b/doc/bugs/git_annex_repair_failed__58___missing_objects/comment_3_317bee33fe675a5abb6fe65540a33d25._comment new file mode 100644 index 0000000000..3e971faa3b --- /dev/null +++ b/doc/bugs/git_annex_repair_failed__58___missing_objects/comment_3_317bee33fe675a5abb6fe65540a33d25._comment @@ -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 +"""]]