diff options
author | Joey Hess <joey@kitenet.net> | 2013-03-11 15:14:42 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2013-03-11 15:14:42 -0400 |
commit | b2f04c1ed094aec6f734103d50077c48f3aad2a9 (patch) | |
tree | 064012fec3e955f1422a6b05ad075894ea6c755b | |
parent | ee98604d9463da1abadd0a9490f90a8bce358279 (diff) |
synthesize RmChange when a directory is deleted
This gets directory renames closer to being fully detected.
There's close to no extra overhead to doing it this way.
-rw-r--r-- | Assistant/Threads/Committer.hs | 13 | ||||
-rw-r--r-- | Assistant/Threads/Watcher.hs | 24 | ||||
-rw-r--r-- | Assistant/Types/Changes.hs | 2 |
3 files changed, 26 insertions, 13 deletions
diff --git a/Assistant/Threads/Committer.hs b/Assistant/Threads/Committer.hs index f1e26f9aa..0d9010cb7 100644 --- a/Assistant/Threads/Committer.hs +++ b/Assistant/Threads/Committer.hs @@ -80,7 +80,7 @@ waitChangeTime a = runEvery (Seconds 1) <~> do changes <- getChanges -- See if now's a good time to commit. now <- liftIO getCurrentTime - case (shouldCommit now changes, lonelychange changes) of + case (shouldCommit now changes, possiblyrename changes) of (True, False) -> a (changes, now) (True, True) -> do -- Wait for other, related changes to arrive. @@ -92,10 +92,13 @@ waitChangeTime a = runEvery (Seconds 1) <~> do _ -> refill changes where {- Did we perhaps only get one of the AddChange and RmChange pair - - that make up a rename? -} - lonelychange [(PendingAddChange _ _)] = True - lonelychange [c] | isRmChange c = True - lonelychange _ = False + - that make up a file rename? Or some of the pairs that make up + - a directory rename? + -} + possiblyrename cs = all renamepart cs + + renamepart (PendingAddChange _ _) = True + renamepart c = isRmChange c isRmChange :: Change -> Bool isRmChange (Change { changeInfo = i }) | i == RmChange = True diff --git a/Assistant/Threads/Watcher.hs b/Assistant/Threads/Watcher.hs index 0f76c6a4c..8d06e6659 100644 --- a/Assistant/Threads/Watcher.hs +++ b/Assistant/Threads/Watcher.hs @@ -43,6 +43,7 @@ import Data.Bits.Utils import Data.Typeable import qualified Data.ByteString.Lazy as L import qualified Control.Exception as E +import Data.Time.Clock checkCanWatch :: Annex () checkCanWatch @@ -251,17 +252,26 @@ onDel file _ = do {- A directory has been deleted, or moved, so tell git to remove anything - that was inside it from its cache. Since it could reappear at any time, - - use --cached to only delete it from the index. + - use --cached to only delete it from the index. - - - Note: This could use unstageFile, but would need to run another git - - command to get the recursive list of files in the directory, so rm is - - just as good. -} + - This queues up a lot of RmChanges, which assists the Committer in + - pairing up renamed files when the directory was renamed. -} onDelDir :: Handler onDelDir dir _ = do debug ["directory deleted", dir] - liftAnnex $ Annex.Queue.addCommand "rm" - [Params "--quiet -r --cached --ignore-unmatch --"] [dir] - madeChange dir RmDirChange + (fs, clean) <- liftAnnex $ inRepo $ LsFiles.deleted [dir] + + liftAnnex $ forM_ fs $ \f -> Annex.Queue.addUpdateIndex =<< + inRepo (Git.UpdateIndex.unstageFile f) + + -- Get the events queued up as fast as possible, so the + -- committer sees them all in one block. + now <- liftIO getCurrentTime + forM_ fs $ \f -> recordChange $ Change now f RmChange + + void $ liftIO $ clean + liftAnnex $ Annex.Queue.flushWhenFull + noChange {- Called when there's an error with inotify or kqueue. -} onErr :: Handler diff --git a/Assistant/Types/Changes.hs b/Assistant/Types/Changes.hs index 9f0aad7a7..651085947 100644 --- a/Assistant/Types/Changes.hs +++ b/Assistant/Types/Changes.hs @@ -14,7 +14,7 @@ import Utility.TSet import Data.Time.Clock import Control.Concurrent.STM -data ChangeInfo = AddChange Key | LinkChange (Maybe Key) | RmChange | RmDirChange +data ChangeInfo = AddChange Key | LinkChange (Maybe Key) | RmChange deriving (Show, Eq) changeInfoKey :: ChangeInfo -> Maybe Key |