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'

This commit is contained in:
Joey Hess 2013-03-12 16:41:54 -04:00
parent e63a983cf1
commit f7de51e8b6
5 changed files with 32 additions and 3 deletions

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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)
)

3
debian/changelog vendored
View file

@ -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.