summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-03-12 16:41:54 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-03-12 16:41:54 -0400
commit957dffd030816a067fa6ee3c93f63311ad1f009c (patch)
tree38770fb328269f1ebc45a26fc7a3f3bf88199ae6
parent79a3398d4cb3837d51d4431a2bb29a7a70a8f335 (diff)
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'
-rw-r--r--Annex.hs11
-rw-r--r--Annex/Content.hs5
-rw-r--r--Annex/Content/Direct.hs10
-rw-r--r--Remote/Git.hs6
-rw-r--r--debian/changelog3
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.