import Annex.Difference
import Annex.UUID
import Annex.Link
+import Annex.WorkTree
import Config
import Annex.Direct
import Annex.AdjustedBranch
import Annex.InodeSentinal
import Upgrade
import Annex.Perms
-import qualified Database.Keys
import Utility.UserInfo
#ifndef mingw32_HOST_OS
import Utility.FileMode
setVersion (fromMaybe defaultVersion mversion)
whenM versionSupportsUnlockedPointers $ do
configureSmudgeFilter
- Database.Keys.scanAssociatedFiles
+ scanUnlockedFiles
v <- checkAdjustedClone
case v of
NeedUpgradeForAdjustedClone ->
{- 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.
-}
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.
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
getAssociatedFiles,
getAssociatedKey,
removeAssociatedFile,
- scanAssociatedFiles,
storeInodeCaches,
addInodeCaches,
getInodeCaches,
removeInodeCaches,
+ runWriter,
) where
import qualified Database.Keys.SQL as SQL
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.
-
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 ->
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]
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
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