populate unlocked files with newly available content when ingesting
authorJoey Hess <joeyh@joeyh.name>
Tue, 22 Dec 2015 20:22:28 +0000 (16:22 -0400)
committerJoey Hess <joeyh@joeyh.name>
Tue, 22 Dec 2015 20:22:28 +0000 (16:22 -0400)
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.

Annex/Content.hs
Annex/Ingest.hs
Assistant/Threads/Committer.hs

index c00863e31029559624a5a687736c921c6bd7f007..e501df072a8dafed7f68bee66927d8d7f924e8ad 100644 (file)
@@ -24,6 +24,7 @@ module Annex.Content (
        withTmp,
        checkDiskSpace,
        moveAnnex,
+       populatePointerFile,
        linkAnnex,
        linkAnnex',
        LinkAnnexResult(..),
index 707f71eff3b6d5006d8c109fbce207d919fbceb4..7f38e9beb7b267419c1b62701aa7cc6a7cf7654f 100644 (file)
@@ -12,6 +12,7 @@ module Annex.Ingest (
        lockDown,
        ingest,
        finishIngestDirect,
+       finishIngestUnlocked,
        addLink,
        makeLink,
        restoreFile,
@@ -28,6 +29,7 @@ import Annex.Link
 import Annex.MetaData
 import qualified Annex
 import qualified Annex.Queue
+import qualified Database.Keys
 import Config
 import Utility.InodeCache
 import Annex.ReplaceFile
@@ -59,9 +61,8 @@ data LockedDown = LockedDown
  - 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.
  -
- - If the file is to be locked, lockingfile is True. Then the write
- - bit is removed from the file as part of lock down to guard against
- - further writes.
+ - If lockingfile is True, the file is going to be added in locked mode.
+ - So, its write bit is removed as part of the lock down.
  -
  - 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)
                        (restoreFile (keyFilename source) key)
                liftIO $ nukeFile $ keyFilename source
+               populateAssociatedFiles key source
                success key mcache s
 
        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)
                case r of
                        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"
 
        godirect key (Just cache) s = do
@@ -168,6 +176,19 @@ finishIngestDirect key source = do
        forM_ otherfs $
                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 source = when (contentLocation source /= keyFilename source) $
        liftIO $ nukeFile $ contentLocation source
index 3e00011f5a288af360bca0051fa9a582e5ca574d..c7633d590cf6e68d670c922d2dd00ef3ded2a1c3 100644 (file)
@@ -347,7 +347,7 @@ handleAdds havelsof delayadd cs = returnWhen (null incomplete) $ do
                let source = keySource $ lockedDown change
                liftAnnex $ if isdirect
                        then finishIngestDirect key source
-                       else Database.Keys.addAssociatedFile key (keyFilename source)
+                       else finishIngestUnlocked key source
                done change Nothing (keyFilename source) key
 
        removedKeysMap :: Bool -> InodeComparisonType -> [Change] -> Annex (M.Map InodeCacheKey Key)