populate unlocked files with newly available content when ingesting

This can happen when ingesting a new file in either locked or unlocked
mode, when some unlocked files in the repo use the same key, and the
content was not locally available before.
This commit is contained in:
Joey Hess 2015-12-22 16:22:28 -04:00
parent 4f60234690
commit cfaac52b88
Failed to extract signature
3 changed files with 27 additions and 5 deletions

View file

@ -24,6 +24,7 @@ module Annex.Content (
withTmp, withTmp,
checkDiskSpace, checkDiskSpace,
moveAnnex, moveAnnex,
populatePointerFile,
linkAnnex, linkAnnex,
linkAnnex', linkAnnex',
LinkAnnexResult(..), LinkAnnexResult(..),

View file

@ -12,6 +12,7 @@ module Annex.Ingest (
lockDown, lockDown,
ingest, ingest,
finishIngestDirect, finishIngestDirect,
finishIngestUnlocked,
addLink, addLink,
makeLink, makeLink,
restoreFile, restoreFile,
@ -28,6 +29,7 @@ import Annex.Link
import Annex.MetaData import Annex.MetaData
import qualified Annex import qualified Annex
import qualified Annex.Queue import qualified Annex.Queue
import qualified Database.Keys
import Config import Config
import Utility.InodeCache import Utility.InodeCache
import Annex.ReplaceFile import Annex.ReplaceFile
@ -59,9 +61,8 @@ data LockedDown = LockedDown
- against some changes, like deletion or overwrite of the file, and - against some changes, like deletion or overwrite of the file, and
- allows lsof checks to be done more efficiently when adding a lot of files. - allows lsof checks to be done more efficiently when adding a lot of files.
- -
- If the file is to be locked, lockingfile is True. Then the write - If lockingfile is True, the file is going to be added in locked mode.
- bit is removed from the file as part of lock down to guard against - So, its write bit is removed as part of the lock down.
- further writes.
- -
- Lockdown can fail if a file gets deleted, and Nothing will be returned. - Lockdown can fail if a file gets deleted, and Nothing will be returned.
-} -}
@ -134,13 +135,20 @@ ingest (Just (LockedDown lockingfile source)) = withTSDelta $ \delta -> do
catchNonAsync (moveAnnex key $ contentLocation source) catchNonAsync (moveAnnex key $ contentLocation source)
(restoreFile (keyFilename source) key) (restoreFile (keyFilename source) key)
liftIO $ nukeFile $ keyFilename source liftIO $ nukeFile $ keyFilename source
populateAssociatedFiles key source
success key mcache s success key mcache s
gounlocked key (Just cache) s = do gounlocked key (Just cache) s = do
-- Remove temp directory hard link first because
-- linkAnnex falls back to copying if a file
-- already has a hard link.
cleanCruft source
r <- linkAnnex key (keyFilename source) (Just cache) r <- linkAnnex key (keyFilename source) (Just cache)
case r of case r of
LinkAnnexFailed -> failure "failed to link to annex" LinkAnnexFailed -> failure "failed to link to annex"
_ -> success key (Just cache) s _ -> do
finishIngestUnlocked key source
success key (Just cache) s
gounlocked _ _ _ = failure "failed statting file" gounlocked _ _ _ = failure "failed statting file"
godirect key (Just cache) s = do godirect key (Just cache) s = do
@ -168,6 +176,19 @@ finishIngestDirect key source = do
forM_ otherfs $ forM_ otherfs $
addContentWhenNotPresent key (keyFilename source) addContentWhenNotPresent key (keyFilename source)
finishIngestUnlocked :: Key -> KeySource -> Annex ()
finishIngestUnlocked key source = do
Database.Keys.addAssociatedFile key (keyFilename source)
populateAssociatedFiles key source
{- Copy to any other locations using the same key. -}
populateAssociatedFiles :: Key -> KeySource -> Annex ()
populateAssociatedFiles key source = do
otherfs <- filter (/= keyFilename source) <$> Database.Keys.getAssociatedFiles key
obj <- calcRepo (gitAnnexLocation key)
forM_ otherfs $
populatePointerFile key obj
cleanCruft :: KeySource -> Annex () cleanCruft :: KeySource -> Annex ()
cleanCruft source = when (contentLocation source /= keyFilename source) $ cleanCruft source = when (contentLocation source /= keyFilename source) $
liftIO $ nukeFile $ contentLocation source liftIO $ nukeFile $ contentLocation source

View file

@ -347,7 +347,7 @@ handleAdds havelsof delayadd cs = returnWhen (null incomplete) $ do
let source = keySource $ lockedDown change let source = keySource $ lockedDown change
liftAnnex $ if isdirect liftAnnex $ if isdirect
then finishIngestDirect key source then finishIngestDirect key source
else Database.Keys.addAssociatedFile key (keyFilename source) else finishIngestUnlocked key source
done change Nothing (keyFilename source) key done change Nothing (keyFilename source) key
removedKeysMap :: Bool -> InodeComparisonType -> [Change] -> Annex (M.Map InodeCacheKey Key) removedKeysMap :: Bool -> InodeComparisonType -> [Change] -> Annex (M.Map InodeCacheKey Key)