diff options
-rw-r--r-- | Annex/Content/Direct.hs | 1 | ||||
-rw-r--r-- | Assistant/Drop.hs | 49 | ||||
-rw-r--r-- | Utility/Monad.hs | 4 | ||||
-rw-r--r-- | debian/changelog | 6 | ||||
-rw-r--r-- | doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn | 8 |
5 files changed, 47 insertions, 21 deletions
diff --git a/Annex/Content/Direct.hs b/Annex/Content/Direct.hs index b9c78f8c0..e061f8e57 100644 --- a/Annex/Content/Direct.hs +++ b/Annex/Content/Direct.hs @@ -7,6 +7,7 @@ module Annex.Content.Direct ( associatedFiles, + associatedFilesRelative, removeAssociatedFile, removeAssociatedFileUnchecked, addAssociatedFile, diff --git a/Assistant/Drop.hs b/Assistant/Drop.hs index 1d22da466..4e81c284a 100644 --- a/Assistant/Drop.hs +++ b/Assistant/Drop.hs @@ -18,6 +18,7 @@ import Command import Annex.Wanted import Annex.Exception import Config +import Annex.Content.Direct import qualified Data.Set as S @@ -35,20 +36,26 @@ handleDrops reason fromhere key f knownpresentremote = do {- The UUIDs are ones where the content is believed to be present. - The Remote list can include other remotes that do not have the content; - only ones that match the UUIDs will be dropped from. - - If allows to drop fromhere, that drop will be tried first. -} + - If allowed to drop fromhere, that drop will be tried first. + - + - In direct mode, all associated files are checked, and only if all + - of them are unwanted are they dropped. + -} handleDropsFrom :: [UUID] -> [Remote] -> Reason -> Bool -> Key -> AssociatedFile -> Maybe Remote -> Assistant () handleDropsFrom _ _ _ _ _ Nothing _ = noop -handleDropsFrom locs rs reason fromhere key (Just f) knownpresentremote - | fromhere = do - n <- getcopies - if checkcopies n Nothing - then go rs =<< dropl n - else go rs n - | otherwise = go rs =<< getcopies +handleDropsFrom locs rs reason fromhere key (Just afile) knownpresentremote = do + fs <- liftAnnex $ ifM isDirect + ( associatedFilesRelative key + , return [afile] + ) + n <- getcopies fs + if fromhere && checkcopies n Nothing + then go fs rs =<< dropl fs n + else go fs rs n where - getcopies = liftAnnex $ do + getcopies fs = liftAnnex $ do (untrusted, have) <- trustPartition UnTrusted locs - numcopies <- getNumCopies =<< numCopies f + numcopies <- maximum <$> mapM (getNumCopies <=< numCopies) fs return (length have, numcopies, S.fromList untrusted) {- Check that we have enough copies still to drop the content. @@ -66,20 +73,20 @@ handleDropsFrom locs rs reason fromhere key (Just f) knownpresentremote | S.member u untrusted = v | otherwise = decrcopies v Nothing - go [] _ = noop - go (r:rest) n - | uuid r `S.notMember` slocs = go rest n + go _ [] _ = noop + go fs (r:rest) n + | uuid r `S.notMember` slocs = go fs rest n | checkcopies n (Just $ Remote.uuid r) = - dropr r n >>= go rest + dropr fs r n >>= go fs rest | otherwise = noop - checkdrop n@(have, numcopies, _untrusted) u a = - ifM (liftAnnex $ wantDrop True u (Just f)) + checkdrop fs n@(have, numcopies, _untrusted) u a = + ifM (liftAnnex $ allM (wantDrop True u . Just) fs) ( ifM (liftAnnex $ safely $ doCommand $ a (Just numcopies)) ( do debug [ "dropped" - , f + , afile , "(from " ++ maybe "here" show u ++ ")" , "(copies now " ++ show (have - 1) ++ ")" , ": " ++ reason @@ -90,11 +97,11 @@ handleDropsFrom locs rs reason fromhere key (Just f) knownpresentremote , return n ) - dropl n = checkdrop n Nothing $ \numcopies -> - Command.Drop.startLocal f numcopies key knownpresentremote + dropl fs n = checkdrop fs n Nothing $ \numcopies -> + Command.Drop.startLocal afile numcopies key knownpresentremote - dropr r n = checkdrop n (Just $ Remote.uuid r) $ \numcopies -> - Command.Drop.startRemote f numcopies key r + dropr fs r n = checkdrop fs n (Just $ Remote.uuid r) $ \numcopies -> + Command.Drop.startRemote afile numcopies key r safely a = either (const False) id <$> tryAnnex a diff --git a/Utility/Monad.hs b/Utility/Monad.hs index 4c3c30473..b66419f76 100644 --- a/Utility/Monad.hs +++ b/Utility/Monad.hs @@ -27,6 +27,10 @@ getM p (x:xs) = maybe (getM p xs) (return . Just) =<< p x anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool anyM p = liftM isJust . firstM p +allM :: Monad m => (a -> m Bool) -> [a] -> m Bool +allM _ [] = return True +allM p (x:xs) = p x <&&> allM p xs + {- Runs an action on values from a list until it succeeds. -} untilTrue :: Monad m => [a] -> (a -> m Bool) -> m Bool untilTrue = flip anyM diff --git a/debian/changelog b/debian/changelog index 4cf933cad..a649c0ea9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -21,6 +21,12 @@ git-annex (4.20130602) UNRELEASED; urgency=low * Android: Fix use of cp command to not try to use features present only on build system. * Windows: Fix hang when adding several files at once. + * assistant: In direct mode, objects are now only dropped when all + associated files are unwanted. This avoids a repreated drop/get loop + of a file that has a copy in an archive directory, and a copy not in an + archive directory. (Indirect mode still has some buggy behavior in this + area, since it does not keep track of associated files.) + Closes: #712060 -- Joey Hess <joeyh@debian.org> Mon, 10 Jun 2013 12:52:44 -0400 diff --git a/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn b/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn index effd2faf5..aaeace66f 100644 --- a/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn +++ b/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn @@ -7,3 +7,11 @@ Karsten [[!tag /design/assistant]] [[!meta title="assistant preferred content handling of files inside and outside archive directory at the same time"]] + +> Update: Current status is this is fixed for direct mode. +> +> In indirect mode, the startup scan will still download and then drop +> content if a file outside and inside the archive directory has the +> same content. It doesn't loop like it did in direct mode, only +> happens once (or once per duplicate file, really). Is still potentially +> annoying and a bug. --[[Joey]] |