summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Git/Config.hs9
-rw-r--r--GitAnnexShell.hs2
-rw-r--r--Remote/GCrypt.hs61
3 files changed, 50 insertions, 22 deletions
diff --git a/Git/Config.hs b/Git/Config.hs
index 513c3e5a6..db795b7a7 100644
--- a/Git/Config.hs
+++ b/Git/Config.hs
@@ -168,3 +168,12 @@ fromPipe r cmd params = try $
where
p = proc cmd $ toCommand params
+{- Reads git config from a specified file and returns the repo populated
+ - with the configuration. -}
+fromFile :: Repo -> FilePath -> IO (Either SomeException (Repo, String))
+fromFile r f = fromPipe r "git"
+ [ Param "config"
+ , Param "--file"
+ , File f
+ , Param "--list"
+ ]
diff --git a/GitAnnexShell.hs b/GitAnnexShell.hs
index 4133d6211..c34b3b307 100644
--- a/GitAnnexShell.hs
+++ b/GitAnnexShell.hs
@@ -61,7 +61,7 @@ options = Option.common ++
check u | u == toUUID expected = noop
check NoUUID = checkGCryptUUID expected
check u = unexpectedUUID expected u
- checkGCryptUUID expected = inRepo getGCryptUUID >>= check
+ checkGCryptUUID expected = check =<< getGCryptUUID True =<< gitRepo
where
check (Just u) | u == toUUID expected = noop
check Nothing = unexpected expected "uninitialized repository"
diff --git a/Remote/GCrypt.hs b/Remote/GCrypt.hs
index fe0632943..5a66cbdeb 100644
--- a/Remote/GCrypt.hs
+++ b/Remote/GCrypt.hs
@@ -40,6 +40,7 @@ import Annex.UUID
import Annex.Ssh
import qualified Remote.Rsync
import Utility.Rsync
+import Utility.Tmp
import Logs.Remote
import Logs.Transfer
import Utility.Gpg
@@ -61,9 +62,9 @@ gen gcryptr u c gc = do
-- get underlying git repo with real path, not gcrypt path
r <- liftIO $ Git.GCrypt.encryptedRemote g gcryptr
let r' = r { Git.remoteName = Git.remoteName gcryptr }
- (mgcryptid, r'') <- liftIO $ getGCryptId r'
- -- doublecheck that local cache matches underlying repo's gcrypt-id
- -- (which might not be set)
+ -- doublecheck that cache matches underlying repo's gcrypt-id
+ -- (which might not be set), only for local repos
+ (mgcryptid, r'') <- getGCryptId True r'
case (mgcryptid, Git.GCrypt.remoteRepoId g (Git.remoteName gcryptr)) of
(Just gcryptid, Just cachedgcryptid)
| gcryptid /= cachedgcryptid -> resetup gcryptid r''
@@ -87,24 +88,6 @@ gen gcryptr u c gc = do
warning $ "not using unknown gcrypt repository pointed to by remote " ++ Git.repoDescribe r
return Nothing
-getGCryptUUID :: Git.Repo -> IO (Maybe UUID)
-getGCryptUUID r = (genUUIDInNameSpace gCryptNameSpace <$>) . fst
- <$> getGCryptId r
-
-coreGCryptId :: String
-coreGCryptId = "core.gcrypt-id"
-
-{- gcrypt repos set up by git-annex as special remotes have a
- - core.gcrypt-id setting in their config, which can be mapped back to
- - the remote's UUID. This only works for local repos.
- - (Also returns a version of input repo with its config read.) -}
-getGCryptId :: Git.Repo -> IO (Maybe Git.GCrypt.GCryptId, Git.Repo)
-getGCryptId r
- | Git.repoIsLocal r = do
- r' <- catchDefaultIO r $ Git.Config.read r
- return (Git.Config.getMaybe coreGCryptId r', r')
- | otherwise = return (Nothing, r)
-
gen' :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
gen' r u c gc = do
cst <- remoteCost gc $
@@ -374,3 +357,39 @@ toAccessMethod :: String -> AccessMethod
toAccessMethod "shell" = AccessShell
toAccessMethod _ = AccessDirect
+getGCryptUUID :: Bool -> Git.Repo -> Annex (Maybe UUID)
+getGCryptUUID fast r = (genUUIDInNameSpace gCryptNameSpace <$>) . fst
+ <$> getGCryptId fast r
+
+coreGCryptId :: String
+coreGCryptId = "core.gcrypt-id"
+
+{- gcrypt repos set up by git-annex as special remotes have a
+ - core.gcrypt-id setting in their config, which can be mapped back to
+ - the remote's UUID.
+ -
+ - In fast mode, only checks local repos. To check a remote repo,
+ - tries git-annex-shell and direct rsync of the git config file.
+ -
+ - (Also returns a version of input repo with its config read.) -}
+getGCryptId :: Bool -> Git.Repo -> Annex (Maybe Git.GCrypt.GCryptId, Git.Repo)
+getGCryptId fast r
+ | Git.repoIsLocal r = extract
+ =<< liftIO (catchDefaultIO r $ Git.Config.read r)
+ | not fast = do
+ fromshell <- Ssh.onRemote r (Git.Config.fromPipe r, Left undefined) "configlist" [] []
+ case fromshell of
+ Right (r', _) -> extract r'
+ Left _ -> do
+ (rsynctransport, rsyncurl, _) <- rsyncTransport r
+ fromrsync <- liftIO $ do
+ withTmpFile "tmpconfig" $ \tmpconfig _ -> do
+ void $ rsync $ rsynctransport ++
+ [ Param $ rsyncurl ++ "/config"
+ , Param tmpconfig
+ ]
+ Git.Config.fromFile r tmpconfig
+ extract $ either (const r) fst fromrsync
+ | otherwise = return (Nothing, r)
+ where
+ extract r' = return (Git.Config.getMaybe coreGCryptId r', r')