From 957dffd030816a067fa6ee3c93f63311ad1f009c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 12 Mar 2013 16:41:54 -0400 Subject: Bugfix: Fix bug in inode cache sentinal check, which broke copying to local repos if the repo being copied from had moved to a different filesystem or otherwise changed all its inodes' --- Annex.hs | 11 +++++++++++ Annex/Content.hs | 5 +++++ Annex/Content/Direct.hs | 10 ++++++++-- Remote/Git.hs | 6 +++++- debian/changelog | 3 +++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Annex.hs b/Annex.hs index 2a17fffe1..117bd2862 100644 --- a/Annex.hs +++ b/Annex.hs @@ -31,6 +31,7 @@ module Annex ( getGitConfig, changeGitConfig, changeGitRepo, + withCurrentState, ) where import "mtl" Control.Monad.State.Strict @@ -216,3 +217,13 @@ changeGitRepo r = changeState $ \s -> s { repo = r , gitconfig = extractGitConfig r } + +{- Converts an Annex action into an IO action, that runs with a copy + - of the current Annex state. + - + - Use with caution; the action should not rely on changing the + - state, as it will be thrown away. -} +withCurrentState :: Annex a -> Annex (IO a) +withCurrentState a = do + s <- getState id + return $ eval s a diff --git a/Annex/Content.hs b/Annex/Content.hs index 0439cb367..673e59b10 100644 --- a/Annex/Content.hs +++ b/Annex/Content.hs @@ -276,6 +276,10 @@ replaceFile file a = do - In direct mode, it's possible for the file to change as it's being sent. - If this happens, runs the rollback action and returns False. The - rollback action should remove the data that was transferred. + - + - Note that the returned action is, in some cases, run in the Annex monad + - of the remote that is receiving the object, rather than the sender. + - So it cannot rely on Annex state, particular -} sendAnnex :: Key -> Annex () -> (FilePath -> Annex Bool) -> Annex Bool sendAnnex key rollback sendobject = go =<< prepSendAnnex key @@ -303,6 +307,7 @@ prepSendAnnex key = withObjectLoc key indirect direct direct [] = return Nothing direct (f:fs) = do cache <- recordedInodeCache key + liftIO $ print ("prepSendAnnex pre cache", cache) -- check that we have a good file ifM (sameInodeCache f cache) ( return $ Just (f, sameInodeCache f cache) diff --git a/Annex/Content/Direct.hs b/Annex/Content/Direct.hs index bbf6e310d..523e15f18 100644 --- a/Annex/Content/Direct.hs +++ b/Annex/Content/Direct.hs @@ -150,8 +150,12 @@ compareInodeCaches :: InodeCache -> InodeCache -> Annex Bool compareInodeCaches x y | compareStrong x y = return True | otherwise = ifM inodesChanged - ( return $ compareWeak x y - , return False + ( do + liftIO $ print ("compareInodeCaches weak") + return $ compareWeak x y + , do + liftIO $ print ("compareInodeCaches no inode change but cache not match") + return False ) compareInodeCachesWith :: Annex InodeComparisonType @@ -171,9 +175,11 @@ inodesChanged = maybe calc return =<< Annex.getState Annex.inodeschanged scache <- liftIO . genInodeCache =<< fromRepo gitAnnexInodeSentinal scached <- readInodeSentinalFile + liftIO $ print (scache, scached) let changed = case (scache, scached) of (Just c1, Just c2) -> not $ compareStrong c1 c2 _ -> True + liftIO $ print changed Annex.changeState $ \s -> s { Annex.inodeschanged = Just changed } return changed diff --git a/Remote/Git.hs b/Remote/Git.hs index 0d7d2a988..0de453522 100644 --- a/Remote/Git.hs +++ b/Remote/Git.hs @@ -351,6 +351,10 @@ copyToRemote r key file p where copylocal Nothing = return False copylocal (Just (object, checksuccess)) = do + -- The checksuccess action is going to be run in + -- the remote's Annex, but it needs access to the current + -- Annex monad's state. + checksuccessio <- Annex.withCurrentState checksuccess let params = rsyncParams r u <- getUUID -- run copy from perspective of remote @@ -360,7 +364,7 @@ copyToRemote r key file p ensureInitialized download u key file noRetry $ Annex.Content.saveState True `after` - Annex.Content.getViaTmpChecked checksuccess key + Annex.Content.getViaTmpChecked (liftIO checksuccessio) key (\d -> rsyncOrCopyFile params object d p) ) diff --git a/debian/changelog b/debian/changelog index 77e64bc4d..73f5905c0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,9 @@ git-annex (4.20130228) UNRELEASED; urgency=low * Bugfix: If the UUID of a remote is not known, prevent --from, --to, and other ways of specifying remotes by name from selecting it, since it is not possible to sanely use it. + * Bugfix: Fix bug in inode cache sentinal check, which broke + copying to local repos if the repo being copied from had moved + to a different filesystem or otherwise changed all its inodes' * Switch from using regex-compat to regex-tdfa, as the C regex library is rather buggy. -- cgit v1.2.3