diff options
-rw-r--r-- | Annex/Content/Direct.hs | 59 | ||||
-rw-r--r-- | Assistant/Threads/Committer.hs | 2 | ||||
-rw-r--r-- | Command/Add.hs | 10 | ||||
-rw-r--r-- | Init.hs | 2 | ||||
-rw-r--r-- | debian/changelog | 1 |
5 files changed, 50 insertions, 24 deletions
diff --git a/Annex/Content/Direct.hs b/Annex/Content/Direct.hs index 1ae127ef6..deca13d65 100644 --- a/Annex/Content/Direct.hs +++ b/Annex/Content/Direct.hs @@ -17,6 +17,8 @@ module Annex.Content.Direct ( sameInodeCache, removeInodeCache, toInodeCache, + inodesChanged, + createInodeSentinalFile, ) where import Common.Annex @@ -146,26 +148,45 @@ sameInodeCache file (Just old) = go =<< liftIO (genInodeCache file) {- Some filesystems get new inodes each time they are mounted. - In order to work on such a filesystem, a sentinal file is used to detect - - when the inodes have changed. -} + - when the inodes have changed. + - + - If the sentinal file does not exist, we have to assume that the + - inodes have changed. + -} inodesChanged :: Annex Bool inodesChanged = maybe calc return =<< Annex.getState Annex.inodeschanged where calc = do - sentinalfile <- fromRepo gitAnnexInodeSentinal - sentinalcachefile <- fromRepo gitAnnexInodeSentinalCache - scache <- liftIO $ genInodeCache sentinalfile - scached <- liftIO $ catchMaybeIO $ readInodeCache <$> readFile sentinalcachefile - case (scache, scached) of - (Just c1, Just (Just c2)) -> changed $ c1 /= c2 - _ -> do - writesentinal - changed True - changed v = do - Annex.changeState $ \s -> s { Annex.inodeschanged = Just v } - return v - writesentinal = do - sentinalfile <- fromRepo gitAnnexInodeSentinal - sentinalcachefile <- fromRepo gitAnnexInodeSentinalCache - liftIO $ writeFile sentinalfile "" - liftIO $ maybe noop (writeFile sentinalcachefile . showInodeCache) - =<< genInodeCache sentinalfile + scache <- liftIO . genInodeCache + =<< fromRepo gitAnnexInodeSentinal + scached <- readInodeSentinalFile + let changed = case (scache, scached) of + (Just c1, Just c2) -> c1 /= c2 + _ -> True + Annex.changeState $ \s -> s { Annex.inodeschanged = Just changed } + return changed + +readInodeSentinalFile :: Annex (Maybe InodeCache) +readInodeSentinalFile = do + sentinalcachefile <- fromRepo gitAnnexInodeSentinalCache + liftIO $ catchDefaultIO Nothing $ + readInodeCache <$> readFile sentinalcachefile + +writeInodeSentinalFile :: Annex () +writeInodeSentinalFile = do + sentinalfile <- fromRepo gitAnnexInodeSentinal + sentinalcachefile <- fromRepo gitAnnexInodeSentinalCache + liftIO $ writeFile sentinalfile "" + liftIO $ maybe noop (writeFile sentinalcachefile . showInodeCache) + =<< genInodeCache sentinalfile + +{- The sentinal file is only created when first initializing a repository. + - If there are any annexed objects in the repository already, creating + - the file would invalidate their inode caches. -} +createInodeSentinalFile :: Annex () +createInodeSentinalFile = + unlessM (alreadyexists <||> hasobjects) + writeInodeSentinalFile + where + alreadyexists = isJust <$> readInodeSentinalFile + hasobjects = liftIO . doesDirectoryExist =<< fromRepo gitAnnexObjectDir diff --git a/Assistant/Threads/Committer.hs b/Assistant/Threads/Committer.hs index b40b8ad28..585dfde9b 100644 --- a/Assistant/Threads/Committer.hs +++ b/Assistant/Threads/Committer.hs @@ -247,9 +247,7 @@ safeToAdd delayadd pending inprocess = do let inprocess' = inprocess ++ catMaybes (map mkinprocess $ zip pending keysources) openfiles <- S.fromList . map fst3 . filter openwrite <$> findopenfiles (map keySource inprocess') - liftIO $ print openfiles let checked = map (check openfiles) inprocess' - liftIO $ print checked {- If new events are received when files are closed, - there's no need to retry any changes that cannot diff --git a/Command/Add.hs b/Command/Add.hs index 7ebf979cd..33adc8efc 100644 --- a/Command/Add.hs +++ b/Command/Add.hs @@ -35,14 +35,14 @@ def = [notBareRepo $ command "add" paramPaths seek "add files to annex"] seek :: [CommandSeek] seek = [ withFilesNotInGit start - , whenNotDirect $ withFilesUnlocked start + , withFilesUnlocked start ] {- The add subcommand annexes a file, generating a key for it using a - backend, and then moving it into the annex directory and setting up - the symlink pointing to its content. -} start :: FilePath -> CommandStart -start file = ifAnnexed file fixup add +start file = ifAnnexed file addpresent add where add = do s <- liftIO $ getSymbolicLinkStatus file @@ -51,7 +51,11 @@ start file = ifAnnexed file fixup add else do showStart "add" file next $ perform file - fixup (key, _) = do + addpresent (key, _) = ifM isDirect + ( ifM (goodContent key file) ( stop , add ) + , fixup key + ) + fixup key = do -- fixup from an interrupted add; the symlink -- is present but not yet added to git showStart "add" file @@ -27,6 +27,7 @@ import Utility.Shell import Utility.FileMode import Config import Annex.Direct +import Annex.Content.Direct import Backend genDescription :: Maybe String -> Annex String @@ -45,6 +46,7 @@ initialize mdescription = do Annex.Branch.create setVersion gitPreCommitHookWrite + createInodeSentinalFile u <- getUUID describeUUID u =<< genDescription mdescription diff --git a/debian/changelog b/debian/changelog index b4bc100f5..e4cdc4d98 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,7 @@ git-annex (3.20130217) UNRELEASED; urgency=low * Android: Support ssh connection caching. * Direct mode: Support filesystems like FAT which can change their inodes each time they are mounted. + * Direct mode: Fix support for adding a modified file. -- Joey Hess <joeyh@debian.org> Sun, 17 Feb 2013 16:42:16 -0400 |