diff options
author | Joey Hess <joeyh@joeyh.name> | 2016-10-17 15:19:47 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2016-10-17 15:19:47 -0400 |
commit | ee7c5c8636e0478746b72e9900811b3a63c450cc (patch) | |
tree | 0fc96bf1d5e01584e9fede3ea44080d76cc3b205 /Annex | |
parent | 697bb401dbb2a9497e8e3cbc895052ad87a75c23 (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.hs | 44 |
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 |