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 | |
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.
-rw-r--r-- | Annex/WorkTree.hs | 44 | ||||
-rw-r--r-- | CHANGELOG | 2 | ||||
-rw-r--r-- | Command/Unlock.hs | 2 | ||||
-rw-r--r-- | doc/bugs/remote_repository_must_be_version_6_as_well_to_have_copied_files_appear_correctly.mdwn | 11 |
4 files changed, 43 insertions, 16 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 @@ -2,6 +2,8 @@ git-annex (6.20161013) UNRELEASED; urgency=medium * lock, smudge: Fix edge cases where data loss could occur in v6 mode when the keys database was not populated. + * upgrade: Handle upgrade to v6 when the repository already contains + v6 unlocked files whose content is already present. -- Joey Hess <id@joeyh.name> Mon, 17 Oct 2016 12:46:54 -0400 diff --git a/Command/Unlock.hs b/Command/Unlock.hs index dfd8350f1..0ac221c1f 100644 --- a/Command/Unlock.hs +++ b/Command/Unlock.hs @@ -56,7 +56,7 @@ performNew dest key = do case r of LinkAnnexOk -> return () LinkAnnexNoop -> return () - _ -> error "unlock failed" + LinkAnnexFailed -> error "unlock failed" , liftIO $ writePointerFile tmp key destmode ) next $ cleanupNew dest key destmode diff --git a/doc/bugs/remote_repository_must_be_version_6_as_well_to_have_copied_files_appear_correctly.mdwn b/doc/bugs/remote_repository_must_be_version_6_as_well_to_have_copied_files_appear_correctly.mdwn index 08df3b13c..57a174455 100644 --- a/doc/bugs/remote_repository_must_be_version_6_as_well_to_have_copied_files_appear_correctly.mdwn +++ b/doc/bugs/remote_repository_must_be_version_6_as_well_to_have_copied_files_appear_correctly.mdwn @@ -35,4 +35,13 @@ $> ./v6-push.sh 6 2>&1 | grep '>>>' > > I am not sure yet why the keys database lacked an entry for the file; > perhaps something to do with it being a v6 unlocked file in a v5 -> repository. --[[Joey]] +> repository. +> +> Ok.. Seems that cloning to a v5 repository, and then copying/getting +> objects into it, and then upgrading to v6 reproduces the problem with the +> keys database. The inode cache does not get populated for unlocked files +> on upgrade. Also, unlocked files stay as pointer files even when their +> content is present in annex/objects. Fixed the upgrade process to handle +> this case. +> +> [[fixed|done]]] --[[Joey]] |