let Remote.availability return Unavilable
authorJoey Hess <joeyh@joeyh.name>
Wed, 16 Aug 2023 18:31:31 +0000 (14:31 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 16 Aug 2023 18:31:31 +0000 (14:31 -0400)
This is groundwork for making special remotes like borg be skipped by
sync when on an offline drive.

Added AVAILABILITY UNAVAILABLE reponse and the UNAVAILABLERESPONSE extension
to the external special remote protocol. The extension is needed because
old git-annex, if it sees that response, will display a warning
message. (It does continue as if the remote is globally available, which
is acceptable, and the warning is only displayed at initremote due to
remote.name.annex-availability caching, but still it seemed best to make
this a protocol extension.)

The remote.name.annex-availability git config is no longer used any
more, and is documented as such. It was only used by external special
remotes to cache the availability, to avoid needing to start the
external process every time. Now that availability is queried as an
Annex action, the external is only started by sync (and the assistant),
when they actually check availability.

Sponsored-by: Nicholas Golder-Manning on Patreon
28 files changed:
Assistant/DaemonStatus.hs
CHANGELOG
Command/Sync.hs
Remote/Adb.hs
Remote/BitTorrent.hs
Remote/Borg.hs
Remote/Bup.hs
Remote/Ddar.hs
Remote/Directory.hs
Remote/External.hs
Remote/External/Types.hs
Remote/GCrypt.hs
Remote/Git.hs
Remote/GitLFS.hs
Remote/Glacier.hs
Remote/Hook.hs
Remote/HttpAlso.hs
Remote/P2P.hs
Remote/Rsync.hs
Remote/S3.hs
Remote/Tahoe.hs
Remote/Web.hs
Remote/WebDAV.hs
Types/Availability.hs
Types/GitConfig.hs
Types/Remote.hs
doc/design/external_special_remote_protocol.mdwn
doc/git-annex.mdwn

index 1dbb27fd4e05e60d15a75fac28927703b6b6fa4f..9be4558761d367e6c38a0d66cb3f89622f370ff9 100644 (file)
@@ -13,6 +13,7 @@ import Assistant.Common
 import Assistant.Alert.Utility
 import Utility.Tmp
 import Utility.NotificationBroadcaster
+import Types.Availability
 import Types.Transfer
 import Logs.Transfer
 import Logs.Trust
@@ -59,6 +60,7 @@ calcSyncRemotes = do
        let (exportremotes, nonexportremotes) = partition (exportTree . Remote.config) contentremotes
        let isimport r = importTree (Remote.config r) || Remote.thirdPartyPopulated (Remote.remotetype r)
        let dataremotes = filter (not . isimport) nonexportremotes
+       tocloud <- anyM iscloud contentremotes
 
        return $ \dstatus -> dstatus
                { syncRemotes = syncable
@@ -66,10 +68,14 @@ calcSyncRemotes = do
                , syncDataRemotes = dataremotes
                , exportRemotes = exportremotes
                , downloadRemotes = contentremotes
-               , syncingToCloudRemote = any iscloud contentremotes
+               , syncingToCloudRemote = tocloud
                }
   where
-       iscloud r = not (Remote.readonly r) && Remote.availability r == Remote.GloballyAvailable
+       iscloud r
+               | Remote.readonly r = pure False
+               | otherwise = tryNonAsync (Remote.availability r) >>= return . \case
+                       Right GloballyAvailable -> True
+                       _ -> False
 
 {- Updates the syncRemotes list from the list of all remotes in Annex state. -}
 updateSyncRemotes :: Assistant ()
index 2282356058463f5fffd64d80445c0b4b3881481e..56b6e138e9bf9a989346eb296a5c0571ea64a374 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,11 @@ git-annex (10.20230803) UNRELEASED; urgency=medium
     directory does not exist. An empty tree was imported, rather than the
     import failing.
   * Stop bundling curl in the OSX dmg and linux standalone image.
+  * sync, assist, push, pull: Skip more types of remotes when they
+    are not present due to eg being on a drive that is offline.
+  * Added AVAILABILITY UNAVAILABLE and the UNAVAILABLERESPONSE extension
+    to the external special remote protocol.
+  * The remote.name.annex-availability git config is no longer used.
 
  -- Joey Hess <id@joeyh.name>  Mon, 07 Aug 2023 13:04:13 -0400
 
index 0d6e0c143f2ced2e1dd50252e2edcec5d102c734..44edf2142a0e34c698a5f952c290c7c8497d1965 100644 (file)
@@ -78,6 +78,7 @@ import Annex.Import
 import Annex.CheckIgnore
 import Types.FileMatcher
 import Types.GitConfig
+import Types.Availability
 import qualified Database.Export as Export
 import Utility.Bloom
 import Utility.OptParse
@@ -388,10 +389,9 @@ syncRemotes' ps available =
        
        listed = concat <$> mapM Remote.byNameOrGroup ps
        
-       good r
-               | Remote.gitSyncableRemoteType (Remote.remotetype r) =
-                       Remote.Git.repoAvail =<< Remote.getRepo r
-               | otherwise = return True
+       good r = tryNonAsync (Remote.availability r) >>= return . \case
+               Right Unavailable -> False
+               _ -> True
        
        fastest = fromMaybe [] . headMaybe . Remote.byCost
 
index f70fe27bdf68eabac20a9a0ab131c2e3e487d5cb..7d4e38696a6a3898d5313b61f53835c02e01d1d0 100644 (file)
@@ -113,7 +113,7 @@ gen r u rc gc rs = do
                , gitconfig = gc
                , localpath = Nothing
                , remotetype = remote
-               , availability = LocallyAvailable
+               , availability = pure LocallyAvailable
                , readonly = False
                , appendonly = False
                , untrustworthy = False
index dcc6f2900408ed346ba26543e84c58007a5fe2df..ccc67a25d0605f237ec9d24045b4b04f81264ecb 100644 (file)
@@ -88,7 +88,7 @@ gen r _ rc gc rs = do
                , readonly = True
                , appendonly = False
                , untrustworthy = False
-               , availability = GloballyAvailable
+               , availability = pure GloballyAvailable
                , remotetype = remote
                , mkUnavailable = return Nothing
                , getInfo = return []
index d3b152c8020d0d6369cf1ea4358c9ef07eafd620..ba22c8cf59a506554dafadad0729e01cb3e31378 100644 (file)
@@ -112,7 +112,8 @@ gen r u rc gc rs = do
                , gitconfig = gc
                , localpath = borgRepoLocalPath borgrepo
                , remotetype = remote
-               , availability = if borgLocal borgrepo then LocallyAvailable else GloballyAvailable
+               , availability = pure $
+                       if borgLocal borgrepo then LocallyAvailable else GloballyAvailable
                , readonly = False
                , appendonly = False
                -- When the user sets the appendonly field, they are
index 8bcacf9b94846821d6744af9fd0ab7e267751481..c754850e22217f2f97f50e0b49152dc7a8122a72 100644 (file)
@@ -97,7 +97,8 @@ gen r u rc gc rs = do
                        then Just buprepo
                        else Nothing
                , remotetype = remote
-               , availability = if bupLocal buprepo then LocallyAvailable else GloballyAvailable
+               , availability = pure $
+                       if bupLocal buprepo then LocallyAvailable else GloballyAvailable
                , readonly = False
                , appendonly = False
                , untrustworthy = False
index 3fc3fdbafbff8777971442371e9877e4cdcc6714..375920a325c50c2b6c8439bbdc140a469f335d54 100644 (file)
@@ -98,7 +98,8 @@ gen r u rc gc rs = do
                        then Just $ ddarRepoLocation ddarrepo
                        else Nothing
                , remotetype = remote
-               , availability = if ddarLocal ddarrepo then LocallyAvailable else GloballyAvailable
+               , availability = pure $
+                       if ddarLocal ddarrepo then LocallyAvailable else GloballyAvailable
                , readonly = False
                , appendonly = False
                , untrustworthy = False
index d234ff59cbac119f1133d3292ebecec3f0888877..b030bb2c464da6a64e4425f0a1363ed7d2b60ca7 100644 (file)
@@ -134,7 +134,7 @@ gen r u rc gc rs = do
                        , readonly = False
                        , appendonly = False
                        , untrustworthy = False
-                       , availability = LocallyAvailable
+                       , availability = pure LocallyAvailable
                        , remotetype = remote
                        , mkUnavailable = gen r u rc
                                (gc { remoteAnnexDirectory = Just "/dev/null" }) rs
index c429dc80fa1cf6fcda072cb8dc960a5924c5231c..22a9a61d32614fea187f24ae20ed0e2970265b5c 100644 (file)
@@ -68,7 +68,7 @@ gen r u rc gc rs
        | externaltype == "readonly" = do
                c <- parsedRemoteConfig remote rc
                cst <- remoteCost gc c expensiveRemoteCost
-               let rmt = mk c cst GloballyAvailable
+               let rmt = mk c cst (pure GloballyAvailable)
                        Nothing
                        (externalInfo externaltype)
                        Nothing
@@ -87,7 +87,6 @@ gen r u rc gc rs
                        (Git.remoteName r) (Just rs)
                Annex.addCleanupAction (RemoteCleanup u) $ stopExternal external
                cst <- getCost external r gc c
-               avail <- getAvailability external r gc
                exportsupported <- if exportTree c
                        then checkExportSupported' external
                        else return False
@@ -107,7 +106,7 @@ gen r u rc gc rs
                let cheapexportsupported = if exportsupported
                        then exportIsSupported
                        else exportUnsupported
-               let rmt = mk c cst avail
+               let rmt = mk c cst (getAvailability external)
                        (Just (whereisKeyM external))
                        (getInfoM external)
                        (Just (claimUrlM external))
@@ -777,25 +776,16 @@ getCost external r gc pc =
                return c
        defcst = expensiveRemoteCost
 
-{- Caches the availability in the git config to avoid needing to start up an
- - external special remote every time time just to ask it what its
- - availability is.
- -
- - Most remotes do not bother to implement a reply to this request;
+{- Most remotes do not bother to implement a reply to this request;
  - globally available is the default.
  -}
-getAvailability :: External -> Git.Repo -> RemoteGitConfig -> Annex Availability
-getAvailability external r gc = 
-       maybe (catchNonAsync query (const (pure defavail))) return
-               (remoteAnnexAvailability gc)
+getAvailability :: External -> Annex Availability
+getAvailability external = catchNonAsync query (const (pure defavail))
   where
-       query = do
-               avail <- handleRequest external GETAVAILABILITY Nothing $ \req -> case req of
-                       AVAILABILITY avail -> result avail
-                       UNSUPPORTED_REQUEST -> result defavail
-                       _ -> Nothing
-               setRemoteAvailability r avail
-               return avail
+       query = handleRequest external GETAVAILABILITY Nothing $ \req -> case req of
+               AVAILABILITY avail -> result avail
+               UNSUPPORTED_REQUEST -> result defavail
+               _ -> Nothing
        defavail = GloballyAvailable
 
 claimUrlM :: External -> URLString -> Annex Bool
index ed8aa20346ea2245fe3d3a2f9e180045209af030..1ee29ebd6c4ab6df4c57a08182b8eea4980541cb 100644 (file)
@@ -110,6 +110,7 @@ supportedExtensionList :: ExtensionList
 supportedExtensionList = ExtensionList
        [ "INFO"
        , "GETGITREMOTENAME"
+       , "UNAVAILABLERESPONSE"
        , asyncExtension
        ]
 
@@ -447,9 +448,11 @@ instance Proto.Serializable Size where
 instance Proto.Serializable Availability where
        serialize GloballyAvailable = "GLOBAL"
        serialize LocallyAvailable = "LOCAL"
+       serialize Unavailable = "UNAVAILABLE"
 
        deserialize "GLOBAL" = Just GloballyAvailable
        deserialize "LOCAL" = Just LocallyAvailable
+       deserialize "UNAVAILABLE" = Just Unavailable
        deserialize _ = Nothing
 
 instance Proto.Serializable [(URLString, Size, FilePath)] where
index 61e8b7210e2feb4e4022a25a92916fe175eb5610..bf8f01ed3ed9ecba77f7f4aaba84d11186d36ae3 100644 (file)
@@ -158,7 +158,7 @@ gen' r u c gc rs = do
                , readonly = Git.repoIsHttp r
                , appendonly = False
                , untrustworthy = False
-               , availability = availabilityCalc r
+               , availability = pure (availabilityCalc r)
                , remotetype = remote
                , mkUnavailable = return Nothing
                , getInfo = gitRepoInfo this
index 387fb9d4f0a15d21d097fddf6b161c6ba1721b9c..d4708e40fa842b245ade15718991c201cf62440c 100644 (file)
@@ -1,6 +1,6 @@
 {- Standard git remotes.
  -
- - Copyright 2011-2021 Joey Hess <id@joeyh.name>
+ - Copyright 2011-2023 Joey Hess <id@joeyh.name>
  -
  - Licensed under the GNU AGPL version 3 or higher.
  -}
@@ -11,7 +11,6 @@
 module Remote.Git (
        remote,
        configRead,
-       repoAvail,
        onLocalRepo,
 ) where
 
@@ -210,7 +209,7 @@ gen r u rc gc rs
                        , readonly = Git.repoIsHttp r
                        , appendonly = False
                        , untrustworthy = False
-                       , availability = availabilityCalc r
+                       , availability = repoAvail r
                        , remotetype = remote
                        , mkUnavailable = unavailable r u rc gc rs
                        , getInfo = gitRepoInfo new
@@ -233,20 +232,24 @@ unavailable r = gen r'
                _ -> r -- already unavailable
 
 {- Checks relatively inexpensively if a repository is available for use. -}
-repoAvail :: Git.Repo -> Annex Bool
+repoAvail :: Git.Repo -> Annex Availability
 repoAvail r 
-       | Git.repoIsHttp r = return True
+       | Git.repoIsHttp r = return GloballyAvailable
        | Git.GCrypt.isEncrypted r = do
                g <- gitRepo
                liftIO $ do
                        er <- Git.GCrypt.encryptedRemote g r
                        if Git.repoIsLocal er || Git.repoIsLocalUnknown er
-                               then catchBoolIO $
-                                       void (Git.Config.read er) >> return True
-                               else return True
-       | Git.repoIsUrl r = return True
-       | Git.repoIsLocalUnknown r = return False
-       | otherwise = liftIO $ isJust <$> catchMaybeIO (Git.Config.read r)
+                               then checklocal er
+                               else return GloballyAvailable
+       | Git.repoIsUrl r = return GloballyAvailable
+       | Git.repoIsLocalUnknown r = return Unavailable
+       | otherwise = checklocal r
+  where
+       checklocal r' = ifM (liftIO $ isJust <$> catchMaybeIO (Git.Config.read r'))
+               ( return LocallyAvailable
+               , return Unavailable
+               )
 
 {- Tries to read the config for a specified remote, updates state, and
  - returns the updated repo. -}
index fc3459f46fb5676628be4e922af529bedb6931b6..31ddc6ccef9cf93b934679cfef760447eb5883c8 100644 (file)
@@ -130,7 +130,7 @@ gen r u rc gc rs = do
                , gitconfig = gc
                , localpath = Nothing
                , remotetype = remote
-               , availability = GloballyAvailable
+               , availability = pure GloballyAvailable
                , readonly = False
                -- content cannot be removed from a git-lfs repo
                , appendonly = True
index e97ad12da4d9ac6cd1847c903b98c87798a9170d..18bd65f21b8f06d71160d461ebfe1a8dc769c809 100644 (file)
@@ -103,7 +103,7 @@ gen r u rc gc rs = do
                        , readonly = False
                        , appendonly = False
                        , untrustworthy = False
-                       , availability = GloballyAvailable
+                       , availability = pure GloballyAvailable
                        , remotetype = remote
                        , mkUnavailable = return Nothing
                        , getInfo = includeCredsInfo c (AWS.creds u) $
index 49d72a8a6cdacbcda74fad7e30af2664f171b14f..a7dd3e659388abdc6e7e24a405a7ad5578d1435e 100644 (file)
@@ -82,7 +82,7 @@ gen r u rc gc rs = do
                        , readonly = False
                        , appendonly = False
                        , untrustworthy = False
-                       , availability = GloballyAvailable
+                       , availability = pure GloballyAvailable
                        , remotetype = remote
                        , mkUnavailable = gen r u rc
                                (gc { remoteAnnexHookType = Just "!dne!" })
index ff5a638cede0d950efd29d3e6edc42193df90e78..06003b7b54fc4ebfc39786750f1b369371dcd4b8 100644 (file)
@@ -95,7 +95,7 @@ gen r u rc gc rs = do
                , readonly = True
                , appendonly = False
                , untrustworthy = False
-               , availability = GloballyAvailable
+               , availability = pure GloballyAvailable
                , remotetype = remote
                , mkUnavailable = return Nothing
                , getInfo = return []
index a5fd926a36f10a162fcdbf15215532cd459b8582..4b47e2f489a70f85efba912dfe4691c5c4aa3a7c 100644 (file)
@@ -77,7 +77,7 @@ chainGen addr r u rc gc rs = do
                , readonly = False
                , appendonly = False
                , untrustworthy = False
-               , availability = GloballyAvailable
+               , availability = pure GloballyAvailable
                , remotetype = remote
                , mkUnavailable = return Nothing
                , getInfo = gitRepoInfo this
index c256fe678412a00b61560b362f2d86546c7cd877..b0fceeab24a09dab5be63fc2d433b1b8be8f5a3d 100644 (file)
@@ -120,7 +120,8 @@ gen r u rc gc rs = do
                        , readonly = False
                        , appendonly = False
                        , untrustworthy = False
