assistant: Notice on startup when the index file is corrupt, and auto-repair.

This commit is contained in:
Joey Hess 2013-11-13 14:27:17 -04:00
parent 5e7e0c7dc0
commit 13108b7196
5 changed files with 39 additions and 12 deletions

View file

@ -25,8 +25,10 @@ import Utility.Batch
import Utility.NotificationBroadcaster
import Config
import Utility.HumanTime
import Git.Repair
import Data.Time.Clock.POSIX
import qualified Data.Set as S
{- This thread runs once at startup, and most other threads wait for it
- to finish. (However, the webapp thread does not, to prevent the UI
@ -36,6 +38,16 @@ sanityCheckerStartupThread startupdelay = namedThreadUnchecked "SanityCheckerSta
{- Stale git locks can prevent commits from happening, etc. -}
void $ repairStaleGitLocks =<< liftAnnex gitRepo
{- A corrupt index file can prevent the assistant from working at
- all, so detect and repair. -}
unlessM (liftAnnex $ inRepo $ checkIndex S.empty) $ do
debug ["corrupt index found at startup; removing"]
liftAnnex $ inRepo nukeIndex
{- Normally the startup scan avoids re-staging files,
- but with the index deleted, everything needs to be
- restaged. -}
modifyDaemonStatus_ $ \s -> s { forceRestage = True }
{- If there's a startup delay, it's done here. -}
liftIO $ maybe noop (threadDelaySeconds . Seconds . fromIntegral . durationSeconds) startupdelay

View file

@ -200,6 +200,9 @@ onAdd matcher file filestatus
add matcher file
| otherwise = noChange
shouldRestage :: DaemonStatus -> Bool
shouldRestage ds = scanComplete ds || forceRestage ds
{- In direct mode, add events are received for both new files, and
- modified existing files.
-}
@ -214,7 +217,7 @@ onAddDirect symlinkssupported matcher file fs = do
- really modified, but it might have
- just been deleted and been put back,
- so it symlink is restaged to make sure. -}
( ifM (scanComplete <$> getDaemonStatus)
( ifM (shouldRestage <$> getDaemonStatus)
( do
link <- liftAnnex $ inRepo $ gitAnnexLink file key
addLink file link (Just key)
@ -286,7 +289,7 @@ onAddSymlink' linktarget mk isdirect file filestatus = go mk
- links too.)
-}
ensurestaged (Just link) daemonstatus
| scanComplete daemonstatus = addLink file link mk
| shouldRestage daemonstatus = addLink file link mk
| otherwise = case filestatus of
Just s
| not (afterLastDaemonRun (statusChangeTime s) daemonstatus) -> noChange

View file

@ -28,6 +28,8 @@ data DaemonStatus = DaemonStatus
{ startedThreads :: M.Map ThreadName (Async (), IO ())
-- False when the daemon is performing its startup scan
, scanComplete :: Bool
-- True when all files should be restaged.
, forceRestage :: Bool
-- Time when a previous process of the daemon was running ok
, lastRunning :: Maybe POSIXTime
-- True when the daily sanity checker is running
@ -81,6 +83,7 @@ newDaemonStatus :: IO DaemonStatus
newDaemonStatus = DaemonStatus
<$> pure M.empty
<*> pure False
<*> pure False
<*> pure Nothing
<*> pure False
<*> pure Nothing

View file

@ -13,6 +13,7 @@ module Git.Repair (
resetLocalBranches,
removeTrackingBranches,
checkIndex,
nukeIndex,
emptyGoodCommits,
) where
@ -368,15 +369,18 @@ verifyTree missing treesha r
else cleanup
{- Checks that the index file only refers to objects that are not missing,
- and is not itself corrupt. -}
- and is not itself corrupt or missing. -}
checkIndex :: MissingObjects -> Repo -> IO Bool
checkIndex missing r = do
checkIndex missing r = ifM (doesFileExist (localGitDir r </> "index"))
( do
(bad, _good, cleanup) <- partitionIndex missing r
if null bad
then cleanup
else do
void cleanup
return False
, return False
)
partitionIndex :: MissingObjects -> Repo -> IO ([LsFiles.StagedDetails], [LsFiles.StagedDetails], IO Bool)
partitionIndex missing r = do
@ -396,7 +400,7 @@ rewriteIndex missing r
| otherwise = do
(bad, good, cleanup) <- partitionIndex missing r
unless (null bad) $ do
nukeFile (localGitDir r </> "index")
nukeIndex r
UpdateIndex.streamUpdateIndex r
=<< (catMaybes <$> mapM reinject good)
void cleanup
@ -408,6 +412,9 @@ rewriteIndex missing r
UpdateIndex.stageFile sha blobtype file r
reinject _ = return Nothing
nukeIndex :: Repo -> IO ()
nukeIndex r = nukeFile (localGitDir r </> "index")
newtype GoodCommits = GoodCommits (S.Set Sha)
emptyGoodCommits :: GoodCommits
@ -502,7 +509,7 @@ runRepairOf fsckresult forced referencerepo g = do
return (True, stillmissing, modifiedbranches)
corruptedindex = do
nukeFile (localGitDir g </> "index")
nukeIndex g
putStrLn "Removed the corrupted index file. You should look at what files are present in your working tree and git add them back to the index when appropriate."
return (True, S.empty, [])

2
debian/changelog vendored
View file

@ -27,6 +27,8 @@ git-annex (5.20131102) UNRELEASED; urgency=low
* Work around Android linker problem that had prevented git-annex from
running on Android 4.3 and 4.4.
* repair: Handle case where index file is corrupt, but all objects are ok.
* assistant: Notice on startup when the index file is corrupt, and
auto-repair.
-- Joey Hess <joeyh@debian.org> Wed, 06 Nov 2013 16:14:14 -0400