From 7e62e57f8c9ea49250399f385ee898667df80800 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 26 Jun 2012 17:15:17 -0400 Subject: [PATCH] Avoid ugly failure mode when moving content from a local repository that is not available. Prelude.undefined error message was introduced by bb4f31a0ee496ffb83d31cc56f8827e47605d763. 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". --- Git.hs | 5 +++ Remote.hs | 2 +- Remote/Git.hs | 75 ++++++++++++++++++++++------------------- debian/changelog | 2 ++ doc/bugs/undefined.mdwn | 2 ++ 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/Git.hs b/Git.hs index 7d64205634..eab33f19d7 100644 --- a/Git.hs +++ b/Git.hs @@ -19,6 +19,7 @@ module Git ( repoIsHttp, repoIsLocal, repoIsLocalBare, + repoIsLocalUnknown, repoDescribe, repoLocation, repoPath, @@ -99,6 +100,10 @@ repoIsLocalBare :: Repo -> Bool repoIsLocalBare Repo { location = Local { worktree = Nothing } } = True repoIsLocalBare _ = False +repoIsLocalUnknown :: Repo -> Bool +repoIsLocalUnknown Repo { location = LocalUnknown { } } = True +repoIsLocalUnknown _ = False + assertLocal :: Repo -> a -> a assertLocal repo action | repoIsUrl repo = error $ unwords diff --git a/Remote.hs b/Remote.hs index 839c6ddb09..e211ef7cb6 100644 --- a/Remote.hs +++ b/Remote.hs @@ -75,7 +75,7 @@ byName' :: String -> Annex (Either String Remote) byName' "" = return $ Left "no remote specified" byName' n = handle . filter matching <$> remoteList 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 matching r = n == name r || toUUID n == uuid r diff --git a/Remote/Git.hs b/Remote/Git.hs index cf7542d74e..df74a769c2 100644 --- a/Remote/Git.hs +++ b/Remote/Git.hs @@ -42,7 +42,8 @@ remote = RemoteType { list :: Annex [Git.Repo] list = do c <- fromRepo Git.config - mapM (tweakurl c) =<< fromRepo Git.remotes + rs <- mapM (tweakurl c) =<< fromRepo Git.remotes + catMaybes <$> mapM configread rs where annexurl n = "remote." ++ n ++ ".annexurl" tweakurl c r = do @@ -52,41 +53,47 @@ list = do Just url -> inRepo $ \g -> Git.Construct.remoteNamed n $ Git.Construct.fromRemoteLocation url g + {- It's assumed to be cheap to read the config of non-URL + - remotes, so this is done each time git-annex is run + - in a way that uses remotes. + - Conversely, the config of an URL remote is only read + - when there is no cached UUID value. -} + configread r = do + notignored <- repoNotIgnored r + u <- getRepoUUID r + r' <- case (repoCheap r, notignored, u) of + (_, False, _) -> return r + (True, _, _) -> tryGitConfigRead r + (False, _, NoUUID) -> tryGitConfigRead 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' + +repoCheap :: Git.Repo -> Bool +repoCheap = not . Git.repoIsUrl gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote -gen r u _ = do - {- It's assumed to be cheap to read the config of non-URL remotes, - - so this is done each time git-annex is run. Conversely, - - the config of an URL remote is only read when there is no - - cached UUID value. -} - let cheap = not $ Git.repoIsUrl r - notignored <- repoNotIgnored r - r' <- case (cheap, notignored, u) of - (_, False, _) -> return r - (True, _, _) -> tryGitConfigRead r - (False, _, NoUUID) -> tryGitConfigRead r - _ -> return r - - u' <- getRepoUUID r' - - let defcst = if cheap then cheapRemoteCost else expensiveRemoteCost - cst <- remoteCost r' defcst - - return Remote { - uuid = u', - cost = cst, - name = Git.repoDescribe r', - storeKey = copyToRemote r', - retrieveKeyFile = copyFromRemote r', - retrieveKeyFileCheap = copyFromRemoteCheap r', - removeKey = dropKey r', - hasKey = inAnnex r', - hasKeyCheap = cheap, - whereisKey = Nothing, - config = Nothing, - repo = r', - remotetype = remote - } +gen r u _ = new <$> remoteCost r defcst + where + defcst = if repoCheap r then cheapRemoteCost else expensiveRemoteCost + new cst = Remote { + uuid = u, + cost = cst, + name = Git.repoDescribe r, + storeKey = copyToRemote r, + retrieveKeyFile = copyFromRemote r, + retrieveKeyFileCheap = copyFromRemoteCheap r, + removeKey = dropKey r, + hasKey = inAnnex r, + hasKeyCheap = repoCheap r, + whereisKey = Nothing, + config = Nothing, + repo = r, + remotetype = remote + } {- Tries to read the config for a specified remote, updates state, and - returns the updated repo. -} diff --git a/debian/changelog b/debian/changelog index 92e992ed75..59eb63b645 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,8 @@ git-annex (3.20120625) UNRELEASED; urgency=low * cabal: Only try to use inotify on Linux. * Version build dependency on STM, and allow building without it, which disables the watch command. + * Avoid ugly failure mode when moving content from a local repository + that is not available. -- Joey Hess Mon, 25 Jun 2012 11:38:12 -0400 diff --git a/doc/bugs/undefined.mdwn b/doc/bugs/undefined.mdwn index 3c157424c4..8ee37f034a 100644 --- a/doc/bugs/undefined.mdwn +++ b/doc/bugs/undefined.mdwn @@ -1,3 +1,5 @@ Trying to move files from a local remote that is not mounted: git-annex: Prelude.undefined + +> [[fixed|done]] --[[Joey]]