-                       , availability = if islocal then LocallyAvailable else GloballyAvailable
+                       , availability = pure $
+                               if islocal then LocallyAvailable else GloballyAvailable
                        , remotetype = remote
                        , mkUnavailable = return Nothing
                        , getInfo = return [("url", url)]
index b96fc96dcb4a6e279bf221e3e6f2d951ce6b23f1..a2ab5a61ffc52e0f354a0747676df27f174bc0ae 100644 (file)
@@ -249,7 +249,7 @@ gen r u rc gc rs = do
                        , readonly = False
                        , appendonly = False
                        , untrustworthy = False
-                       , availability = GloballyAvailable
+                       , availability = pure GloballyAvailable
                        , remotetype = remote
                        , mkUnavailable = gen r u (M.insert hostField (Proposed "!dne!") rc) gc rs
                        , getInfo = includeCredsInfo c (AWS.creds u) (s3Info c info)
index d5b6a0902ef50936ce496f5b2a64204c0cd67b4e..7c2ad0c25a45c4563fd394fa9ae41d298efce923 100644 (file)
@@ -108,7 +108,7 @@ gen r u rc gc rs = do
                , readonly = False
                , appendonly = False
                , untrustworthy = False
-               , availability = GloballyAvailable
+               , availability = pure GloballyAvailable
                , remotetype = remote
                , mkUnavailable = return Nothing
                , getInfo = return []
