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

View file

@ -1,6 +1,6 @@
{- 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.
-}
@ -12,6 +12,13 @@ import Annex.Link
import Annex.CatFile
import Annex.Version
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,
- 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 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,
getAssociatedKey,
removeAssociatedFile,
scanAssociatedFiles,
storeInodeCaches,
addInodeCaches,
getInodeCaches,
removeInodeCaches,
runWriter,
) where
import qualified Database.Keys.SQL as SQL
@ -36,11 +36,7 @@ import Annex.InodeSentinal
import qualified Git.Types
import qualified Git.LsTree
import qualified Git.Branch
import Git.Ref
import Git.FilePath
import Annex.CatFile
import Database.Esqueleto hiding (Key)
{- Runs an action that reads from the database.
-
@ -168,32 +164,6 @@ getAssociatedKey = map fromIKey <$$> runReaderIO . SQL.getAssociatedKey
removeAssociatedFile :: Key -> TopFilePath -> Annex ()
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. -}
storeInodeCaches :: Key -> [FilePath] -> Annex ()
storeInodeCaches k fs = withTSDelta $ \d ->

View file

@ -68,6 +68,18 @@ addAssociatedFile ik f = queueDb $ do
where
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
- some of them may not be any longer. -}
getAssociatedFiles :: IKey -> ReadHandle -> IO [TopFilePath]

View file

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