- prevent losing the content if the source file is deleted, but does not
- guard against modifications.
-}
-linkAnnex :: Key -> FilePath -> Annex LinkAnnexResult
-linkAnnex key src = do
+linkAnnex :: Key -> FilePath -> Maybe InodeCache -> Annex LinkAnnexResult
+linkAnnex key src srcic = do
dest <- calcRepo (gitAnnexLocation key)
- modifyContent dest $ linkAnnex' key src dest
+ modifyContent dest $ linkAnnex' key src srcic dest
{- Hard links (or copies) src to dest, one of which should be the
- annex object. Updates inode cache for src and for dest when it's
- changed. -}
-linkAnnex' :: Key -> FilePath -> FilePath -> Annex LinkAnnexResult
-linkAnnex' key src dest =
+linkAnnex' :: Key -> FilePath -> Maybe InodeCache -> FilePath -> Annex LinkAnnexResult
+linkAnnex' _ _ Nothing _ = return LinkAnnexFailed
+linkAnnex' key src (Just srcic) dest =
ifM (liftIO $ doesFileExist dest)
( do
- Database.Keys.storeInodeCaches key [src]
+ Database.Keys.addInodeCaches key [srcic]
return LinkAnnexNoop
, ifM (linkAnnex'' key src dest)
( do
thawContent dest
- Database.Keys.storeInodeCaches key [dest, src]
- return LinkAnnexOk
- , do
- Database.Keys.storeInodeCaches key [src]
- return LinkAnnexFailed
+ -- src could have changed while being copied
+ -- to dest
+ mcache <- withTSDelta (liftIO . genInodeCache src)
+ case mcache of
+ Just srcic' | compareStrong srcic srcic' -> do
+ destic <- withTSDelta (liftIO . genInodeCache dest)
+ Database.Keys.addInodeCaches key $
+ catMaybes [destic, Just srcic]
+ return LinkAnnexOk
+ _ -> do
+ liftIO $ nukeFile dest
+ failed
+ , failed
)
)
+ where
+ failed = do
+ Database.Keys.addInodeCaches key [srcic]
+ return LinkAnnexFailed
data LinkAnnexResult = LinkAnnexOk | LinkAnnexFailed | LinkAnnexNoop
import Annex.MetaData
import Annex.FileMatcher
import Annex.InodeSentinal
+import Utility.InodeCache
import Types.KeySource
import Backend
import Logs.Location
-- If the file being cleaned was hard linked to the old key's annex object,
-- modifying the file will have caused the object to have the wrong content.
--- Clean up from that, making the
+-- Clean up from that.
cleanOldKey :: FilePath -> Key -> Annex ()
cleanOldKey modifiedfile key = do
obj <- calcRepo (gitAnnexLocation key)
case fs' of
-- If linkAnnex fails, the file with the content
-- is still present, so no need for any recovery.
- (f:_) -> void $ linkAnnex key f
+ (f:_) -> do
+ ic <- withTSDelta (liftIO . genInodeCache f)
+ void $ linkAnnex key f ic
_ -> lostcontent
where
lostcontent = logStatus key InfoMissing
ingest :: FilePath -> Annex Key
ingest file = do
backend <- chooseBackend file
+ ic <- withTSDelta (liftIO . genInodeCache file)
let source = KeySource
{ keyFilename = file
, contentLocation = file
- , inodeCache = Nothing
+ , inodeCache = ic
}
k <- fst . fromMaybe (error "failed to generate a key")
<$> genKey source backend
-- Hard link (or copy) file content to annex object
-- to prevent it from being lost when git checks out
-- a branch not containing this file.
- r <- linkAnnex k file
+ r <- linkAnnex k file ic
case r of
LinkAnnexFailed -> error "Problem adding file to the annex"
LinkAnnexOk -> logStatus k InfoPresent
import Annex.Version
import Annex.Link
import Annex.ReplaceFile
+import Annex.InodeSentinal
+import Utility.InodeCache
import Utility.CopyFile
cmd :: Command
performNew :: FilePath -> Key -> CommandPerform
performNew dest key = do
src <- calcRepo (gitAnnexLocation key)
+ srcic <- withTSDelta (liftIO . genInodeCache src)
replaceFile dest $ \tmp -> do
- r <- linkAnnex' key src tmp
+ r <- linkAnnex' key src srcic tmp
case r of
LinkAnnexOk -> return ()
_ -> error "linkAnnex failed"
import qualified Git.LsFiles
import qualified Git.Branch
import Git.FileMode
+import Utility.InodeCache
upgrade :: Bool -> Annex Bool
upgrade automatic = do
-- not populated with it. Since the work tree file
-- is recorded as an associated file, things will still
-- work that way, it's just not ideal.
- void $ linkAnnex k f
+ ic <- withTSDelta (liftIO . genInodeCache f)
+ void $ linkAnnex k f ic
writepointer f k = liftIO $ do
nukeFile f
writeFile f (formatPointer k)