diff --git a/Annex/Content.hs b/Annex/Content.hs index 768b2a9dc3..6542804f73 100644 --- a/Annex/Content.hs +++ b/Annex/Content.hs @@ -196,19 +196,19 @@ contentLockFile key = Just <$> calcRepo (gitAnnexContentLock key) {- Prevents the content from being removed while the action is running. - Uses a shared lock. - - - Does not actually check if the content is present. Use inAnnex for that. - - However, since the contentLockFile is the content file in indirect mode, - - if the content is not present, locking it will fail. - - - - If locking fails, throws an exception rather than running the action. + - If locking fails, or the content is not present, throws an exception + - rather than running the action. - - Note that, in direct mode, nothing prevents the user from directly - editing or removing the content, even while it's locked by this. -} lockContentShared :: Key -> (VerifiedCopy -> Annex a) -> Annex a -lockContentShared key a = lockContentUsing lock key $ do - u <- getUUID - withVerifiedCopy LockedCopy u (return True) a +lockContentShared key a = lockContentUsing lock key $ ifM (inAnnex key) + ( do + u <- getUUID + withVerifiedCopy LockedCopy u (return True) a + , giveup $ "failed to lock content: not present" + ) where #ifndef mingw32_HOST_OS lock contentfile Nothing = tryLockShared Nothing contentfile diff --git a/CHANGELOG b/CHANGELOG index 38a947116d..174e4a3e1b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,16 @@ git-annex (6.20180228) UNRELEASED; urgency=medium * Improve SHA*E extension extraction code to not treat parts of the filename that contain punctuation or other non-alphanumeric characters as extensions. Before, such characters were filtered out. + * Fix data loss bug when the local repository uses direct mode, and a + locally modified file is dropped from a remote repsitory. The bug + caused the modified file to be counted as a copy of the original file. + (This is not a severe bug because in such a situation, dropping + from the remote and then modifying the file is allowed and has the same + end result.) + * Fix bug in content locking over tor, when the remote repository is + in direct mode, it neglected to check that the content was actually + present when locking it. This could cause git annex drop to remove + the only copy of a file when it thought the tor remote had a copy. -- Joey Hess <id@joeyh.name> Wed, 28 Feb 2018 11:53:03 -0400 diff --git a/Command/LockContent.hs b/Command/LockContent.hs index 202ba20d1c..1ed8cdf0b2 100644 --- a/Command/LockContent.hs +++ b/Command/LockContent.hs @@ -22,9 +22,8 @@ cmd = noCommit $ seek :: CmdParams -> CommandSeek seek = withWords start --- First, lock the content. Then, make sure the content is actually --- present, and print out "OK". Wait for the caller to send a line before --- dropping the lock. +-- First, lock the content, then print out "OK". +-- Wait for the caller to send a line before dropping the lock. start :: [String] -> CommandStart start [ks] = do ok <- lockContentShared k (const locksuccess) @@ -34,12 +33,9 @@ start [ks] = do else exitFailure where k = fromMaybe (giveup "bad key") (file2key ks) - locksuccess = ifM (inAnnex k) - ( liftIO $ do - putStrLn contentLockedMarker - hFlush stdout - _ <- getProtocolLine stdin - return True - , return False - ) + locksuccess = liftIO $ do + putStrLn contentLockedMarker + hFlush stdout + _ <- getProtocolLine stdin + return True start _ = giveup "Specify exactly 1 key." diff --git a/P2P/Protocol.hs b/P2P/Protocol.hs index a00d24416f..81b2156cc2 100644 --- a/P2P/Protocol.hs +++ b/P2P/Protocol.hs @@ -233,8 +233,8 @@ data LocalF c | TryLockContent Key (Bool -> Proto ()) c -- ^ Try to lock the content of a key, preventing it -- from being deleted, while running the provided protocol - -- action. If unable to lock the content, runs the protocol action - -- with False. + -- action. If unable to lock the content, or the content is not + -- present, runs the protocol action with False. | WaitRefChange (ChangedRefs -> c) -- ^ Waits for one or more git refs to change and returns them. deriving (Functor) diff --git a/Remote/Git.hs b/Remote/Git.hs index 2cebcce4a8..caa6774648 100644 --- a/Remote/Git.hs +++ b/Remote/Git.hs @@ -391,11 +391,8 @@ lockKey r duc key callback -- and then run the callback in the original -- annex monad, not the remote's. onLocalFast r $ - Annex.Content.lockContentShared key $ \vc -> - ifM (Annex.Content.inAnnex key) - ( liftIO $ inorigrepo $ callback vc - , failedlock - ) + Annex.Content.lockContentShared key $ + liftIO . inorigrepo . callback , failedlock ) | Git.repoIsSsh (repo r) = do