Avoid ugly failure mode when moving content from a local repository that is not available.

Prelude.undefined error message was introduced by
bb4f31a0ee.

It seems best to filter out local repositories that cannot be accessed
from the list of remotes, rather than keeping them in and making every
thing that uses the list have to deal with remotes that may have an unknown
location.

Besides fixing the error message, this also makes unavailable local
remotes' names not be shown in various messages, including in git annex
status output.

Also, move --to an unavailable local repository now avoids some ugly
errors like "changeWorkingDirectory: does not exist".
This commit is contained in:
Joey Hess 2012-06-26 17:15:17 -04:00
parent a7b8c807d9
commit 7e62e57f8c
5 changed files with 51 additions and 35 deletions

5
Git.hs
View file

@ -19,6 +19,7 @@ module Git (
repoIsHttp, repoIsHttp,
repoIsLocal, repoIsLocal,
repoIsLocalBare, repoIsLocalBare,
repoIsLocalUnknown,
repoDescribe, repoDescribe,
repoLocation, repoLocation,
repoPath, repoPath,
@ -99,6 +100,10 @@ repoIsLocalBare :: Repo -> Bool
repoIsLocalBare Repo { location = Local { worktree = Nothing } } = True repoIsLocalBare Repo { location = Local { worktree = Nothing } } = True
repoIsLocalBare _ = False repoIsLocalBare _ = False
repoIsLocalUnknown :: Repo -> Bool
repoIsLocalUnknown Repo { location = LocalUnknown { } } = True
repoIsLocalUnknown _ = False
assertLocal :: Repo -> a -> a assertLocal :: Repo -> a -> a
assertLocal repo action assertLocal repo action
| repoIsUrl repo = error $ unwords | repoIsUrl repo = error $ unwords

View file

@ -75,7 +75,7 @@ byName' :: String -> Annex (Either String Remote)
byName' "" = return $ Left "no remote specified" byName' "" = return $ Left "no remote specified"
byName' n = handle . filter matching <$> remoteList byName' n = handle . filter matching <$> remoteList
where where
handle [] = Left $ "there is no git remote named \"" ++ n ++ "\"" handle [] = Left $ "there is no available git remote named \"" ++ n ++ "\""
handle match = Right $ Prelude.head match handle match = Right $ Prelude.head match
matching r = n == name r || toUUID n == uuid r matching r = n == name r || toUUID n == uuid r

View file

@ -42,7 +42,8 @@ remote = RemoteType {
list :: Annex [Git.Repo] list :: Annex [Git.Repo]
list = do list = do
c <- fromRepo Git.config c <- fromRepo Git.config
mapM (tweakurl c) =<< fromRepo Git.remotes rs <- mapM (tweakurl c) =<< fromRepo Git.remotes
catMaybes <$> mapM configread rs
where where
annexurl n = "remote." ++ n ++ ".annexurl" annexurl n = "remote." ++ n ++ ".annexurl"
tweakurl c r = do tweakurl c r = do
@ -52,39 +53,45 @@ list = do
Just url -> inRepo $ \g -> Just url -> inRepo $ \g ->
Git.Construct.remoteNamed n $ Git.Construct.remoteNamed n $
Git.Construct.fromRemoteLocation url g Git.Construct.fromRemoteLocation url g
{- It's assumed to be cheap to read the config of non-URL
gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote - remotes, so this is done each time git-annex is run
gen r u _ = do - in a way that uses remotes.
{- It's assumed to be cheap to read the config of non-URL remotes, - Conversely, the config of an URL remote is only read
- so this is done each time git-annex is run. Conversely, - when there is no cached UUID value. -}
- the config of an URL remote is only read when there is no configread r = do
- cached UUID value. -}
let cheap = not $ Git.repoIsUrl r
notignored <- repoNotIgnored r notignored <- repoNotIgnored r
r' <- case (cheap, notignored, u) of u <- getRepoUUID r
r' <- case (repoCheap r, notignored, u) of
(_, False, _) -> return r (_, False, _) -> return r
(True, _, _) -> tryGitConfigRead r (True, _, _) -> tryGitConfigRead r
(False, _, NoUUID) -> tryGitConfigRead r (False, _, NoUUID) -> tryGitConfigRead r
_ -> return r _ -> return r
{- A repo with a LocalUnknown location is not currently
- accessible, so skip it. -}
if Git.repoIsLocalUnknown r'
then return Nothing
else return $ Just r'
u' <- getRepoUUID r' repoCheap :: Git.Repo -> Bool
repoCheap = not . Git.repoIsUrl
let defcst = if cheap then cheapRemoteCost else expensiveRemoteCost gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote
cst <- remoteCost r' defcst gen r u _ = new <$> remoteCost r defcst
where
return Remote { defcst = if repoCheap r then cheapRemoteCost else expensiveRemoteCost
uuid = u', new cst = Remote {
uuid = u,
cost = cst, cost = cst,
name = Git.repoDescribe r', name = Git.repoDescribe r,
storeKey = copyToRemote r', storeKey = copyToRemote r,
retrieveKeyFile = copyFromRemote r', retrieveKeyFile = copyFromRemote r,
retrieveKeyFileCheap = copyFromRemoteCheap r', retrieveKeyFileCheap = copyFromRemoteCheap r,
removeKey = dropKey r', removeKey = dropKey r,
hasKey = inAnnex r', hasKey = inAnnex r,
hasKeyCheap = cheap, hasKeyCheap = repoCheap r,
whereisKey = Nothing, whereisKey = Nothing,
config = Nothing, config = Nothing,
repo = r', repo = r,
remotetype = remote remotetype = remote
} }

2
debian/changelog vendored
View file

@ -3,6 +3,8 @@ git-annex (3.20120625) UNRELEASED; urgency=low
* cabal: Only try to use inotify on Linux. * cabal: Only try to use inotify on Linux.
* Version build dependency on STM, and allow building without it, * Version build dependency on STM, and allow building without it,
which disables the watch command. which disables the watch command.
* Avoid ugly failure mode when moving content from a local repository
that is not available.
-- Joey Hess <joeyh@debian.org> Mon, 25 Jun 2012 11:38:12 -0400 -- Joey Hess <joeyh@debian.org> Mon, 25 Jun 2012 11:38:12 -0400

View file

@ -1,3 +1,5 @@
Trying to move files from a local remote that is not mounted: Trying to move files from a local remote that is not mounted:
git-annex: Prelude.undefined git-annex: Prelude.undefined
> [[fixed|done]] --[[Joey]]