diff options
-rw-r--r-- | Annex.hs | 2 | ||||
-rw-r--r-- | Assistant/Threads/Watcher.hs | 5 | ||||
-rw-r--r-- | Checks.hs | 11 | ||||
-rw-r--r-- | Command.hs | 14 | ||||
-rw-r--r-- | Command/Add.hs | 5 | ||||
-rw-r--r-- | Command/AddUnused.hs | 6 | ||||
-rw-r--r-- | Command/AddUrl.hs | 4 | ||||
-rw-r--r-- | Command/Copy.hs | 5 | ||||
-rw-r--r-- | Command/Direct.hs | 7 | ||||
-rw-r--r-- | Command/Drop.hs | 2 | ||||
-rw-r--r-- | Command/Find.hs | 2 | ||||
-rw-r--r-- | Command/Fix.hs | 2 | ||||
-rw-r--r-- | Command/FromKey.hs | 7 | ||||
-rw-r--r-- | Command/Fsck.hs | 2 | ||||
-rw-r--r-- | Command/Import.hs | 5 | ||||
-rw-r--r-- | Command/Indirect.hs | 7 | ||||
-rw-r--r-- | Command/Lock.hs | 2 | ||||
-rw-r--r-- | Command/Log.hs | 2 | ||||
-rw-r--r-- | Command/Migrate.hs | 3 | ||||
-rw-r--r-- | Command/Move.hs | 2 | ||||
-rw-r--r-- | Command/ReKey.hs | 2 | ||||
-rw-r--r-- | Command/Reinject.hs | 2 | ||||
-rw-r--r-- | Command/Unannex.hs | 3 | ||||
-rw-r--r-- | Command/Uninit.hs | 2 | ||||
-rw-r--r-- | Command/Unlock.hs | 2 | ||||
-rw-r--r-- | Command/Watch.hs | 4 | ||||
-rw-r--r-- | Command/WebApp.hs | 4 | ||||
-rw-r--r-- | Command/Whereis.hs | 2 | ||||
-rw-r--r-- | Config.hs | 15 | ||||
-rw-r--r-- | Utility/FSEvents.hs | 5 | ||||
-rw-r--r-- | debian/changelog | 4 | ||||
-rw-r--r-- | doc/direct_mode.mdwn | 12 | ||||
-rw-r--r-- | doc/git-annex.mdwn | 3 |
33 files changed, 85 insertions, 70 deletions
@@ -104,6 +104,7 @@ data AnnexState = AnnexState , uuidmap :: Maybe UUIDMap , preferredcontentmap :: Maybe PreferredContentMap , shared :: Maybe SharedRepository + , direct :: Maybe Bool , forcetrust :: TrustMap , trustmap :: Maybe TrustMap , groupmap :: Maybe GroupMap @@ -133,6 +134,7 @@ newState gitrepo = AnnexState , uuidmap = Nothing , preferredcontentmap = Nothing , shared = Nothing + , direct = Nothing , forcetrust = M.empty , trustmap = Nothing , groupmap = Nothing diff --git a/Assistant/Threads/Watcher.hs b/Assistant/Threads/Watcher.hs index a69ab6a09..1c5d7206b 100644 --- a/Assistant/Threads/Watcher.hs +++ b/Assistant/Threads/Watcher.hs @@ -69,7 +69,6 @@ watchThread = NamedThread "Watcher" $ do errhook <- hook onErr let hooks = mkWatchHooks { addHook = addhook - , modifyHook = addhook , delHook = delhook , addSymlinkHook = addsymlinkhook , delDirHook = deldirhook @@ -143,10 +142,10 @@ onAddDirect file fs = do case (v, fs) of (Just key, Just filestatus) -> ifM (liftAnnex $ changedFileStatus key filestatus) - ( noChange - , do + ( do liftAnnex $ changedDirect key file pendingAddChange file + , noChange ) _ -> pendingAddChange file @@ -13,6 +13,8 @@ module Checks where import Common.Annex import Types.Command import Init +import Config +import qualified Git commonChecks :: [CommandCheck] commonChecks = [repoExists] @@ -20,6 +22,14 @@ commonChecks = [repoExists] repoExists :: CommandCheck repoExists = CommandCheck 0 ensureInitialized +notDirect :: Command -> Command +notDirect = addCheck $ whenM isDirect $ + error "You cannot run this subcommand in a direct mode repository." + +notBareRepo :: Command -> Command +notBareRepo = addCheck $ whenM (fromRepo Git.repoIsLocalBare) $ + error "You cannot run this subcommand in a bare repository." + dontCheck :: CommandCheck -> Command -> Command dontCheck check cmd = mutateCheck cmd $ \c -> filter (/= check) c @@ -29,3 +39,4 @@ addCheck check cmd = mutateCheck cmd $ \c -> mutateCheck :: Command -> ([CommandCheck] -> [CommandCheck]) -> Command mutateCheck cmd@(Command { cmdcheck = c }) a = cmd { cmdcheck = a c } + diff --git a/Command.hs b/Command.hs index 6c127c15d..8225f7b1b 100644 --- a/Command.hs +++ b/Command.hs @@ -17,8 +17,6 @@ module Command ( doCommand, whenAnnexed, ifAnnexed, - notBareRepo, - notDirect, isBareRepo, numCopies, numCopiesCheck, @@ -98,18 +96,6 @@ whenAnnexed a file = ifAnnexed file (a file) (return Nothing) ifAnnexed :: FilePath -> ((Key, Backend) -> Annex a) -> Annex a -> Annex a ifAnnexed file yes no = maybe no yes =<< Backend.lookupFile file -notBareRepo :: Annex a -> Annex a -notBareRepo a = do - whenM isBareRepo $ - error "You cannot run this subcommand in a bare repository." - a - -notDirect :: Annex a -> Annex a -notDirect a = ifM isDirect - ( error "You cannot run this subcommand in a direct mode repository." - , a - ) - isBareRepo :: Annex Bool isBareRepo = fromRepo Git.repoIsLocalBare diff --git a/Command/Add.hs b/Command/Add.hs index e18f8592c..b3181cfd7 100644 --- a/Command/Add.hs +++ b/Command/Add.hs @@ -23,7 +23,8 @@ import Utility.FileMode import Config def :: [Command] -def = [command "add" paramPaths seek "add files to annex"] +def = [notDirect $ notBareRepo $ + command "add" paramPaths seek "add files to annex"] {- Add acts on both files not checked into git yet, and unlocked files. -} seek :: [CommandSeek] @@ -33,7 +34,7 @@ seek = [withFilesNotInGit start, withFilesUnlocked start] - backend, and then moving it into the annex directory and setting up - the symlink pointing to its content. -} start :: FilePath -> CommandStart -start file = notBareRepo $ notDirect $ ifAnnexed file fixup add +start file = ifAnnexed file fixup add where add = do s <- liftIO $ getSymbolicLinkStatus file diff --git a/Command/AddUnused.hs b/Command/AddUnused.hs index 519c67e1b..23dbdfcca 100644 --- a/Command/AddUnused.hs +++ b/Command/AddUnused.hs @@ -14,14 +14,16 @@ import qualified Command.Add import Types.Key def :: [Command] -def = [command "addunused" (paramRepeating paramNumRange) +def = [notDirect $ command "addunused" (paramRepeating paramNumRange) seek "add back unused files"] seek :: [CommandSeek] seek = [withUnusedMaps start] start :: UnusedMaps -> Int -> CommandStart -start = startUnused "addunused" perform (performOther "bad") (performOther "tmp") +start = startUnused "addunused" perform + (performOther "bad") + (performOther "tmp") perform :: Key -> CommandPerform perform key = next $ Command.Add.cleanup file key True diff --git a/Command/AddUrl.hs b/Command/AddUrl.hs index 0003237eb..9c6e8aa86 100644 --- a/Command/AddUrl.hs +++ b/Command/AddUrl.hs @@ -24,7 +24,7 @@ import Types.KeySource import Config def :: [Command] -def = [withOptions [fileOption, pathdepthOption] $ +def = [notDirect $ notBareRepo $ withOptions [fileOption, pathdepthOption] $ command "addurl" (paramRepeating paramUrl) seek "add urls to annex"] fileOption :: Option @@ -39,7 +39,7 @@ seek = [withField fileOption return $ \f -> withStrings $ start f d] start :: Maybe FilePath -> Maybe Int -> String -> CommandStart -start optfile pathdepth s = notBareRepo $ go $ fromMaybe bad $ parseURI s +start optfile pathdepth s = go $ fromMaybe bad $ parseURI s where bad = fromMaybe (error $ "bad url " ++ s) $ parseURI $ escapeURIString isUnescapedInURI s diff --git a/Command/Copy.hs b/Command/Copy.hs index 6967c2f93..08c95369b 100644 --- a/Command/Copy.hs +++ b/Command/Copy.hs @@ -14,8 +14,9 @@ import qualified Remote import Annex.Wanted def :: [Command] -def = [withOptions Command.Move.options $ command "copy" paramPaths seek - "copy content of files to/from another repository"] +def = [notDirect $ + withOptions Command.Move.options $ command "copy" paramPaths seek + "copy content of files to/from another repository"] seek :: [CommandSeek] seek = [withField Command.Move.toOption Remote.byName $ \to -> diff --git a/Command/Direct.hs b/Command/Direct.hs index 8e7f40145..0c007bb10 100644 --- a/Command/Direct.hs +++ b/Command/Direct.hs @@ -16,15 +16,14 @@ import Config import Annex.Direct def :: [Command] -def = [command "direct" paramNothing seek "switch repository to direct mode"] +def = [notBareRepo $ + command "direct" paramNothing seek "switch repository to direct mode"] seek :: [CommandSeek] seek = [withNothing start] start :: CommandStart -start = notBareRepo $ - ifM isDirect - ( stop , next perform ) +start = ifM isDirect ( stop , next perform ) perform :: CommandPerform perform = do diff --git a/Command/Drop.hs b/Command/Drop.hs index 3a30703d5..cb38275bf 100644 --- a/Command/Drop.hs +++ b/Command/Drop.hs @@ -20,7 +20,7 @@ import qualified Option import Annex.Wanted def :: [Command] -def = [withOptions [fromOption] $ command "drop" paramPaths seek +def = [notDirect $ withOptions [fromOption] $ command "drop" paramPaths seek "indicate content of files not currently wanted"] fromOption :: Option diff --git a/Command/Find.hs b/Command/Find.hs index 96f47ec87..8090f11c6 100644 --- a/Command/Find.hs +++ b/Command/Find.hs @@ -20,7 +20,7 @@ import Types.Key import qualified Option def :: [Command] -def = [noCommit $ withOptions [formatOption, print0Option] $ +def = [notDirect $ noCommit $ withOptions [formatOption, print0Option] $ command "find" paramPaths seek "lists available files"] formatOption :: Option diff --git a/Command/Fix.hs b/Command/Fix.hs index 38c8ac6e6..4b0151342 100644 --- a/Command/Fix.hs +++ b/Command/Fix.hs @@ -13,7 +13,7 @@ import qualified Annex.Queue import Annex.Content def :: [Command] -def = [noCommit $ command "fix" paramPaths seek +def = [notDirect $ noCommit $ command "fix" paramPaths seek "fix up symlinks to point to annexed content"] seek :: [CommandSeek] diff --git a/Command/FromKey.hs b/Command/FromKey.hs index f998fe1e6..d023be686 100644 --- a/Command/FromKey.hs +++ b/Command/FromKey.hs @@ -14,14 +14,15 @@ import Annex.Content import Types.Key def :: [Command] -def = [command "fromkey" (paramPair paramKey paramPath) seek - "adds a file using a specific key"] +def = [notDirect $ notBareRepo $ + command "fromkey" (paramPair paramKey paramPath) seek + "adds a file using a specific key"] seek :: [CommandSeek] seek = [withWords start] start :: [String] -> CommandStart -start (keyname:file:[]) = notBareRepo $ do +start (keyname:file:[]) = do let key = fromMaybe (error "bad key") $ file2key keyname inbackend <- inAnnex key unless inbackend $ error $ diff --git a/Command/Fsck.hs b/Command/Fsck.hs index 09f8b1136..04837a9e8 100644 --- a/Command/Fsck.hs +++ b/Command/Fsck.hs @@ -34,7 +34,7 @@ import System.Posix.Types (EpochTime) import System.Locale def :: [Command] -def = [withOptions options $ command "fsck" paramPaths seek +def = [notDirect $ withOptions options $ command "fsck" paramPaths seek "check for problems"] fromOption :: Option diff --git a/Command/Import.hs b/Command/Import.hs index cf91f7b5a..e8e839e4f 100644 --- a/Command/Import.hs +++ b/Command/Import.hs @@ -13,13 +13,14 @@ import qualified Annex import qualified Command.Add def :: [Command] -def = [command "import" paramPaths seek "move and add files from outside git working copy"] +def = [notDirect $ notBareRepo $ command "import" paramPaths seek + "move and add files from outside git working copy"] seek :: [CommandSeek] seek = [withPathContents start] start :: (FilePath, FilePath) -> CommandStart -start (srcfile, destfile) = notBareRepo $ +start (srcfile, destfile) = ifM (liftIO $ isRegularFile <$> getSymbolicLinkStatus srcfile) ( do showStart "import" destfile diff --git a/Command/Indirect.hs b/Command/Indirect.hs index 058a7b750..168d837ff 100644 --- a/Command/Indirect.hs +++ b/Command/Indirect.hs @@ -18,15 +18,14 @@ import Annex.Content import Annex.CatFile def :: [Command] -def = [command "indirect" paramNothing seek "switch repository to indirect mode"] +def = [notBareRepo $ command "indirect" paramNothing seek + "switch repository to indirect mode"] seek :: [CommandSeek] seek = [withNothing start] start :: CommandStart -start = notBareRepo $ - ifM isDirect - ( next perform, stop ) +start = ifM isDirect ( next perform, stop ) perform :: CommandPerform perform = do diff --git a/Command/Lock.hs b/Command/Lock.hs index 8aadf3f59..c34e6a16b 100644 --- a/Command/Lock.hs +++ b/Command/Lock.hs @@ -12,7 +12,7 @@ import Command import qualified Annex.Queue def :: [Command] -def = [command "lock" paramPaths seek "undo unlock command"] +def = [notDirect $ command "lock" paramPaths seek "undo unlock command"] seek :: [CommandSeek] seek = [withFilesUnlocked start, withFilesUnlockedToBeCommitted start] diff --git a/Command/Log.hs b/Command/Log.hs index 6608a9906..b20d17674 100644 --- a/Command/Log.hs +++ b/Command/Log.hs @@ -36,7 +36,7 @@ data RefChange = RefChange type Outputter = Bool -> POSIXTime -> [UUID] -> Annex () def :: [Command] -def = [withOptions options $ +def = [notDirect $ withOptions options $ command "log" paramPaths seek "shows location log"] options :: [Option] diff --git a/Command/Migrate.hs b/Command/Migrate.hs index d486eeb09..f3ff0dd72 100644 --- a/Command/Migrate.hs +++ b/Command/Migrate.hs @@ -18,7 +18,8 @@ import qualified Command.ReKey import qualified Command.Fsck def :: [Command] -def = [command "migrate" paramPaths seek "switch data to different backend"] +def = [notDirect $ + command "migrate" paramPaths seek "switch data to different backend"] seek :: [CommandSeek] seek = [withFilesInGit $ whenAnnexed start] diff --git a/Command/Move.hs b/Command/Move.hs index 316e4192e..80b362c8a 100644 --- a/Command/Move.hs +++ b/Command/Move.hs @@ -19,7 +19,7 @@ import Logs.Presence import Logs.Transfer def :: [Command] -def = [withOptions options $ command "move" paramPaths seek +def = [notDirect $ withOptions options $ command "move" paramPaths seek "move content of files to/from another repository"] fromOption :: Option diff --git a/Command/ReKey.hs b/Command/ReKey.hs index ea06873c4..df878a581 100644 --- a/Command/ReKey.hs +++ b/Command/ReKey.hs @@ -16,7 +16,7 @@ import qualified Command.Add import Logs.Web def :: [Command] -def = [command "rekey" +def = [notDirect $ command "rekey" (paramOptional $ paramRepeating $ paramPair paramPath paramKey) seek "change keys used for files"] diff --git a/Command/Reinject.hs b/Command/Reinject.hs index d346925fa..12657f7f4 100644 --- a/Command/Reinject.hs +++ b/Command/Reinject.hs @@ -14,7 +14,7 @@ import Annex.Content import qualified Command.Fsck def :: [Command] -def = [command "reinject" (paramPair "SRC" "DEST") seek +def = [notDirect $ command "reinject" (paramPair "SRC" "DEST") seek "sets content of annexed file"] seek :: [CommandSeek] diff --git a/Command/Unannex.hs b/Command/Unannex.hs index 89134bb84..c5ab028cd 100644 --- a/Command/Unannex.hs +++ b/Command/Unannex.hs @@ -16,7 +16,8 @@ import qualified Git.Command import qualified Git.LsFiles as LsFiles def :: [Command] -def = [command "unannex" paramPaths seek "undo accidential add command"] +def = [notDirect $ + command "unannex" paramPaths seek "undo accidential add command"] seek :: [CommandSeek] seek = [withFilesInGit $ whenAnnexed start] diff --git a/Command/Uninit.hs b/Command/Uninit.hs index 37b3ff511..beb17394d 100644 --- a/Command/Uninit.hs +++ b/Command/Uninit.hs @@ -18,7 +18,7 @@ import qualified Annex.Branch import Annex.Content def :: [Command] -def = [addCheck check $ command "uninit" paramPaths seek +def = [notDirect $ addCheck check $ command "uninit" paramPaths seek "de-initialize git-annex and clean out repository"] check :: Annex () diff --git a/Command/Unlock.hs b/Command/Unlock.hs index 5a0e6efeb..422afcc55 100644 --- a/Command/Unlock.hs +++ b/Command/Unlock.hs @@ -18,7 +18,7 @@ def = , c "edit" "same as unlock" ] where - c n = command n paramPaths seek + c n = notDirect . command n paramPaths seek seek :: [CommandSeek] seek = [withFilesInGit $ whenAnnexed start] diff --git a/Command/Watch.hs b/Command/Watch.hs index eb70ef6b1..25b5c6bba 100644 --- a/Command/Watch.hs +++ b/Command/Watch.hs @@ -13,7 +13,7 @@ import Command import Option def :: [Command] -def = [withOptions [foregroundOption, stopOption] $ +def = [notBareRepo $ withOptions [foregroundOption, stopOption] $ command "watch" paramNothing seek "watch for changes"] seek :: [CommandSeek] @@ -28,7 +28,7 @@ stopOption :: Option stopOption = Option.flag [] "stop" "stop daemon" start :: Bool -> Bool -> Bool -> CommandStart -start assistant foreground stopdaemon = notBareRepo $ do +start assistant foreground stopdaemon = do if stopdaemon then stopDaemon else startDaemon assistant foreground Nothing -- does not return diff --git a/Command/WebApp.hs b/Command/WebApp.hs index 11ba23d83..581d6d4dd 100644 --- a/Command/WebApp.hs +++ b/Command/WebApp.hs @@ -29,7 +29,7 @@ import Control.Concurrent import Control.Concurrent.STM def :: [Command] -def = [noCommit $ noRepo startNoRepo $ dontCheck repoExists $ +def = [noCommit $ noRepo startNoRepo $ dontCheck repoExists $ notBareRepo $ command "webapp" paramNothing seek "launch webapp"] seek :: [CommandSeek] @@ -39,7 +39,7 @@ start :: CommandStart start = start' True start' :: Bool -> CommandStart -start' allowauto = notBareRepo $ do +start' allowauto = do liftIO $ ensureInstalled ifM isInitialized ( go , auto ) stop diff --git a/Command/Whereis.hs b/Command/Whereis.hs index 251c4ec7a..6c60ab19d 100644 --- a/Command/Whereis.hs +++ b/Command/Whereis.hs @@ -15,7 +15,7 @@ import Remote import Logs.Trust def :: [Command] -def = [noCommit $ command "whereis" paramPaths seek +def = [notDirect $ noCommit $ command "whereis" paramPaths seek "lists repositories that have file content"] seek :: [CommandSeek] @@ -116,13 +116,20 @@ getDiskReserve = fromMaybe megabyte . readSize dataUnits where megabyte = 1000000 -{- Gets annex.direct setting. -} +{- Gets annex.direct setting, cached for speed. -} isDirect :: Annex Bool -isDirect = fromMaybe False . Git.Config.isTrue <$> - getConfig (annexConfig "direct") "" +isDirect = maybe fromconfig return =<< Annex.getState Annex.direct + where + fromconfig = do + direct <- fromMaybe False . Git.Config.isTrue <$> + getConfig (annexConfig "direct") "" + Annex.changeState $ \s -> s { Annex.direct = Just direct } + return direct setDirect :: Bool -> Annex () -setDirect b = setConfig (annexConfig "direct") (if b then "true" else "false") +setDirect b = do + setConfig (annexConfig "direct") (if b then "true" else "false") + Annex.changeState $ \s -> s { Annex.direct = Just b } {- Gets annex.httpheaders or annex.httpheaders-command setting, - splitting it into lines. -} diff --git a/Utility/FSEvents.hs b/Utility/FSEvents.hs index 97431c159..af8c2fc2f 100644 --- a/Utility/FSEvents.hs +++ b/Utility/FSEvents.hs @@ -50,8 +50,13 @@ watchDir dir ignored hooks = do ) else maybe (runhook delHook Nothing) handleadd =<< getstatus (eventPath evt) + {- Add hooks are run when a file is modified for + - compatability with INotify, which calls the add + - hook when a file is closed, and so tends to call + - both add and modify for file modifications. -} when (hasflag eventFlagItemModified && not (hasflag eventFlagItemIsDir)) $ do ms <- getstatus $ eventPath evt + maybe noop handleadd ms runhook modifyHook ms where hasflag f = eventFlags evt .&. f /= 0 diff --git a/debian/changelog b/debian/changelog index ef1c7ee34..793fa7404 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,8 +3,8 @@ git-annex (3.20121212) UNRELEASED; urgency=low * direct, indirect: New commands, that switch a repository to and from direct mode. In direct mode, files are accessed directly, rather than via symlinks. Note that direct mode is currently experimental. Many - git and git-annex commands do not work, or can even cause data loss in - direct mode. + git-annex commands do not work in direct mode. Some git commands can + cause data loss when used in direct mode repositories. * assistant: Support direct mode. * OSX assistant: Now uses the FSEvents API to detect file changes. This avoids issues with running out of file descriptors on large trees, diff --git a/doc/direct_mode.mdwn b/doc/direct_mode.mdwn index 2acf52fd5..862a843cf 100644 --- a/doc/direct_mode.mdwn +++ b/doc/direct_mode.mdwn @@ -42,9 +42,9 @@ changed files to git, pushes them out, pulls down any changes, etc. You can also run `git annex get` to transfer the content of files into your direct mode repository. Or if the direct mode repository is a remote of -some other, regular git-annex repository, you can use commands like `git -annex copy` and `git annex move` to transfer the contents of files to the -direct mode repository. +some other, regular git-annex repository, you can use commands in the other +repository like `git annex copy` and `git annex move` to transfer the +contents of files to the direct mode repository. You can use `git commit --staged`. (But not `git commit -a` .. It'll commit whole large files into git!) @@ -53,15 +53,11 @@ You can use `git log` and other git query commands. ## what doesn't work in direct mode -Don't use `git annex add` -- it thinks all direct mode files are unlocked, -and locks them. - In general git-annex commands will only work in direct mode repositories on files whose content is not present. That's because such files are still represented as symlinks, which git-annex commands know how to operate on. So, `git annex get` works, but `git annex drop` and `git annex move` don't, -and things like `git annex fsck` and `git annex status` show incomplete -information. +and things like `git annex status` show incomplete information. It's technically possible to make all git-annex commands work in direct mode repositories, so this might change. Check back to this page to see diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn index 169c234c1..b36577d99 100644 --- a/doc/git-annex.mdwn +++ b/doc/git-annex.mdwn @@ -190,6 +190,9 @@ subdirectories). Like watch, but also automatically syncs changes to other remotes. Typically started at boot, or when you log in. + With the --autostart option, the assistant is started in any repositories + it has created. + * webapp Runs a web app, that allows easy setup of a git-annex repository, |