diff --git a/Annex/Init.hs b/Annex/Init.hs index 5acfccf7f6..d7c1ebd9ed 100644 --- a/Annex/Init.hs +++ b/Annex/Init.hs @@ -1,6 +1,6 @@ {- git-annex repository initialization - - - Copyright 2011-2019 Joey Hess + - Copyright 2011-2020 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} @@ -35,11 +35,13 @@ import Annex.Difference import Annex.UUID import Annex.WorkTree import Annex.Fixup +import Annex.Path import Config import Config.Files import Config.Smudge import qualified Upgrade.V5.Direct as Direct import qualified Annex.AdjustedBranch as AdjustedBranch +import Remote.List.Util (remotesChanged) import Annex.Environment import Annex.Hook import Annex.InodeSentinal @@ -150,8 +152,10 @@ ensureInitialized :: Annex () ensureInitialized = getVersion >>= maybe needsinit checkUpgrade where needsinit = ifM Annex.Branch.hasSibling - ( initialize Nothing Nothing - , giveup $ "First run: git-annex init" + ( do + initialize Nothing Nothing + autoEnableSpecialRemotes + , giveup "First run: git-annex init" ) {- Checks if a repository is initialized. Does not check version for ugrade. -} @@ -287,3 +291,25 @@ fixupUnusualReposAfterInit :: Annex () fixupUnusualReposAfterInit = do gc <- Annex.getGitConfig void $ inRepo $ \r -> fixupUnusualRepos r gc + +{- Try to enable any special remotes that are configured to do so. + - + - The enabling is done in a child process to avoid it using stdio. + -} +autoEnableSpecialRemotes :: Annex () +autoEnableSpecialRemotes = do + rp <- fromRawFilePath <$> fromRepo Git.repoPath + cmd <- liftIO programPath + liftIO $ withNullHandle $ \nullh -> do + let p = proc cmd + [ "init" + , "--autoenable" + ] + (Nothing, Nothing, Nothing, pid) <- createProcess $ p + { std_out = UseHandle nullh + , std_err = UseHandle nullh + , std_in = UseHandle nullh + , cwd = Just rp + } + void $ waitForProcess pid + remotesChanged diff --git a/Assistant/DeleteRemote.hs b/Assistant/DeleteRemote.hs index c7cf807831..f0743401bd 100644 --- a/Assistant/DeleteRemote.hs +++ b/Assistant/DeleteRemote.hs @@ -16,7 +16,7 @@ import Types.Transfer import Logs.Location import Assistant.DaemonStatus import qualified Remote -import Remote.List +import Remote.List.Util import qualified Git.Remote.Remove import Logs.Trust import qualified Annex @@ -35,7 +35,7 @@ disableRemote uuid = do <$> liftAnnex (Remote.remoteFromUUID uuid) liftAnnex $ do inRepo $ Git.Remote.Remove.remove (Remote.name remote) - void $ remoteListRefresh + remotesChanged updateSyncRemotes return remote diff --git a/Assistant/MakeRemote.hs b/Assistant/MakeRemote.hs index 3b36ef9a51..45ceb01337 100644 --- a/Assistant/MakeRemote.hs +++ b/Assistant/MakeRemote.hs @@ -13,7 +13,7 @@ import Assistant.Common import Assistant.Ssh import qualified Types.Remote as R import qualified Remote -import Remote.List +import Remote.List.Util import qualified Remote.Rsync as Rsync import qualified Remote.GCrypt as GCrypt import qualified Git @@ -46,7 +46,7 @@ makeSshRemote sshdata = maker (sshRepoName sshdata) (genSshUrl sshdata) addRemote :: Annex RemoteName -> Annex Remote addRemote a = do name <- a - void remoteListRefresh + remotesChanged maybe (error "failed to add remote") return =<< Remote.byName (Just name) @@ -174,7 +174,9 @@ previouslyUsedCredPair -> (Remote -> Bool) -> Annex (Maybe CredPair) previouslyUsedCredPair getstorage remotetype criteria = - getM fromstorage =<< filter criteria . filter sametype <$> remoteList + getM fromstorage + =<< filter criteria . filter sametype + <$> Remote.remoteList where sametype r = R.typename (R.remotetype r) == R.typename remotetype fromstorage r = do diff --git a/Assistant/Sync.hs b/Assistant/Sync.hs index 5b19d5216a..2b0fae5c97 100644 --- a/Assistant/Sync.hs +++ b/Assistant/Sync.hs @@ -22,8 +22,8 @@ import qualified Git import qualified Git.Command import qualified Remote import qualified Types.Remote as Remote -import qualified Remote.List as Remote import qualified Annex.Branch +import Remote.List.Util import Annex.UUID import Annex.TaggedPush import Annex.Ssh @@ -268,7 +268,7 @@ changeSyncFlag r enabled = do repo <- Remote.getRepo r let key = Config.remoteAnnexConfig repo "sync" Config.setConfig key (boolConfig enabled) - void Remote.remoteListRefresh + remotesChanged updateExportTreeFromLogAll :: Assistant () updateExportTreeFromLogAll = do diff --git a/Assistant/Threads/ConfigMonitor.hs b/Assistant/Threads/ConfigMonitor.hs index b8ccb9e23d..a0d748df66 100644 --- a/Assistant/Threads/ConfigMonitor.hs +++ b/Assistant/Threads/ConfigMonitor.hs @@ -18,7 +18,7 @@ import Logs.Trust import Logs.PreferredContent import Logs.Group import Logs.NumCopies -import Remote.List (remoteListRefresh) +import Remote.List.Util import qualified Git.LsTree as LsTree import Git.Types import Git.FilePath @@ -60,7 +60,7 @@ type Configs = S.Set (RawFilePath, Sha) configFilesActions :: [(RawFilePath, Assistant ())] configFilesActions = [ (uuidLog, void $ liftAnnex uuidDescMapLoad) - , (remoteLog, void $ liftAnnex remoteListRefresh) + , (remoteLog, void $ liftAnnex remotesChanged) , (trustLog, void $ liftAnnex trustMapLoad) , (groupLog, void $ liftAnnex groupMapLoad) , (numcopiesLog, void $ liftAnnex globalNumCopiesLoad) diff --git a/Assistant/WebApp/Configurators/Edit.hs b/Assistant/WebApp/Configurators/Edit.hs index c82fbe248f..cacacdc024 100644 --- a/Assistant/WebApp/Configurators/Edit.hs +++ b/Assistant/WebApp/Configurators/Edit.hs @@ -25,7 +25,7 @@ import qualified Remote.S3 as S3 #endif import qualified Remote import qualified Types.Remote as Remote -import qualified Remote.List as Remote +import Remote.List.Util import Logs.UUID import Logs.Group import Logs.PreferredContent @@ -116,7 +116,7 @@ setRepoConfig uuid mremote oldc newc = do , Param $ T.unpack $ repoName oldc , Param name ] - void Remote.remoteListRefresh + remotesChanged liftAssistant updateSyncRemotes when associatedDirectoryChanged $ case repoAssociatedDirectory newc of Nothing -> noop @@ -309,7 +309,7 @@ getUpgradeRepositoryR r = go =<< liftAnnex (repoIdRemote r) setConfig (remoteAnnexConfig repo "ignore") (Git.Config.boolConfig False) - liftAnnex $ void Remote.remoteListRefresh + liftAnnex remotesChanged liftAssistant updateSyncRemotes liftAssistant $ syncRemote rmt redirect DashboardR diff --git a/Assistant/WebApp/RepoList.hs b/Assistant/WebApp/RepoList.hs index f388dd77b9..9fcca1ae26 100644 --- a/Assistant/WebApp/RepoList.hs +++ b/Assistant/WebApp/RepoList.hs @@ -14,7 +14,7 @@ import Assistant.DaemonStatus import Assistant.WebApp.Notifications import qualified Remote import qualified Types.Remote as Remote -import Remote.List (remoteListRefresh) +import Remote.List.Util import Annex.UUID (getUUID) import Logs.Remote import Logs.Trust @@ -242,7 +242,7 @@ getRepositoriesReorderR = do when (Remote.cost r /= newcost) $ do repo <- Remote.getRepo r setRemoteCost repo newcost - void remoteListRefresh + remotesChanged fromjs = fromMaybe (RepoUUID NoUUID) . readish . T.unpack reorderCosts :: Remote -> [Remote] -> [(Remote, Cost)] diff --git a/CHANGELOG b/CHANGELOG index b19ab01110..95dd7fe9f8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ git-annex (8.20200523) UNRELEASED; urgency=medium + * Try to enable special remotes configured with autoenable=yes + when git-annex auto-initialization happens in a new clone of an + existing repo. Previously, git-annex init had to be explicitly run to + enable them. Special remotes cannot display anything when autoenabled + this way, to avoid interfering with the output of git-annex query + commands. * export: Added options for json output. * import: Added --json-progress. * addurl: Make --preserve-filename also apply when eg a torrent contains diff --git a/Command/Init.hs b/Command/Init.hs index 65bb05ca0b..b79f5be635 100644 --- a/Command/Init.hs +++ b/Command/Init.hs @@ -1,6 +1,6 @@ {- git-annex command - - - Copyright 2010 Joey Hess + - Copyright 2010-2020 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} @@ -24,6 +24,7 @@ cmd = dontCheck repoExists $ data InitOptions = InitOptions { initDesc :: String , initVersion :: Maybe RepoVersion + , autoEnableOnly :: Bool } optParser :: CmdParamsDesc -> Parser InitOptions @@ -33,6 +34,10 @@ optParser desc = InitOptions ( long "version" <> metavar paramValue <> help "Override default annex.version" )) + <*> switch + ( long "autoenable" + <> help "only enable special remotes configured with autoenable=true" + ) parseRepoVersion :: MonadFail m => String -> m RepoVersion parseRepoVersion s = case RepoVersion <$> readish s of @@ -47,8 +52,11 @@ seek :: InitOptions -> CommandSeek seek = commandAction . start start :: InitOptions -> CommandStart -start os = starting "init" (ActionItemOther (Just $ initDesc os)) $ - perform os +start os + | autoEnableOnly os = starting "init" (ActionItemOther (Just "autoenable")) $ + performAutoEnableOnly + | otherwise = starting "init" (ActionItemOther (Just $ initDesc os)) $ + perform os perform :: InitOptions -> CommandPerform perform os = do @@ -63,3 +71,8 @@ perform os = do (initVersion os) Annex.SpecialRemote.autoEnable next $ return True + +performAutoEnableOnly :: CommandPerform +performAutoEnableOnly = do + Annex.SpecialRemote.autoEnable + next $ return True diff --git a/Remote.hs b/Remote.hs index 6670925df0..581a035eaf 100644 --- a/Remote.hs +++ b/Remote.hs @@ -74,6 +74,7 @@ import Logs.Trust import Logs.Location hiding (logStatus) import Logs.Web import Remote.List +import Remote.List.Util import Config import Config.DynamicConfig import Git.Types (RemoteName, ConfigKey(..), fromConfigValue) @@ -286,7 +287,7 @@ remoteFromUUID u = ifM ((==) u <$> getUUID) findinmap = M.lookup u <$> remoteMap id {- Re-read remote list in case a new remote has popped up. -} tryharder = do - void remoteListRefresh + remotesChanged findinmap {- Filters a list of remotes to ones that have the listed uuids. -} diff --git a/Remote/List.hs b/Remote/List.hs index e605a62cd1..db8c53feb5 100644 --- a/Remote/List.hs +++ b/Remote/List.hs @@ -21,7 +21,6 @@ import Remote.Helper.Hooks import Remote.Helper.ReadOnly import Remote.Helper.ExportImport import qualified Git -import qualified Git.Config import qualified Remote.Git import qualified Remote.GCrypt @@ -90,17 +89,6 @@ remoteList' autoinit = do >>= mapM (remoteGen m t) >>= return . catMaybes -{- Forces the remoteList to be re-generated, re-reading the git config. -} -remoteListRefresh :: Annex [Remote] -remoteListRefresh = do - newg <- inRepo Git.Config.reRead - Annex.changeState $ \s -> s - { Annex.remotes = [] - , Annex.gitremotes = Nothing - , Annex.repo = newg - } - remoteList - {- Generates a Remote. -} remoteGen :: M.Map UUID RemoteConfig -> RemoteType -> Git.Repo -> Annex (Maybe Remote) remoteGen m t g = do diff --git a/Remote/List/Util.hs b/Remote/List/Util.hs new file mode 100644 index 0000000000..382a98fa5d --- /dev/null +++ b/Remote/List/Util.hs @@ -0,0 +1,24 @@ +{- git-annex remote list utils + - + - Copyright 2011-2020 Joey Hess + - + - Licensed under the GNU AGPL version 3 or higher. + -} + +module Remote.List.Util where + +import Annex.Common +import qualified Annex +import qualified Git.Config + +{- Call when remotes have changed. Re-reads the git config, and + - invalidates the cache so the remoteList will be re-generated next time + - it's used. -} +remotesChanged :: Annex () +remotesChanged = do + newg <- inRepo Git.Config.reRead + Annex.changeState $ \s -> s + { Annex.remotes = [] + , Annex.gitremotes = Nothing + , Annex.repo = newg + } diff --git a/doc/bugs/autoenable__61__true_seems_to_not_work_any_longer.mdwn b/doc/bugs/autoenable__61__true_seems_to_not_work_any_longer.mdwn index b5396e7faf..021f9bf6d5 100644 --- a/doc/bugs/autoenable__61__true_seems_to_not_work_any_longer.mdwn +++ b/doc/bugs/autoenable__61__true_seems_to_not_work_any_longer.mdwn @@ -78,3 +78,5 @@ I am a little confused though since we do test for this scenario in datalad and [[!tag projects/datalad]] [[!meta title="autoenable not done for implicit init"]] + +> [[done]], autoinit will now autoenable --[[Joey]] diff --git a/doc/git-annex-init.mdwn b/doc/git-annex-init.mdwn index c6b814b277..2c48977e40 100644 --- a/doc/git-annex-init.mdwn +++ b/doc/git-annex-init.mdwn @@ -48,6 +48,11 @@ to the user who tries to run git-annex init. When the version given is one that automatically upgrades to a newer version, it will automatically use the newer version instead. +* --autoenable + + Only enable any special remotes that were configured with + autoenable=true, do not otherwise initialize anything. + # SEE ALSO [[git-annex]](1) diff --git a/doc/git-annex-initremote.mdwn b/doc/git-annex-initremote.mdwn index ca204eac7f..c3fd0b0da0 100644 --- a/doc/git-annex-initremote.mdwn +++ b/doc/git-annex-initremote.mdwn @@ -93,10 +93,10 @@ want to use `git annex renameremote`. * `autoenable` To avoid `git annex enableremote` needing to be run, - you can pass "autoenable=true". Then when [[git-annex-init]](1) - is run in a new clone, it will attempt to enable the special remote. Of - course, this works best when the special remote does not need anything - special to be done to get it enabled. + you can pass "autoenable=true". Then when git-annex is run in a new clone, + it will attempt to enable the special remote. Of course, this works best + when the special remote does not need anything special to be done to get + it enabled. * `uuid` diff --git a/git-annex.cabal b/git-annex.cabal index d702fd81d6..9aa7430b18 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -956,6 +956,7 @@ Executable git-annex Remote.Helper.Ssh Remote.Hook Remote.List + Remote.List.Util Remote.P2P Remote.Rsync Remote.Rsync.RsyncUrl