index 4a1b7a61c343d3f214def5ae2ff20cc47838a162..b3b788d2dfa5414c6ca66ec3baacbb6dfd15da90 100644 (file)
@@ -93,7 +93,7 @@ gen r u rc gc rs = do
                , readonly = True
                , appendonly = False
                , untrustworthy = False
-               , availability = GloballyAvailable
+               , availability = pure GloballyAvailable
                , remotetype = remote
                , mkUnavailable = return Nothing
                , getInfo = return []
index e9e771d754547dc3f4177db736dc1d395aa0970f..08594dfba4759cad7563862f4ab1e9179b4eb541 100644 (file)
@@ -117,7 +117,7 @@ gen r u rc gc rs = do
                        , readonly = False
                        , appendonly = False
                        , untrustworthy = False
-                       , availability = GloballyAvailable
+                       , availability = pure GloballyAvailable
                        , remotetype = remote
                        , mkUnavailable = gen r u (M.insert urlField (Proposed "http://!dne!/") rc) gc rs
                        , getInfo = includeCredsInfo c (davCreds u) $
index 9e8bbf63b72aadccc4024492239dece374abe31b..3d3e6ac41607eed8b712290c620809b4bc833151 100644 (file)
@@ -7,5 +7,5 @@
 
 module Types.Availability where
 
-data Availability = GloballyAvailable | LocallyAvailable
-       deriving (Eq, Show, Read)
+data Availability = GloballyAvailable | LocallyAvailable | Unavailable
+       deriving (Eq, Show)
index 833db43c0f130494198b2d8c3cb60056cf1f14e0..13978e8338dacbf8c734b597271aa7eec8efb5e1 100644 (file)
@@ -37,7 +37,6 @@ import Utility.DataUnits
 import Config.Cost
 import Types.UUID
 import Types.Distribution
-import Types.Availability
 import Types.Concurrency
 import Types.NumCopies
 import Types.Difference
@@ -351,7 +350,6 @@ data RemoteGitConfig = RemoteGitConfig
        , remoteAnnexTrustLevel :: Maybe String
        , remoteAnnexStartCommand :: Maybe String
        , remoteAnnexStopCommand :: Maybe String
