This commit is contained in:
Joey Hess 2016-10-17 14:58:33 -04:00
parent 93425dd575
commit 148bd0dbfd
No known key found for this signature in database
GPG key ID: C910D9222512E3C7
5 changed files with 52 additions and 35 deletions

View file

@ -31,6 +31,7 @@ import Annex.Version
import Annex.Difference import Annex.Difference
import Annex.UUID import Annex.UUID
import Annex.Link import Annex.Link
import Annex.WorkTree
import Config import Config
import Annex.Direct import Annex.Direct
import Annex.AdjustedBranch import Annex.AdjustedBranch
@ -39,7 +40,6 @@ import Annex.Hook
import Annex.InodeSentinal import Annex.InodeSentinal
import Upgrade import Upgrade
import Annex.Perms import Annex.Perms
import qualified Database.Keys
import Utility.UserInfo import Utility.UserInfo
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import Utility.FileMode import Utility.FileMode
@ -90,7 +90,7 @@ initialize' mversion = do
setVersion (fromMaybe defaultVersion mversion) setVersion (fromMaybe defaultVersion mversion)
whenM versionSupportsUnlockedPointers $ do whenM versionSupportsUnlockedPointers $ do
configureSmudgeFilter configureSmudgeFilter
Database.Keys.scanAssociatedFiles scanUnlockedFiles
v <- checkAdjustedClone v <- checkAdjustedClone
case v of case v of
NeedUpgradeForAdjustedClone -> NeedUpgradeForAdjustedClone ->

View file

