aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Annex/Content.hs16
-rw-r--r--CHANGELOG10
-rw-r--r--Command/LockContent.hs18
-rw-r--r--P2P/Protocol.hs4
-rw-r--r--Remote/Git.hs7
5 files changed, 29 insertions, 26 deletions
diff --git a/Annex/Content.hs b/Annex/Content.hs
index 768b2a9dc..6542804f7 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 38a947116..174e4a3e1 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 202ba20d1..1ed8cdf0b 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 a00d24416..81b2156cc 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 2cebcce4a..caa677464 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