summaryrefslogtreecommitdiff
path: root/Assistant/Threads
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-04-02 12:45:26 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-04-02 12:45:31 -0400
commit0af77809e07891bfec17813e4a3f4285f7cb17a4 (patch)
treeab3f738d8ceca1d33a420bf217244f328267ca93 /Assistant/Threads
parent973e1ad6bc463cad961373ed71351d3ccfede3fe (diff)
assistant: Fix bug that could cause direct mode files to be unstaged from git.
My test case for this bug is to have the assistant running and syncing to a remote, and create a file in the annex. Then at the command line run git annex drop. The assistant sees that the file is gone, sees it's a wanted file, and downloads it from the remote. With a directory special remote and a small file, I was seeing around 1 time in 3, a race where the file got unstaged from git after it got downloaded. Looking at what direct mode content managing code does in this case, it deletes the symlink, and then adds the file content back. It would be possible, sometimes, to avoid removing the symlink and do this atomically. And I probably should.. but in some cases, particularly where the file needs to be run through `cp` (multiple direct mode files with same content), there's no way to atomically replace the symlink with the content. Anyway, the bug turns out to be something that the watcher does right for indirect mode, but not for direct mode. When it got an add event, it checked to see if this was a new file, or one we've already added. In the latter case, no add event was queued. But that means that only the rm event is queued, and so it unstages the file. Fixed by queueing an add event even when the file is already in git. Tested by running hundreds of drops in a loop; file remained staged.
Diffstat (limited to 'Assistant/Threads')
-rw-r--r--Assistant/Threads/Watcher.hs9
1 files changed, 6 insertions, 3 deletions
diff --git a/Assistant/Threads/Watcher.hs b/Assistant/Threads/Watcher.hs
index c2ba90ebe..89cef6ea7 100644
--- a/Assistant/Threads/Watcher.hs
+++ b/Assistant/Threads/Watcher.hs
@@ -184,8 +184,11 @@ onAdd matcher file filestatus
| otherwise = noChange
{- In direct mode, add events are received for both new files, and
- - modified existing files. Or, in some cases, existing files that have not
- - really been modified. -}
+ - modified existing files.
+ -
+ - It's possible to get an add event for an existing file that is not
+ - really modified, but it might have just been deleted and been put back,
+ - so it's restaged to make sure. -}
onAddDirect :: FileMatcher -> Handler
onAddDirect matcher file fs = do
debug ["add direct", file]
@@ -193,7 +196,7 @@ onAddDirect matcher file fs = do
case (v, fs) of
(Just key, Just filestatus) ->
ifM (liftAnnex $ sameFileStatus key filestatus)
- ( noChange
+ ( add matcher file
, do
liftAnnex $ changedDirect key file
add matcher file