link/copy pointer files to object content when it's added
authorJoey Hess <joeyh@joeyh.name>
Wed, 9 Dec 2015 19:25:14 +0000 (15:25 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 9 Dec 2015 19:27:29 +0000 (15:27 -0400)
Annex/Content.hs
doc/todo/smudge.mdwn

index 73cb6ab012dc50745366691fd067bac5d621eb14..d3bf4f94fe7a75655f35b867eb3e68dc69e194e8 100644 (file)
@@ -72,6 +72,7 @@ import qualified Types.Backend
 import qualified Backend
 import Types.NumCopies
 import Annex.UUID
+import qualified Database.AssociatedFiles as AssociatedFiles
 
 {- Checks if a given key's content is currently present. -}
 inAnnex :: Key -> Annex Bool
@@ -414,7 +415,10 @@ checkDiskSpace destination key alreadythere samefilesystem = ifM (Annex.getState
 
 {- Moves a key's content into .git/annex/objects/
  -
- - In direct mode, moves it to the associated file, or files.
+ - When a key has associated pointer files, the object is hard
+ - linked (or copied) to the files, and the object file is left thawed.
+ - In direct mode, moves the object file to the associated file, or files.
  -
  - What if the key there already has content? This could happen for
  - various reasons; perhaps the same content is being annexed again.
@@ -442,7 +446,10 @@ moveAnnex key src = withObjectLoc key storeobject storedirect
                ( alreadyhave
                , modifyContent dest $ do
                        liftIO $ moveFile src dest
-                       freezeContent dest
+                       fs <- AssociatedFiles.getDb key
+                       if null fs
+                               then freezeContent dest
+                               else mapM_ (populateAssociatedFile key dest) fs
                )
        storeindirect = storeobject =<< calcRepo (gitAnnexLocation key)
 
@@ -472,6 +479,15 @@ moveAnnex key src = withObjectLoc key storeobject storedirect
        
        alreadyhave = liftIO $ removeFile src
 
+populateAssociatedFile :: Key -> FilePath -> FilePath -> Annex ()
+populateAssociatedFile k obj f = go =<< isPointerFile f
+  where
+       go (Just k') | k == k' = liftIO $ do
+               nukeFile f
+               unlessM (catchBoolIO $ createLinkOrCopy obj f) $
+                       writeFile f (formatPointer k)
+       go _ = return ()
+
 {- Hard links a file into .git/annex/objects/, falling back to a copy
  - if necessary.
  -
index 949de27daf3d9f0e379a04db3a91572aef21424b..373c655617268d21e2158df186937accef1dd340 100644 (file)
@@ -330,17 +330,14 @@ files to be unlocked, while the indirect upgrades don't touch the files.
   such objects. This parallels how inAnnex checks work for direct mode.
 * Reconcile staged changes into the associated files database, whenever
   the database is queried.
-* See if the case where this is not used can be optimised. Eg, if the
-  associated files database doesn't exist at all, we know smudge/clean are
-  not used, so queries for associated files don't need to open the database
-  or do reconciliation, but can simply return none.
+* See if the case where the associated files database is not used can be
+  optimised. Eg, if the associated files database doesn't exist at all,
+  we know smudge/clean are not used, so queries for associated files don't
+  need to open the database or do reconciliation, but can simply return none.
   Also, no need for Backend.lookupFile to catKeyFile in this case
   (when not in direct mode).
-* Update pointer files when adding the content of a key to the annex
-  (ie, `git annex get`).
-  - Check the associated files database to find associated files for the key.
-  - Check worktree file to ensure it's still a pointer to the key.
-  - Hard-link to annex object.
+  However, beware over-optimisation breaking the assistant or perhaps other
+  long-lived processes.
 * Update pointer files when dropping the content of a key.
   - Check the associated files database to find associated files for the key.
   - Verify that worktree files are not modified from the annexed object.