{- git-annex special remote configuration
-
- - Copyright 2011-2019 Joey Hess <id@joeyh.name>
+ - Copyright 2011-2021 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
import Git.Types (RemoteName)
import qualified Data.Map as M
-import Data.Ord
{- See if there's an existing special remote with this name.
-
- - Prefer remotes that are not dead when a name appears multiple times. -}
+ - Remotes that are not dead come first in the list
+ - when a name appears multiple times. -}
findExisting :: RemoteName -> Annex (Maybe (UUID, RemoteConfig, Maybe (ConfigFrom UUID)))
findExisting name = do
+ (a, b) <- findExisting' name
+ return (headMaybe (a++b))
+
+{- Dead remotes with the name are in the second list, all others in the
+ - first list. -}
+findExisting' :: RemoteName -> Annex ([(UUID, RemoteConfig, Maybe (ConfigFrom UUID))], [(UUID, RemoteConfig, Maybe (ConfigFrom UUID))])
+findExisting' name = do
t <- trustMap
- headMaybe
- . sortBy (comparing $ \(u, _, _) -> Down $ M.lookup u t)
+ partition (\(u, _, _) -> M.lookup u t /= Just DeadTrusted)
. findByRemoteConfig (\c -> lookupName c == Just name)
<$> Logs.Remote.remoteConfigMap
* export: When a non-annexed symlink is in the tree to be exported, skip it.
* import: When the previously exported tree contained a non-annexed symlink,
preserve it in the imported tree so it does not get deleted.
+ * enableremote: Better handling of the unusual case where
+ multiple special remotes have been initialized with the same name.
-- Joey Hess <id@joeyh.name> Mon, 03 Jan 2022 14:01:14 -0400
start (name:rest) = go =<< filter matchingname <$> Annex.getGitRemotes
where
matchingname r = Git.remoteName r == Just name
- go [] = startSpecialRemote name (Logs.Remote.keyValToConfig Proposed rest)
- =<< SpecialRemote.findExisting name
+ go [] =
+ let use = startSpecialRemote name (Logs.Remote.keyValToConfig Proposed rest)
+ in SpecialRemote.findExisting' name >>= \case
+ -- enable dead remote only when there is no
+ -- other remote with the same name
+ ([], l) -> use l
+ (l, _) -> use l
go (r:_) = do
-- This could be either a normal git remote or a special
-- remote that has an url (eg gcrypt).
ai = ActionItemOther (Just name)
si = SeekInput [name]
-startSpecialRemote :: Git.RemoteName -> Remote.RemoteConfig -> Maybe (UUID, Remote.RemoteConfig, Maybe (SpecialRemote.ConfigFrom UUID)) -> CommandStart
-startSpecialRemote name config Nothing = do
+startSpecialRemote :: Git.RemoteName -> Remote.RemoteConfig -> [(UUID, Remote.RemoteConfig, Maybe (SpecialRemote.ConfigFrom UUID))] -> CommandStart
+startSpecialRemote name config [] = do
m <- SpecialRemote.specialRemoteMap
confm <- Logs.Remote.remoteConfigMap
Remote.nameToUUID' name >>= \case
Right u | u `M.member` m ->
startSpecialRemote name config $
- Just (u, fromMaybe M.empty (M.lookup u confm), Nothing)
+ [(u, fromMaybe M.empty (M.lookup u confm), Nothing)]
_ -> unknownNameError "Unknown remote name."
-startSpecialRemote name config (Just (u, c, mcu)) =
+startSpecialRemote name config ((u, c, mcu):[]) =
starting "enableremote" ai si $ do
let fullconfig = config `M.union` c
t <- either giveup return (SpecialRemote.findType fullconfig)
where
ai = ActionItemOther (Just name)
si = SeekInput [name]
+startSpecialRemote _ _ _ =
+ giveup "Multiple remotes have that name. Either use git-annex renameremote to rename them, or specify the uuid of the remote to enable."
performSpecialRemote :: RemoteType -> UUID -> R.RemoteConfig -> R.RemoteConfig -> RemoteGitConfig -> Maybe (SpecialRemote.ConfigFrom UUID) -> CommandPerform
performSpecialRemote t u oldc c gc mcu = do