assistant: Notice on startup when the index file is corrupt, and auto-repair.
This commit is contained in:
parent
5e7e0c7dc0
commit
13108b7196
5 changed files with 39 additions and 12 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
2
debian/changelog
vendored
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue