Skip to content
Browse files

Avoid ugly failure mode when moving content from a local repository t…

…hat is not available.

Prelude.undefined error message was introduced by
bb4f31a.

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".
  • Loading branch information...
1 parent a7b8c80 commit 7e62e57f8c9ea49250399f385ee898667df80800 @joeyh committed
Showing with 51 additions and 35 deletions.
  1. +5 −0 Git.hs
  2. +1 −1 Remote.hs
  3. +41 −34 Remote/Git.hs
  4. +2 −0 debian/changelog
  5. +2 −0 doc/bugs/undefined.mdwn
View
5 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
View
2 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
View
75 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'
-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
+repoCheap :: Git.Repo -> Bool
+repoCheap = not . Git.repoIsUrl
- 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 :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex 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. -}
View
2 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 <joeyh@debian.org> Mon, 25 Jun 2012 11:38:12 -0400
View
2 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]]

0 comments on commit 7e62e57

Please sign in to comment.
Something went wrong with that request. Please try again.