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.
This commit is contained in:
parent
535d9e4998
commit
7d2c813396
2 changed files with 22 additions and 9 deletions
|
@ -48,6 +48,7 @@ import qualified Command.Add
|
||||||
import qualified Git.Command
|
import qualified Git.Command
|
||||||
import qualified Git.UpdateIndex
|
import qualified Git.UpdateIndex
|
||||||
import qualified Git.HashObject
|
import qualified Git.HashObject
|
||||||
|
import qualified Git.LsFiles
|
||||||
import qualified Backend
|
import qualified Backend
|
||||||
import Annex.Content
|
import Annex.Content
|
||||||
import Annex.CatFile
|
import Annex.CatFile
|
||||||
|
@ -67,7 +68,7 @@ import System.INotify
|
||||||
|
|
||||||
type ChangeChan = TChan Change
|
type ChangeChan = TChan Change
|
||||||
|
|
||||||
type Handler = FilePath -> Annex (Maybe Change)
|
type Handler = FilePath -> Bool -> Annex (Maybe Change)
|
||||||
|
|
||||||
data Change = Change
|
data Change = Change
|
||||||
{ changeTime :: UTCTime
|
{ changeTime :: UTCTime
|
||||||
|
@ -173,9 +174,9 @@ runChangeChan = atomically
|
||||||
-
|
-
|
||||||
- Exceptions are ignored, otherwise a whole watcher thread could be crashed.
|
- Exceptions are ignored, otherwise a whole watcher thread could be crashed.
|
||||||
-}
|
-}
|
||||||
runHandler :: MVar Annex.AnnexState -> ChangeChan -> Handler -> FilePath -> IO ()
|
runHandler :: MVar Annex.AnnexState -> ChangeChan -> Handler -> FilePath -> Bool -> IO ()
|
||||||
runHandler st changechan handler file = void $ do
|
runHandler st changechan handler file inscan = void $ do
|
||||||
r <- tryIO (runStateMVar st $ handler file)
|
r <- tryIO (runStateMVar st $ handler file inscan)
|
||||||
case r of
|
case r of
|
||||||
Left e -> print e
|
Left e -> print e
|
||||||
Right Nothing -> noop
|
Right Nothing -> noop
|
||||||
|
@ -201,7 +202,7 @@ noChange = return Nothing
|
||||||
- or return a Change, leaving that to onAddSymlink.
|
- or return a Change, leaving that to onAddSymlink.
|
||||||
-}
|
-}
|
||||||
onAdd :: Handler
|
onAdd :: Handler
|
||||||
onAdd file = do
|
onAdd file False = do
|
||||||
showStart "add" file
|
showStart "add" file
|
||||||
handle =<< Command.Add.ingest file
|
handle =<< Command.Add.ingest file
|
||||||
noChange
|
noChange
|
||||||
|
@ -210,13 +211,23 @@ onAdd file = do
|
||||||
handle (Just key) = do
|
handle (Just key) = do
|
||||||
Command.Add.link file key True
|
Command.Add.link file key True
|
||||||
showEndOk
|
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.
|
{- 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
|
- Or, if it is a git-annex symlink, ensure it points to the content
|
||||||
- before adding it.
|
- before adding it.
|
||||||
-}
|
-}
|
||||||
onAddSymlink :: Handler
|
onAddSymlink :: Handler
|
||||||
onAddSymlink file = go =<< Backend.lookupFile file
|
onAddSymlink file _inscan = go =<< Backend.lookupFile file
|
||||||
where
|
where
|
||||||
go Nothing = addlink =<< liftIO (readSymbolicLink file)
|
go Nothing = addlink =<< liftIO (readSymbolicLink file)
|
||||||
go (Just (key, _)) = do
|
go (Just (key, _)) = do
|
||||||
|
@ -249,7 +260,7 @@ onAddSymlink file = go =<< Backend.lookupFile file
|
||||||
madeChange file "link"
|
madeChange file "link"
|
||||||
|
|
||||||
onDel :: Handler
|
onDel :: Handler
|
||||||
onDel file = do
|
onDel file _inscan = do
|
||||||
Annex.Queue.addUpdateIndex =<<
|
Annex.Queue.addUpdateIndex =<<
|
||||||
inRepo (Git.UpdateIndex.unstageFile file)
|
inRepo (Git.UpdateIndex.unstageFile file)
|
||||||
madeChange file "rm"
|
madeChange file "rm"
|
||||||
|
@ -262,14 +273,14 @@ onDel file = do
|
||||||
- command to get the recursive list of files in the directory, so rm is
|
- command to get the recursive list of files in the directory, so rm is
|
||||||
- just as good. -}
|
- just as good. -}
|
||||||
onDelDir :: Handler
|
onDelDir :: Handler
|
||||||
onDelDir dir = do
|
onDelDir dir _inscan = do
|
||||||
Annex.Queue.addCommand "rm"
|
Annex.Queue.addCommand "rm"
|
||||||
[Params "--quiet -r --cached --ignore-unmatch --"] [dir]
|
[Params "--quiet -r --cached --ignore-unmatch --"] [dir]
|
||||||
madeChange dir "rmdir"
|
madeChange dir "rmdir"
|
||||||
|
|
||||||
{- Called when there's an error with inotify. -}
|
{- Called when there's an error with inotify. -}
|
||||||
onErr :: Handler
|
onErr :: Handler
|
||||||
onErr msg = do
|
onErr msg _inscan = do
|
||||||
warning msg
|
warning msg
|
||||||
return Nothing
|
return Nothing
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,8 @@ watchDir :: INotify -> FilePath -> (FilePath -> Bool) -> WatchHooks -> IO ()
|
||||||
watchDir i dir ignored hooks
|
watchDir i dir ignored hooks
|
||||||
| ignored dir = noop
|
| ignored dir = noop
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
|
-- Use a lock to make sure events generated during initial
|
||||||
|
-- scan come before real inotify events.
|
||||||
lock <- newLock
|
lock <- newLock
|
||||||
let handler event = withLock lock (void $ go event)
|
let handler event = withLock lock (void $ go event)
|
||||||
void (addWatch i watchevents dir handler)
|
void (addWatch i watchevents dir handler)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue