summaryrefslogtreecommitdiff
path: root/Command/Watch.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-06-12 14:50:54 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-06-12 15:57:24 -0400
commit7d2c8133967d2f12cd18cf8f57e91a107e17bedb (patch)
tree14212326bc87d8f88dc4cc953e54dc36e3ae6781 /Command/Watch.hs
parent535d9e49984daa7669f8bbc6e83ef2f7989c21c9 (diff)
fix bug that turned files already in git into symlinks
This requires a relatively expensive test at file add time to see if it's in git already. But it can be optimised to only happen during the startup scan.
Diffstat (limited to 'Command/Watch.hs')
-rw-r--r--Command/Watch.hs29
1 files changed, 20 insertions, 9 deletions
diff --git a/Command/Watch.hs b/Command/Watch.hs
index 5564df7bc..1b728f254 100644
--- a/Command/Watch.hs
+++ b/Command/Watch.hs
@@ -48,6 +48,7 @@ import qualified Command.Add
import qualified Git.Command
import qualified Git.UpdateIndex
import qualified Git.HashObject
+import qualified Git.LsFiles
import qualified Backend
import Annex.Content
import Annex.CatFile
@@ -67,7 +68,7 @@ import System.INotify
type ChangeChan = TChan Change
-type Handler = FilePath -> Annex (Maybe Change)
+type Handler = FilePath -> Bool -> Annex (Maybe Change)
data Change = Change
{ changeTime :: UTCTime
@@ -173,9 +174,9 @@ runChangeChan = atomically
-
- Exceptions are ignored, otherwise a whole watcher thread could be crashed.
-}
-runHandler :: MVar Annex.AnnexState -> ChangeChan -> Handler -> FilePath -> IO ()
-runHandler st changechan handler file = void $ do
- r <- tryIO (runStateMVar st $ handler file)
+runHandler :: MVar Annex.AnnexState -> ChangeChan -> Handler -> FilePath -> Bool -> IO ()
+runHandler st changechan handler file inscan = void $ do
+ r <- tryIO (runStateMVar st $ handler file inscan)
case r of
Left e -> print e
Right Nothing -> noop
@@ -201,7 +202,7 @@ noChange = return Nothing
- or return a Change, leaving that to onAddSymlink.
-}
onAdd :: Handler
-onAdd file = do
+onAdd file False = do
showStart "add" file
handle =<< Command.Add.ingest file
noChange
@@ -210,13 +211,23 @@ onAdd file = do
handle (Just key) = do
Command.Add.link file key True
showEndOk
+{- During initial directory scan, this will be run for any files that
+ - are already checked into git. We don't want to turn those into symlinks,
+ - so do a check. This is rather expensive, but only happens during
+ - startup, and when a directory is moved into the tree. -}
+onAdd file True = do
+ liftIO $ putStrLn $ "expensive check for " ++ file
+ ifM (null <$> inRepo (Git.LsFiles.notInRepo False [file]))
+ ( noChange
+ , onAdd file False
+ )
{- A symlink might be an arbitrary symlink, which is just added.
- Or, if it is a git-annex symlink, ensure it points to the content
- before adding it.
-}
onAddSymlink :: Handler
-onAddSymlink file = go =<< Backend.lookupFile file
+onAddSymlink file _inscan = go =<< Backend.lookupFile file
where
go Nothing = addlink =<< liftIO (readSymbolicLink file)
go (Just (key, _)) = do
@@ -249,7 +260,7 @@ onAddSymlink file = go =<< Backend.lookupFile file
madeChange file "link"
onDel :: Handler
-onDel file = do
+onDel file _inscan = do
Annex.Queue.addUpdateIndex =<<
inRepo (Git.UpdateIndex.unstageFile file)
madeChange file "rm"
@@ -262,14 +273,14 @@ onDel file = do
- command to get the recursive list of files in the directory, so rm is
- just as good. -}
onDelDir :: Handler
-onDelDir dir = do
+onDelDir dir _inscan = do
Annex.Queue.addCommand "rm"
[Params "--quiet -r --cached --ignore-unmatch --"] [dir]
madeChange dir "rmdir"
{- Called when there's an error with inotify. -}
onErr :: Handler
-onErr msg = do
+onErr msg _inscan = do
warning msg
return Nothing