-       , remoteAnnexAvailability :: Maybe Availability
        , remoteAnnexSpeculatePresent :: Bool
        , remoteAnnexBare :: Maybe Bool
        , remoteAnnexRetry :: Maybe Integer
@@ -416,7 +414,6 @@ extractRemoteGitConfig r remotename = do
                , remoteAnnexTrustLevel = notempty $ getmaybe "trustlevel"
                , remoteAnnexStartCommand = notempty $ getmaybe "start-command"
                , remoteAnnexStopCommand = notempty $ getmaybe "stop-command"
-               , remoteAnnexAvailability = getmayberead "availability"
                , remoteAnnexSpeculatePresent = getbool "speculate-present" False
                , remoteAnnexBare = getmaybebool "bare"
                , remoteAnnexRetry = getmayberead "retry"
index 52b5adab6b6fbe1fee9c19838ccab11728c92bff..971c4a87c6a22e7c03c697dabe143b9182d699fa 100644 (file)
@@ -152,7 +152,8 @@ data RemoteA a = Remote
        -- decide.
        , untrustworthy :: Bool
        -- a Remote can be globally available. (Ie, "in the cloud".)
-       , availability :: Availability
+       -- Some Remotes can mark themselves unavailable.
+       , availability :: a Availability
        -- the type of the remote
        , remotetype :: RemoteTypeA a
        -- For testing, makes a version of this remote that is not
index d4bf6bcf3d3f8501990690cc44a0d04e009646ef..26a4a5185893718aa1113bf0bb9c66db5689bd3c 100644 (file)
@@ -45,7 +45,7 @@ Recent versions of git-annex respond with a message indicating
 protocol extensions that it supports. Older versions of
 git-annex do not send this message.
 
-       EXTENSIONS INFO ASYNC GETGITREMOTENAME
+       EXTENSIONS INFO ASYNC GETGITREMOTENAME UNAVAILABLERESPONSE
 
 The special remote can respond to that with its own EXTENSIONS message, listing
 any extensions it wants to use. 
@@ -207,9 +207,19 @@ the special remote can reply with `UNSUPPORTED-REQUEST`.
   (Ie stored in the cloud vs on a local disk.)  
   If the remote replies with `UNSUPPORTED-REQUEST`, its availability
   is assumed to be global. So, only remotes that are only reachable
-  locally need to worry about implementing this.
+  locally need to worry about implementing this.  
+  This is queried at remote startup, so should avoid doing anything that
+  can take long to run or is expensive. Checking if a directory where the
+  remote stores files is currently mounted is the kind of thing it makes
+  sense to do here.
   * `AVAILABILITY GLOBAL|LOCAL`  
     Indicates if the remote is globally or only locally available.
+  * `AVAILABILITY UNAVAILABLE`  
+    Indicates that the remote is not currently available.  
+    This will prevent some git-annex commands like `git-annex sync` from
+    trying to use the remote.  
+    Older versions of git-annex do not support this response, so avoid
+    sending it unless the `UNAVAILABLERESPONSE` extension is enabled.
 * `CLAIMURL Url`  
   Asks the remote if it wishes to claim responsibility for downloading
   an url.
@@ -445,13 +455,16 @@ avoid talking to the buggy old version of git-annex.
 These protocol extensions are currently supported.
 
 * `INFO`  
-  This makes the `INFO` message available to use.
+  This allows using the `INFO` message.
 * `ASYNC`  
   This lets multiple actions be performed at the same time by
   a single external special remote program, rather than starting multiple
   programs. See the [[async_appendix]] for details.
 * `GETGITREMOTENAME`  
-  This makes the `GETGITREMOTENAME` message available to use.
+  This allows using the `GETGITREMOTENAME` message.
+* `UNAVAILABLERESPONSE`  
+  This allows the `AVAILABILITY UNAVAILABLE` response to be used
+  in reply to `GETAVAILABILITY`.
 
 ## signals
 
index d8b73cf0b6748d7a27201b55464e2a21ff4d5246..b51e6dc8810510e70a1fc74fcdec024291c450f5 100644 (file)
@@ -1565,8 +1565,7 @@ Remotes are configured using these settings in `.git/config`.
 
 * `remote.<name>.annex-availability`
 
-  Can be used to tell git-annex whether a remote is LocallyAvailable
-  or GloballyAvailable. Normally, git-annex determines this automatically.
+  This configuration setting is no longer used.
 
 * `remote.<name>.annex-speculate-present`