summaryrefslogtreecommitdiff
path: root/Annex
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2016-10-17 15:19:47 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2016-10-17 15:19:47 -0400
commitee7c5c8636e0478746b72e9900811b3a63c450cc (patch)
tree0fc96bf1d5e01584e9fede3ea44080d76cc3b205 /Annex
parent697bb401dbb2a9497e8e3cbc895052ad87a75c23 (diff)
upgrade: Handle upgrade to v6 when the repository already contains v6 unlocked files whose content is already present.
Closes https://github.com/datalad/datalad/issues/1020 The use of runWriter in scanUnlockedFiles broke due to this change; it failed with blocked indefinitely in mvar, because the database write handle was taken while linkFromAnnex needed to also write to it (to update the inode cache). So, switched to using a separate runWriter for each call to addAssociatedFileFast. A little less efficient, but not greatly; the writes should all still be cached.
Diffstat (limited to 'Annex')
-rw-r--r--Annex/WorkTree.hs44
1 files changed, 30 insertions, 14 deletions
diff --git a/Annex/WorkTree.hs b/Annex/WorkTree.hs
index fe42ab726..d62e15aee 100644
--- a/Annex/WorkTree.hs
+++ b/Annex/WorkTree.hs
@@ -11,7 +11,10 @@ import Annex.Common
import Annex.Link
import Annex.CatFile
import Annex.Version
+import Annex.Content
+import Annex.ReplaceFile
import Config
+import Git.FilePath
import qualified Git.Ref
import qualified Git.Branch
import qualified Git.LsTree
@@ -54,24 +57,37 @@ ifAnnexed file yes no = maybe no yes =<< lookupFile file
- This is expensive, and so normally the associated files are updated
- incrementally when changes are noticed. So, this only needs to be done
- when initializing/upgrading a v6 mode repository.
+ -
+ - Also, the content for the unlocked file may already be present as
+ - an annex object. If so, make the unlocked file use that content.
-}
scanUnlockedFiles :: Annex ()
-scanUnlockedFiles = whenM (isJust <$> inRepo Git.Branch.current) $
- Database.Keys.runWriter $ \h -> do
- showSideAction "scanning for unlocked files"
- liftIO $ Database.Keys.SQL.dropAllAssociatedFiles h
- (l, cleanup) <- inRepo $ Git.LsTree.lsTree Git.Ref.headRef
- forM_ l $ \i ->
- when (isregfile i) $
- maybe noop (add h i)
- =<< catKey (Git.LsTree.sha i)
- liftIO $ void cleanup
+scanUnlockedFiles = whenM (isJust <$> inRepo Git.Branch.current) $ do
+ showSideAction "scanning for unlocked files"
+ Database.Keys.runWriter $
+ liftIO . Database.Keys.SQL.dropAllAssociatedFiles
+ (l, cleanup) <- inRepo $ Git.LsTree.lsTree Git.Ref.headRef
+ forM_ l $ \i ->
+ when (isregfile i) $
+ maybe noop (add i)
+ =<< catKey (Git.LsTree.sha i)
+ liftIO $ void cleanup
where
isregfile i = case Git.Types.toBlobType (Git.LsTree.mode i) of
Just Git.Types.FileBlob -> True
Just Git.Types.ExecutableBlob -> True
_ -> False
- add h i k = liftIO $ Database.Keys.SQL.addAssociatedFileFast
- (toIKey k)
- (Git.LsTree.file i)
- h
+ add i k = do
+ let tf = Git.LsTree.file i
+ Database.Keys.runWriter $
+ liftIO . Database.Keys.SQL.addAssociatedFileFast (toIKey k) tf
+ whenM (inAnnex k) $ do
+ f <- fromRepo $ fromTopFilePath tf
+ destmode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus f
+ replaceFile f $ \tmp -> do
+ r <- linkFromAnnex k tmp destmode
+ case r of
+ LinkAnnexOk -> return ()
+ LinkAnnexNoop -> return ()
+ LinkAnnexFailed -> liftIO $
+ writePointerFile tmp k destmode