@ -1,6 +1,6 @@
{- git-annex worktree files {- git-annex worktree files
- -
- Copyright 2013-2015 Joey Hess <id@joeyh.name> - Copyright 2013-2016 Joey Hess <id@joeyh.name>
- -
- Licensed under the GNU GPL version 3 or higher. - Licensed under the GNU GPL version 3 or higher.
-} -}
@ -12,6 +12,13 @@ import Annex.Link
import Annex.CatFile import Annex.CatFile
import Annex.Version import Annex.Version
import Config import Config
import qualified Git.Ref
import qualified Git.Branch
import qualified Git.LsTree
import qualified Git.Types
import Database.Types
import qualified Database.Keys
import qualified Database.Keys.SQL
{- Looks up the key corresponding to an annexed file in the work tree, {- Looks up the key corresponding to an annexed file in the work tree,
- by examining what the file links to. - by examining what the file links to.
@ -41,3 +48,30 @@ whenAnnexed a file = ifAnnexed file (a file) (return Nothing)
ifAnnexed :: FilePath -> (Key -> Annex a) -> Annex a -> Annex a ifAnnexed :: FilePath -> (Key -> Annex a) -> Annex a -> Annex a
ifAnnexed file yes no = maybe no yes =<< lookupFile file ifAnnexed file yes no = maybe no yes =<< lookupFile file
{- Find all unlocked files and update the keys database for them.
-
- This is expensive, and so normally the associated files are updated
- incrementally when changes are noticed. So, this only needs to be done
- when initializing/upgrading a v6 mode repository.
-}
scanUnlockedFiles :: Annex ()
scanUnlockedFiles = whenM (isJust <$> inRepo Git.Branch.current) $
Database.Keys.runWriter $ \h -> do
showSideAction "scanning for unlocked files"
liftIO $ Database.Keys.SQL.dropAllAssociatedFiles h
(l, cleanup) <- inRepo $ Git.LsTree.lsTree Git.Ref.headRef
forM_ l $ \i ->
when (isregfile i) $
maybe noop (add h i)
=<< catKey (Git.LsTree.sha i)
liftIO $ void cleanup
where
isregfile i = case Git.Types.toBlobType (Git.LsTree.mode i) of
Just Git.Types.FileBlob -> True
Just Git.Types.ExecutableBlob -> True
_ -> False
add h i k = liftIO $ Database.Keys.SQL.addAssociatedFileFast
(toIKey k)
(Git.LsTree.file i)
h

View file

@ -14,11 +14,11 @@ module Database.Keys (
getAssociatedFiles, getAssociatedFiles,
getAssociatedKey, getAssociatedKey,
removeAssociatedFile, removeAssociatedFile,
scanAssociatedFiles,
storeInodeCaches, storeInodeCaches,
addInodeCaches, addInodeCaches,
getInodeCaches, getInodeCaches,
removeInodeCaches, removeInodeCaches,
runWriter,
) where ) where
import qualified Database.Keys.SQL as SQL import qualified Database.Keys.SQL as SQL
@ -36,11 +36,7 @@ import Annex.InodeSentinal
import qualified Git.Types import qualified Git.Types
import qualified Git.LsTree import qualified Git.LsTree
import qualified Git.Branch import qualified Git.Branch
import Git.Ref
import Git.FilePath import Git.FilePath
import Annex.CatFile
import Database.Esqueleto hiding (Key)
{- Runs an action that reads from the database. {- Runs an action that reads from the database.
- -
@ -168,32 +164,6 @@ getAssociatedKey = map fromIKey <$$> runReaderIO . SQL.getAssociatedKey
removeAssociatedFile :: Key -> TopFilePath -> Annex () removeAssociatedFile :: Key -> TopFilePath -> Annex ()
removeAssociatedFile k = runWriterIO . SQL.removeAssociatedFile (toIKey k) removeAssociatedFile k = runWriterIO . SQL.removeAssociatedFile (toIKey k)
{- Find all unlocked associated files. This is expensive, and so normally
- the associated files are updated incrementally when changes are noticed. -}
scanAssociatedFiles :: Annex ()
scanAssociatedFiles = whenM (isJust <$> inRepo Git.Branch.current) $
runWriter $ \h -> do
showSideAction "scanning for unlocked files"
dropallassociated h
(l, cleanup) <- inRepo $ Git.LsTree.lsTree headRef
forM_ l $ \i ->
when (isregfile i) $
maybe noop (add h i)
=<< catKey (Git.LsTree.sha i)
liftIO $ void cleanup
where
dropallassociated h = liftIO $ flip SQL.queueDb h $
delete $ from $ \(_r :: SqlExpr (Entity SQL.Associated)) ->
return ()
isregfile i = case Git.Types.toBlobType (Git.LsTree.mode i) of
Just Git.Types.FileBlob -> True
Just Git.Types.ExecutableBlob -> True
_ -> False
add h i k = liftIO $ flip SQL.queueDb h $
void $ insertUnique $ SQL.Associated
(toIKey k)
(toSFilePath $ getTopFilePath $ Git.LsTree.file i)
{- Stats the files, and stores their InodeCaches. -} {- Stats the files, and stores their InodeCaches. -}
storeInodeCaches :: Key -> [FilePath] -> Annex () storeInodeCaches :: Key -> [FilePath] -> Annex ()
storeInodeCaches k fs = withTSDelta $ \d -> storeInodeCaches k fs = withTSDelta $ \d ->

View file

@ -68,6 +68,18 @@ addAssociatedFile ik f = queueDb $ do
where where
af = toSFilePath (getTopFilePath f) af = toSFilePath (getTopFilePath f)
-- Does not remove any old association for a file, but less expensive
-- than addAssociatedFile. Calling dropAllAssociatedFiles first and then
-- this is an efficient way to update all associated files.
addAssociatedFileFast :: IKey -> TopFilePath -> WriteHandle -> IO ()
addAssociatedFileFast ik f = queueDb $ void $ insertUnique $ Associated ik af
where
af = toSFilePath (getTopFilePath f)
dropAllAssociatedFiles :: WriteHandle -> IO ()
dropAllAssociatedFiles = queueDb $
delete $ from $ \(_r :: SqlExpr (Entity Associated)) -> return ()
{- Note that the files returned were once associated with the key, but {- Note that the files returned were once associated with the key, but
- some of them may not be any longer. -} - some of them may not be any longer. -}
getAssociatedFiles :: IKey -> ReadHandle -> IO [TopFilePath] getAssociatedFiles :: IKey -> ReadHandle -> IO [TopFilePath]

View file

@ -15,6 +15,7 @@ import Annex.Link
import Annex.Direct import Annex.Direct
import Annex.Content import Annex.Content
import Annex.CatFile import Annex.CatFile
import Annex.WorkTree
import qualified Database.Keys import qualified Database.Keys
import qualified Annex.Content.Direct as Direct import qualified Annex.Content.Direct as Direct
import qualified Git import qualified Git
@ -31,7 +32,7 @@ upgrade :: Bool -> Annex Bool
upgrade automatic = do upgrade automatic = do
unless automatic $ unless automatic $
showAction "v5 to v6" showAction "v5 to v6"
Database.Keys.scanAssociatedFiles scanUnlockedFiles
whenM isDirect $ do whenM isDirect $ do
{- Direct mode makes the same tradeoff of using less disk {- Direct mode makes the same tradeoff of using less disk
- space, with less preservation of old versions of files - space, with less preservation of old versions of files