add git config lookups for annex.name, annex.backends, etc

This commit is contained in:
Joey Hess 2010-10-11 00:19:38 -04:00
parent c5d7ca0a5a
commit 2bd3eea031
5 changed files with 75 additions and 16 deletions

View file

@ -18,20 +18,38 @@ import LocationLog
startAnnex :: IO State startAnnex :: IO State
startAnnex = do startAnnex = do
r <- currentRepo r <- currentRepo
config <- getConfig r
gitPrep r gitPrep r
-- TODO query git repo for configuration return State {
return State { repo = r, backends = supportedBackends } repo = r,
gitconfig = config
}
{- Query the git repo for relevant configuration settings. -}
getConfig :: GitRepo -> IO GitConfig
getConfig repo = do
-- a name can be configured, if none is, use the repository path
name <- gitConfigGet "annex.name" (top repo)
-- default number of copies to keep of file contents is 1
numcopies <- gitConfigGet "annex.numcopies" "1"
backends <- gitConfigGet "annex.backends" ""
return GitConfig {
annex_name = name,
annex_numcopies = read numcopies,
annex_backends = parseBackendList backends
}
{- Annexes a file, storing it in a backend, and then moving it into {- Annexes a file, storing it in a backend, and then moving it into
- the annex directory and setting up the symlink pointing to its content. -} - the annex directory and setting up the symlink pointing to its content. -}
annexFile :: State -> FilePath -> IO () annexFile :: State -> FilePath -> IO ()
annexFile state file = do annexFile state file = do
alreadyannexed <- lookupBackend (backends state) (repo state) file alreadyannexed <- lookupBackend backends (repo state) file
case (alreadyannexed) of case (alreadyannexed) of
Just _ -> error $ "already annexed: " ++ file Just _ -> error $ "already annexed: " ++ file
Nothing -> do Nothing -> do
checkLegal file checkLegal file
stored <- storeFile (backends state) (repo state) file stored <- storeFile (annex_backends $ gitconfig state) (repo state) file
case (stored) of case (stored) of
Nothing -> error $ "no backend could store: " ++ file Nothing -> error $ "no backend could store: " ++ file
Just key -> symlink key Just key -> symlink key
@ -47,15 +65,16 @@ annexFile state file = do
if ((isSymbolicLink s) || (not $ isRegularFile s)) if ((isSymbolicLink s) || (not $ isRegularFile s))
then error $ "not a regular file: " ++ file then error $ "not a regular file: " ++ file
else return () else return ()
backends = annex_backends $ gitconfig state
{- Inverse of annexFile. -} {- Inverse of annexFile. -}
unannexFile :: State -> FilePath -> IO () unannexFile :: State -> FilePath -> IO ()
unannexFile state file = do unannexFile state file = do
alreadyannexed <- lookupBackend (backends state) (repo state) file alreadyannexed <- lookupBackend backends (repo state) file
case (alreadyannexed) of case (alreadyannexed) of
Nothing -> error $ "not annexed " ++ file Nothing -> error $ "not annexed " ++ file
Just _ -> do Just _ -> do
mkey <- dropFile (backends state) (repo state) file mkey <- dropFile backends (repo state) file
case (mkey) of case (mkey) of
Nothing -> return () Nothing -> return ()
Just key -> do Just key -> do
@ -63,6 +82,8 @@ unannexFile state file = do
removeFile file removeFile file
renameFile src file renameFile src file
return () return ()
where
backends = annex_backends $ gitconfig state
{- Sets up a git repo for git-annex. May be called repeatedly. -} {- Sets up a git repo for git-annex. May be called repeatedly. -}
gitPrep :: GitRepo -> IO () gitPrep :: GitRepo -> IO ()

View file

@ -4,6 +4,7 @@
module BackendList where module BackendList where
-- When adding a new backend, import it here and add it to the list. -- When adding a new backend, import it here and add it to the list.
import Types
import qualified BackendFile import qualified BackendFile
import qualified BackendChecksum import qualified BackendChecksum
import qualified BackendUrl import qualified BackendUrl
@ -12,3 +13,20 @@ supportedBackends =
, BackendChecksum.backend , BackendChecksum.backend
, BackendUrl.backend , BackendUrl.backend
] ]
{- Parses a string with a list of backend names into
- a list of Backend objects. If the list is empty,
- defaults to supportedBackends. -}
parseBackendList :: String -> [Backend]
parseBackendList s =
if (length s == 0)
then supportedBackends
else map (lookupBackendName) $ words s
{- Looks up a supported backed by name. -}
lookupBackendName :: String -> Backend
lookupBackendName s =
if ((length matches) /= 1)
then error $ "unknown backend " ++ s
else matches !! 0
where matches = filter (\b -> s == name b) supportedBackends

