From b33a649a252424e447c9b33834eb439992dda15b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 24 May 2016 15:24:38 -0400 Subject: [PATCH] enableremote: Can now be used to explicitly enable git-annex to use git remotes. Using the command this way prevents other git-annex commands from probing new git remotes to auto-enable them. --- CHANGELOG | 3 ++ Command/EnableRemote.hs | 87 +++++++++++++++++++++------------ doc/git-annex-enableremote.mdwn | 19 ++++--- 3 files changed, 71 insertions(+), 38 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0a971b33f4..8a40585732 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,9 @@ git-annex (6.20160512) UNRELEASED; urgency=medium when in a subdirectory of the repository. This affected git annex view. * Fix crash when entering/changing view in a subdirectory of a repo that has a dotfile in its root. + * enableremote: Can now be used to explicitly enable git-annex to use + git remotes. Using the command this way prevents other git-annex + commands from probing new git remotes to auto-enable them. * Support building with ghc 8.0.1. * Pass the various gnupg-options configs to gpg in several cases where they were not before. Most notably, gnupg-decrypt-options is now diff --git a/Command/EnableRemote.hs b/Command/EnableRemote.hs index be20ea0498..bf0ad37a34 100644 --- a/Command/EnableRemote.hs +++ b/Command/EnableRemote.hs @@ -1,6 +1,6 @@ {- git-annex command - - - Copyright 2013 Joey Hess + - Copyright 2013-2016 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} @@ -8,18 +8,22 @@ module Command.EnableRemote where import Command +import qualified Annex import qualified Logs.Remote import qualified Types.Remote as R +import qualified Git.Types as Git import qualified Annex.SpecialRemote import qualified Remote import qualified Types.Remote as Remote +import qualified Remote.Git import Logs.UUID +import Annex.UUID import qualified Data.Map as M cmd :: Command cmd = command "enableremote" SectionSetup - "enables use of an existing special remote" + "enables git-annex to use a remote" (paramPair paramName $ paramOptional $ paramRepeating paramKeyValue) (withParams seek) @@ -27,43 +31,62 @@ seek :: CmdParams -> CommandSeek seek = withWords start start :: [String] -> CommandStart -start [] = unknownNameError "Specify the special remote to enable." -start (name:ws) = go =<< Annex.SpecialRemote.findExisting name +start [] = unknownNameError "Specify the remote to enable." +start (name:rest) = go =<< filter matchingname <$> Annex.fromRepo Git.remotes where - config = Logs.Remote.keyValToConfig ws - - go Nothing = do - m <- Annex.SpecialRemote.specialRemoteMap - confm <- Logs.Remote.readRemoteLog - v <- Remote.nameToUUID' name - case v of - Right u | u `M.member` m -> - go (Just (u, fromMaybe M.empty (M.lookup u confm))) - _ -> unknownNameError "Unknown special remote." - go (Just (u, c)) = do - let fullconfig = config `M.union` c - t <- either error return (Annex.SpecialRemote.findType fullconfig) - showStart "enableremote" name - gc <- maybe def Remote.gitconfig <$> Remote.byUUID u - next $ perform t u fullconfig gc + matchingname r = Git.remoteName r == Just name + go [] = startSpecialRemote name (Logs.Remote.keyValToConfig rest) + =<< Annex.SpecialRemote.findExisting name + go (r:_) = startNormalRemote name r + +type RemoteName = String + +startNormalRemote :: RemoteName -> Git.Repo -> CommandStart +startNormalRemote name r = do + showStart "enableremote" name + next $ next $ do + r' <- Remote.Git.configRead False r + u <- getRepoUUID r' + return (u /= NoUUID) + +startSpecialRemote :: RemoteName -> Remote.RemoteConfig -> Maybe (UUID, Remote.RemoteConfig) -> CommandStart +startSpecialRemote name config Nothing = do + m <- Annex.SpecialRemote.specialRemoteMap + confm <- Logs.Remote.readRemoteLog + v <- Remote.nameToUUID' name + case v of + Right u | u `M.member` m -> + startSpecialRemote name config $ + Just (u, fromMaybe M.empty (M.lookup u confm)) + _ -> unknownNameError "Unknown remote name." +startSpecialRemote name config (Just (u, c)) = do + let fullconfig = config `M.union` c + t <- either error return (Annex.SpecialRemote.findType fullconfig) + showStart "enableremote" name + gc <- maybe def Remote.gitconfig <$> Remote.byUUID u + next $ performSpecialRemote t u fullconfig gc + +performSpecialRemote :: RemoteType -> UUID -> R.RemoteConfig -> RemoteGitConfig -> CommandPerform +performSpecialRemote t u c gc = do + (c', u') <- R.setup t (Just u) Nothing c gc + next $ cleanupSpecialRemote u' c' + +cleanupSpecialRemote :: UUID -> R.RemoteConfig -> CommandCleanup +cleanupSpecialRemote u c = do + Logs.Remote.configSet u c + return True unknownNameError :: String -> Annex a unknownNameError prefix = do m <- Annex.SpecialRemote.specialRemoteMap descm <- M.unionWith Remote.addName <$> uuidMap <*> pure m - msg <- if M.null m + specialmsg <- if M.null m then pure "(No special remotes are currently known; perhaps use initremote instead?)" else Remote.prettyPrintUUIDsDescs "known special remotes" descm (M.keys m) - error $ prefix ++ "\n" ++ msg - -perform :: RemoteType -> UUID -> R.RemoteConfig -> RemoteGitConfig -> CommandPerform -perform t u c gc = do - (c', u') <- R.setup t (Just u) Nothing c gc - next $ cleanup u' c' - -cleanup :: UUID -> R.RemoteConfig -> CommandCleanup -cleanup u c = do - Logs.Remote.configSet u c - return True + nouuids <- filterM (\r -> (==) NoUUID <$> getRepoUUID r) + =<< Annex.fromRepo Git.remotes + let nouuidmsg = unlines $ map ("\t" ++) $ + mapMaybe Git.remoteName nouuids + error $ concat $ filter (not . null) [prefix ++ "\n", nouuidmsg, specialmsg] diff --git a/doc/git-annex-enableremote.mdwn b/doc/git-annex-enableremote.mdwn index 8467247157..d63dfaf627 100644 --- a/doc/git-annex-enableremote.mdwn +++ b/doc/git-annex-enableremote.mdwn @@ -1,6 +1,6 @@ # NAME -git-annex enableremote - enables use of an existing special remote +git-annex enableremote - enables git-annex to use a remote # SYNOPSIS @@ -8,15 +8,22 @@ git annex enableremote `name|uuid|desc [param=value ...]` # DESCRIPTION -Enables use of an existing special remote in the current repository, -which may be a different repository than the one in which it was -originally created with the initremote command. +Enables use of an existing remote in the current repository. -The name of the remote is the same name used when originally +This is often used to enable use of a special (non-git) remote, by +a different repository than the one in which it was +originally created with the initremote command. + +It can also be used to explicitly enable a git remote, +so that git-annex can store the contents of files there. First +run `git remote add`, and then `git annex enableremote` with the name of +the remote. + +When enabling a special remote, specify the same name used when originally creating that remote with `git annex initremote`. Run `git annex enableremote` without any name to get a list of special remote names. Or you can specify the uuid or description of the -remote. +special remote. Some special remotes may need parameters to be specified every time they are enabled. For example, the directory special remote requires a directory=