fsck: Now works in bare repositories.
Checks location log information, and file contents. Does not check that numcopies is satisfied, as .gitattributes information about numcopies is not available in a bare repository. In practice, that should not be a problem, since fsck is also run in a checkout and will check numcopies there.
This commit is contained in:
parent
fef2cf7398
commit
2566eb85fe
7 changed files with 77 additions and 31 deletions
25
Command.hs
25
Command.hs
|
@ -81,18 +81,6 @@ doCommand = start
|
||||||
success = return True
|
success = return True
|
||||||
failure = showEndFail >> return False
|
failure = showEndFail >> return False
|
||||||
|
|
||||||
notAnnexed :: FilePath -> Annex (Maybe a) -> Annex (Maybe a)
|
|
||||||
notAnnexed file a = maybe a (const $ return Nothing) =<< Backend.lookupFile file
|
|
||||||
|
|
||||||
isAnnexed :: FilePath -> ((Key, Backend Annex) -> Annex (Maybe a)) -> Annex (Maybe a)
|
|
||||||
isAnnexed file a = maybe (return Nothing) a =<< Backend.lookupFile file
|
|
||||||
|
|
||||||
notBareRepo :: Annex a -> Annex a
|
|
||||||
notBareRepo a = do
|
|
||||||
whenM (Git.repoIsLocalBare <$> gitRepo) $
|
|
||||||
error "You cannot run this subcommand in a bare repository."
|
|
||||||
a
|
|
||||||
|
|
||||||
{- These functions find appropriate files or other things based on a
|
{- These functions find appropriate files or other things based on a
|
||||||
user's parameters, and prepare actions operating on them. -}
|
user's parameters, and prepare actions operating on them. -}
|
||||||
withFilesInGit :: (FilePath -> CommandStart) -> CommandSeek
|
withFilesInGit :: (FilePath -> CommandStart) -> CommandSeek
|
||||||
|
@ -168,7 +156,18 @@ runFilteredGen a d fs = do
|
||||||
ok <- matcher f
|
ok <- matcher f
|
||||||
if ok then a v else stop
|
if ok then a v else stop
|
||||||
|
|
||||||
{- filter out symlinks -}
|
notAnnexed :: FilePath -> Annex (Maybe a) -> Annex (Maybe a)
|
||||||
|
notAnnexed file a = maybe a (const $ return Nothing) =<< Backend.lookupFile file
|
||||||
|
|
||||||
|
isAnnexed :: FilePath -> ((Key, Backend Annex) -> Annex (Maybe a)) -> Annex (Maybe a)
|
||||||
|
isAnnexed file a = maybe (return Nothing) a =<< Backend.lookupFile file
|
||||||
|
|
||||||
|
notBareRepo :: Annex a -> Annex a
|
||||||
|
notBareRepo a = do
|
||||||
|
whenM (Git.repoIsLocalBare <$> gitRepo) $
|
||||||
|
error "You cannot run this subcommand in a bare repository."
|
||||||
|
a
|
||||||
|
|
||||||
notSymlink :: FilePath -> IO Bool
|
notSymlink :: FilePath -> IO Bool
|
||||||
notSymlink f = liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f
|
notSymlink f = liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- git-annex command
|
{- git-annex command
|
||||||
-
|
-
|
||||||
- Copyright 2010,2011 Joey Hess <joey@kitenet.net>
|
- Copyright 2010-2011 Joey Hess <joey@kitenet.net>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -12,6 +12,8 @@ import Command
|
||||||
import qualified Remote
|
import qualified Remote
|
||||||
import qualified Types.Backend
|
import qualified Types.Backend
|
||||||
import qualified Types.Key
|
import qualified Types.Key
|
||||||
|
import qualified Backend
|
||||||
|
import qualified Git
|
||||||
import Annex.Content
|
import Annex.Content
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
import Logs.Trust
|
import Logs.Trust
|
||||||
|
@ -24,30 +26,61 @@ def :: [Command]
|
||||||
def = [command "fsck" paramPaths seek "check for problems"]
|
def = [command "fsck" paramPaths seek "check for problems"]
|
||||||
|
|
||||||
seek :: [CommandSeek]
|
seek :: [CommandSeek]
|
||||||
seek = [withNumCopies start]
|
seek = [withNumCopies start, withBarePresentKeys startBare]
|
||||||
|
|
||||||
start :: FilePath -> Maybe Int -> CommandStart
|
start :: FilePath -> Maybe Int -> CommandStart
|
||||||
start file numcopies = notBareRepo $ isAnnexed file $ \(key, backend) -> do
|
start file numcopies = isAnnexed file $ \(key, backend) -> do
|
||||||
showStart "fsck" file
|
showStart "fsck" file
|
||||||
next $ perform key file backend numcopies
|
next $ perform key file backend numcopies
|
||||||
|
|
||||||
perform :: Key -> FilePath -> Backend Annex -> Maybe Int -> CommandPerform
|
perform :: Key -> FilePath -> Backend Annex -> Maybe Int -> CommandPerform
|
||||||
perform key file backend numcopies = check =<< sequence
|
perform key file backend numcopies = check
|
||||||
-- order matters
|
-- order matters
|
||||||
[ verifyLocationLog key file
|
[ verifyLocationLog key file
|
||||||
, checkKeySize key
|
, checkKeySize key
|
||||||
, checkKeyNumCopies key file numcopies
|
, checkKeyNumCopies key file numcopies
|
||||||
, (Types.Backend.fsckKey backend) key
|
, (Types.Backend.fsckKey backend) key
|
||||||
]
|
]
|
||||||
|
|
||||||
|
{- To fsck a bare repository, fsck each key in the location log. -}
|
||||||
|
withBarePresentKeys :: (Key -> CommandStart) -> CommandSeek
|
||||||
|
withBarePresentKeys a params = do
|
||||||
|
bare <- Git.repoIsLocalBare <$> gitRepo
|
||||||
|
if bare
|
||||||
|
then do
|
||||||
|
unless (null params) $ do
|
||||||
|
error "fsck should be run without parameters in a bare repository"
|
||||||
|
liftM (map a) loggedKeys
|
||||||
|
else return []
|
||||||
|
|
||||||
|
startBare :: Key -> CommandStart
|
||||||
|
startBare key = case Backend.maybeLookupBackendName (Types.Key.keyBackendName key) of
|
||||||
|
Nothing -> stop
|
||||||
|
Just backend -> do
|
||||||
|
showStart "fsck" (show key)
|
||||||
|
next $ performBare key backend
|
||||||
|
|
||||||
|
{- Note that numcopies cannot be checked in a bare repository, because
|
||||||
|
- getting the numcopies value requires a working copy with .gitattributes
|
||||||
|
- files. -}
|
||||||
|
performBare :: Key -> Backend Annex -> CommandPerform
|
||||||
|
performBare key backend = check
|
||||||
|
[ verifyLocationLog key (show key)
|
||||||
|
, checkKeySize key
|
||||||
|
, (Types.Backend.fsckKey backend) key
|
||||||
|
]
|
||||||
|
|
||||||
|
check :: [Annex Bool] -> CommandPerform
|
||||||
|
check s = sequence s >>= dispatch
|
||||||
where
|
where
|
||||||
check vs
|
dispatch vs
|
||||||
| all (== True) vs = next $ return True
|
| all (== True) vs = next $ return True
|
||||||
| otherwise = stop
|
| otherwise = stop
|
||||||
|
|
||||||
{- Checks that the location log reflects the current status of the key,
|
{- Checks that the location log reflects the current status of the key,
|
||||||
in this repository only. -}
|
in this repository only. -}
|
||||||
verifyLocationLog :: Key -> FilePath -> Annex Bool
|
verifyLocationLog :: Key -> String -> Annex Bool
|
||||||
verifyLocationLog key file = do
|
verifyLocationLog key desc = do
|
||||||
g <- gitRepo
|
g <- gitRepo
|
||||||
present <- inAnnex key
|
present <- inAnnex key
|
||||||
|
|
||||||
|
@ -69,7 +102,7 @@ verifyLocationLog key file = do
|
||||||
(False, True) -> do
|
(False, True) -> do
|
||||||
fix g u InfoMissing
|
fix g u InfoMissing
|
||||||
warning $
|
warning $
|
||||||
"** Based on the location log, " ++ file
|
"** Based on the location log, " ++ desc
|
||||||
++ "\n** was expected to be present, " ++
|
++ "\n** was expected to be present, " ++
|
||||||
"but its content is missing."
|
"but its content is missing."
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -67,19 +67,11 @@ checkRemoteUnused name = do
|
||||||
checkRemoteUnused' :: Remote.Remote Annex -> Annex ()
|
checkRemoteUnused' :: Remote.Remote Annex -> Annex ()
|
||||||
checkRemoteUnused' r = do
|
checkRemoteUnused' r = do
|
||||||
showAction "checking for unused data"
|
showAction "checking for unused data"
|
||||||
remotehas <- filterM isthere =<< loggedKeys
|
remotehas <- loggedKeysFor (Remote.uuid r)
|
||||||
remoteunused <- excludeReferenced remotehas
|
remoteunused <- excludeReferenced remotehas
|
||||||
let list = number 0 remoteunused
|
let list = number 0 remoteunused
|
||||||
writeUnusedFile "" list
|
writeUnusedFile "" list
|
||||||
unless (null remoteunused) $ showLongNote $ remoteUnusedMsg r list
|
unless (null remoteunused) $ showLongNote $ remoteUnusedMsg r list
|
||||||
where
|
|
||||||
{- This should run strictly to avoid the filterM
|
|
||||||
- building many thunks containing keyLocations data. -}
|
|
||||||
isthere k = do
|
|
||||||
us <- keyLocations k
|
|
||||||
let !there = uuid `elem` us
|
|
||||||
return there
|
|
||||||
uuid = Remote.uuid r
|
|
||||||
|
|
||||||
writeUnusedFile :: FilePath -> [(Int, Key)] -> Annex ()
|
writeUnusedFile :: FilePath -> [(Int, Key)] -> Annex ()
|
||||||
writeUnusedFile prefix l = do
|
writeUnusedFile prefix l = do
|
||||||
|
|
|
@ -17,6 +17,7 @@ module Logs.Location (
|
||||||
readLog,
|
readLog,
|
||||||
keyLocations,
|
keyLocations,
|
||||||
loggedKeys,
|
loggedKeys,
|
||||||
|
loggedKeysFor,
|
||||||
logFile,
|
logFile,
|
||||||
logFileKey
|
logFileKey
|
||||||
) where
|
) where
|
||||||
|
@ -44,6 +45,18 @@ keyLocations = currentLog . logFile
|
||||||
loggedKeys :: Annex [Key]
|
loggedKeys :: Annex [Key]
|
||||||
loggedKeys = mapMaybe (logFileKey . takeFileName) <$> Annex.Branch.files
|
loggedKeys = mapMaybe (logFileKey . takeFileName) <$> Annex.Branch.files
|
||||||
|
|
||||||
|
{- Finds all keys that have location log information indicating
|
||||||
|
- they are present for the specified repository. -}
|
||||||
|
loggedKeysFor :: UUID -> Annex [Key]
|
||||||
|
loggedKeysFor u = filterM isthere =<< loggedKeys
|
||||||
|
where
|
||||||
|
{- This should run strictly to avoid the filterM
|
||||||
|
- building many thunks containing keyLocations data. -}
|
||||||
|
isthere k = do
|
||||||
|
us <- keyLocations k
|
||||||
|
let !there = u `elem` us
|
||||||
|
return there
|
||||||
|
|
||||||
{- The filename of the log file for a given key. -}
|
{- The filename of the log file for a given key. -}
|
||||||
logFile :: Key -> String
|
logFile :: Key -> String
|
||||||
logFile key = hashDirLower key ++ keyFile key ++ ".log"
|
logFile key = hashDirLower key ++ keyFile key ++ ".log"
|
||||||
|
|
4
debian/changelog
vendored
4
debian/changelog
vendored
|
@ -8,6 +8,10 @@ git-annex (3.20111026) UNRELEASED; urgency=low
|
||||||
* drop --from is now supported to remove file content from a remote.
|
* drop --from is now supported to remove file content from a remote.
|
||||||
* status: Now always shows the current repository, even when it does not
|
* status: Now always shows the current repository, even when it does not
|
||||||
appear in uuid.log.
|
appear in uuid.log.
|
||||||
|
* fsck: Now works in bare repositories. Checks location log information,
|
||||||
|
and file contents. Does not check that numcopies is satisfied, as
|
||||||
|
.gitattributes information about numcopies is not available in a bare
|
||||||
|
repository.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Thu, 27 Oct 2011 13:58:53 -0400
|
-- Joey Hess <joeyh@debian.org> Thu, 27 Oct 2011 13:58:53 -0400
|
||||||
|
|
||||||
|
|
|
@ -17,3 +17,5 @@ See http://lists.madduck.net/pipermail/vcs-home/2011-June/000433.html
|
||||||
>>> While storing the data is no longer an issue in bare repos, fsck would
|
>>> While storing the data is no longer an issue in bare repos, fsck would
|
||||||
>>> need a special mode that examines all the location logs, since it
|
>>> need a special mode that examines all the location logs, since it
|
||||||
>>> cannot run thru the checked out files. --[[Joey]]
|
>>> cannot run thru the checked out files. --[[Joey]]
|
||||||
|
|
||||||
|
>>>> [[done]]! --[[Joey]]
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
What is says on the tin:
|
What is says on the tin:
|
||||||
|
|
||||||
|
|
||||||
22:56:54 < RichiH> joeyh_: by the way, i have been thinking about fsck on bare repos
|
22:56:54 < RichiH> joeyh_: by the way, i have been thinking about fsck on bare repos
|
||||||
22:57:37 < RichiH> joeyh_: the best i could come with is to have a bare and a non-bare access the same repo store
|
22:57:37 < RichiH> joeyh_: the best i could come with is to have a bare and a non-bare access the same repo store
|
||||||
22:58:00 < RichiH> joeyh_: alternatively, with the SHA* backend, you have all the information to verify that the local data is correct
|
22:58:00 < RichiH> joeyh_: alternatively, with the SHA* backend, you have all the information to verify that the local data is correct
|
||||||
|
@ -10,3 +9,7 @@ What is says on the tin:
|
||||||
23:14:51 < joeyh_> unused/dropunused could work in bare repos too btw
|
23:14:51 < joeyh_> unused/dropunused could work in bare repos too btw
|
||||||
|
|
||||||
> Also `status`'s total annex keys/size could be handled for bare repos. --[[Joey]]
|
> Also `status`'s total annex keys/size could be handled for bare repos. --[[Joey]]
|
||||||
|
|
||||||
|
>> Fsck is done. Rest not done yet. --[[Joey]]
|
||||||
|
|
||||||
|
[[!meta title="support status, unused, dropunused in bare repos"]]
|
||||||
|
|
Loading…
Reference in a new issue