View file

@ -5,7 +5,10 @@ module GitRepo where
import Directory import Directory
import System.Directory import System.Directory
import System.Path import System.Path
import System.Cmd.Utils
import System.IO
import Data.String.Utils import Data.String.Utils
import Control.Exception
import Utility import Utility
import Types import Types
@ -14,11 +17,9 @@ gitRepo :: FilePath -> IO GitRepo
gitRepo dir = do gitRepo dir = do
b <- isBareRepo dir b <- isBareRepo dir
-- TOOD query repo for configuration settings; other repositories; etc
return GitRepo { return GitRepo {
top = dir, top = dir,
bare = b, bare = b
remotes = []
} }
{- Path to a repository's gitattributes file. -} {- Path to a repository's gitattributes file. -}
@ -53,10 +54,19 @@ gitRelative repo file = drop (length absrepo) absfile
Nothing -> error $ file ++ " is not located inside git repository " ++ absrepo Nothing -> error $ file ++ " is not located inside git repository " ++ absrepo
{- Stages a changed file in git's index. -} {- Stages a changed file in git's index. -}
gitAdd :: GitRepo -> FilePath -> IO ()
gitAdd repo file = do gitAdd repo file = do
-- TODO -- TODO
return () return ()
{- Queries git-config. -}
gitConfigGet :: String -> String -> IO String
gitConfigGet name defaultValue =
handle ((\_ -> return defaultValue)::SomeException -> IO String) $
pOpen ReadFromPipe "git" ["config", "--get", name] $ \h -> do
ret <- hGetLine h
return ret
{- Finds the current git repository, which may be in a parent directory. -} {- Finds the current git repository, which may be in a parent directory. -}
currentRepo :: IO GitRepo currentRepo :: IO GitRepo
currentRepo = do currentRepo = do

View file

@ -23,12 +23,17 @@ data Backend = Backend {
-- a git repository -- a git repository
data GitRepo = GitRepo { data GitRepo = GitRepo {
top :: FilePath, top :: FilePath,
bare :: Bool, bare :: Bool
remotes :: [GitRepo]
} }
-- git-annex's runtime state -- git-annex's runtime state
data State = State { data State = State {
repo :: GitRepo, repo :: GitRepo,
backends :: [Backend] gitconfig :: GitConfig
}
data GitConfig = GitConfig {
annex_name :: String,
annex_numcopies :: Int,
annex_backends :: [Backend]
} }

View file

@ -124,8 +124,9 @@ so the lines may be in arbitrary order, but it will never conflict.)
## configuration ## configuration
* `annex.numcopies` -- number of copies of files to keep * `annex.numcopies` -- number of copies of files to keep
* `annex.backend` -- name of the default key/value backend to use to * `annex.backends` -- space-separated list of names of
store new files the key/value backends to use. The first listed is used to store
new files.
* `annex.name` -- allows specifying a unique name for this repository. * `annex.name` -- allows specifying a unique name for this repository.
If not specified, the name is derived from its directory's location and If not specified, the name is derived from its directory's location and
the hostname. When a repository is on removable media it is useful to give the hostname. When a repository is on removable media it is useful to give
@ -145,11 +146,15 @@ If the symlink to annexed content is relative, moving it to a subdir will
break it. But it it's absolute, moving the git repo (or mounting its drive break it. But it it's absolute, moving the git repo (or mounting its drive
elsewhere) will break it. Either: elsewhere) will break it. Either:
* Use relative links and need `git annex mv` to move (or post-commit * Use relative links and need `git annex --mv` to move (or post-commit
hook that caches moves and updates links). hook that caches moves and updates links).
* Use absolute links and need `git annex fixlinks` when location changes; * Use absolute links and need `git annex fixlinks` when location changes;
note that would also mean that git would see the symlink targets changed note that would also mean that git would see the symlink targets changed
and want to commit the change. and want to commit the change. And, other clones of the repo would
diverge and there would be conflicts on the symlink text. Ugh.
Hard links are not an option, because git would then happily commit the
file content. Amoung other reasons..
### free space determination ### free space determination