got rid of the .git-annex/key.backend files

This commit is contained in:
Joey Hess 2010-10-13 00:42:46 -04:00
parent 9926fe5c8a
commit 208bba8d30
5 changed files with 52 additions and 65 deletions

View file

@ -25,8 +25,8 @@ import LocationLog
import Types import Types
{- Checks if a given key is currently present in the annexLocation -} {- Checks if a given key is currently present in the annexLocation -}
inAnnex :: State -> Key -> IO Bool inAnnex :: State -> Backend -> Key -> IO Bool
inAnnex state key = doesFileExist $ annexLocation state key inAnnex state backend key = doesFileExist $ annexLocation state backend key
{- On startup, examine the git repo, prepare it, and record state for {- On startup, examine the git repo, prepare it, and record state for
- later. -} - later. -}
@ -56,15 +56,14 @@ annexFile state file = do
Just (key, backend) -> setup key backend Just (key, backend) -> setup key backend
where where
setup key backend = do setup key backend = do
let dest = annexLocation state key let dest = annexLocation state backend key
createDirectoryIfMissing True (parentDir dest) createDirectoryIfMissing True (parentDir dest)
renameFile file dest renameFile file dest
createSymbolicLink dest file createSymbolicLink dest file
gitRun (repo state) ["add", file, bfile] gitRun (repo state) ["add", file]
gitRun (repo state) ["commit", "-m", gitRun (repo state) ["commit", "-m",
("git-annex annexed " ++ file), file, bfile] ("git-annex annexed " ++ file), file]
logStatus state key ValuePresent logStatus state key ValuePresent
where bfile = backendFile state backend file
checkLegal file = do checkLegal file = do
s <- getSymbolicLinkStatus file s <- getSymbolicLinkStatus file
if ((isSymbolicLink s) || (not $ isRegularFile s)) if ((isSymbolicLink s) || (not $ isRegularFile s))
@ -82,16 +81,15 @@ unannexFile state file = do
case (mkey) of case (mkey) of
Nothing -> return () Nothing -> return ()
Just (key, backend) -> do Just (key, backend) -> do
let src = annexLocation state key let src = annexLocation state backend key
removeFile file removeFile file
gitRun (repo state) ["rm", file, bfile] gitRun (repo state) ["rm", file]
gitRun (repo state) ["commit", "-m", gitRun (repo state) ["commit", "-m",
("git-annex unannexed " ++ file), ("git-annex unannexed " ++ file),
file, bfile] file]
renameFile src file renameFile src file
logStatus state key ValueMissing logStatus state key ValueMissing
return () return ()
where bfile = backendFile state backend file
{- Transfers the file from a remote. -} {- Transfers the file from a remote. -}
annexGetFile :: State -> FilePath -> IO () annexGetFile :: State -> FilePath -> IO ()
@ -100,12 +98,12 @@ annexGetFile state file = do
case (alreadyannexed) of case (alreadyannexed) of
Nothing -> error $ "not annexed " ++ file Nothing -> error $ "not annexed " ++ file
Just backend -> do Just backend -> do
key <- lookupKey state backend file key <- fileKey file
inannex <- inAnnex state key inannex <- inAnnex state backend key
if (inannex) if (inannex)
then return () then return ()
else do else do
let dest = annexLocation state key let dest = annexLocation state backend key
createDirectoryIfMissing True (parentDir dest) createDirectoryIfMissing True (parentDir dest)
success <- retrieveFile state file dest success <- retrieveFile state file dest
if (success) if (success)

View file

@ -17,12 +17,14 @@ module Backend (
lookupBackend, lookupBackend,
storeFile, storeFile,
retrieveFile, retrieveFile,
lookupKey, fileKey,
dropFile dropFile
) where ) where
import System.Directory import System.Directory
import System.FilePath
import Data.String.Utils import Data.String.Utils
import System.Posix.Files
import Locations import Locations
import GitRepo import GitRepo
import Utility import Utility
@ -41,7 +43,6 @@ storeFile' (b:bs) state file = do
if (not stored) if (not stored)
then nextbackend then nextbackend
else do else do
recordKey state b file key
return $ Just (key, b) return $ Just (key, b)
where where
nextbackend = storeFile' bs state file nextbackend = storeFile' bs state file
@ -53,9 +54,9 @@ retrieveFile state file dest = do
result <- lookupBackend state file result <- lookupBackend state file
case (result) of case (result) of
Nothing -> return False Nothing -> return False
Just b -> do Just backend -> do
key <- lookupKey state b file key <- fileKey file
(retrieveKeyFile b) state key dest (retrieveKeyFile backend) state key dest
{- Drops the key for a file from the backend that has it. -} {- Drops the key for a file from the backend that has it. -}
dropFile :: State -> FilePath -> IO (Maybe (Key, Backend)) dropFile :: State -> FilePath -> IO (Maybe (Key, Backend))
@ -63,11 +64,10 @@ dropFile state file = do
result <- lookupBackend state file result <- lookupBackend state file
case (result) of case (result) of
Nothing -> return Nothing Nothing -> return Nothing
Just b -> do Just backend -> do
key <- lookupKey state b file key <- fileKey file
(removeKey b) state key (removeKey backend) state key
removeFile $ backendFile state b file return $ Just (key, backend)
return $ Just (key, b)
{- Looks up the backend used for an already annexed file. -} {- Looks up the backend used for an already annexed file. -}
lookupBackend :: State -> FilePath -> IO (Maybe Backend) lookupBackend :: State -> FilePath -> IO (Maybe Backend)
@ -83,22 +83,12 @@ lookupBackend' (b:bs) state file = do
{- Checks if a file is available via a given backend. -} {- Checks if a file is available via a given backend. -}
checkBackend :: Backend -> State -> FilePath -> IO (Bool) checkBackend :: Backend -> State -> FilePath -> IO (Bool)
checkBackend backend state file = doesFileExist $ backendFile state backend file checkBackend backend state file =
doesFileExist $ annexLocation state backend file
{- Looks up the key a backend uses for an already annexed file. -} {- Looks up the key corresponding to an annexed file,
lookupKey :: State -> Backend -> FilePath -> IO Key - by examining what the file symlinks to. -}
lookupKey state backend file = do fileKey :: FilePath -> IO Key
k <- readFile (backendFile state backend file) fileKey file = do
return $ chomp k l <- readSymbolicLink (file)
where return $ takeFileName $ l
chomp s = if (endswith "\n" s)
then (reverse . (drop 1) . reverse) s
else s
{- Records the key used for an annexed file. -}
recordKey :: State -> Backend -> FilePath -> Key -> IO ()
recordKey state backend file key = do
createDirectoryIfMissing True (parentDir record)
writeFile record $ key ++ "\n"
where
record = backendFile state backend file

View file

@ -5,8 +5,7 @@ module Locations (
gitStateDir, gitStateDir,
stateLoc, stateLoc,
keyFile, keyFile,
annexLocation, annexLocation
backendFile
) where ) where
import Data.String.Utils import Data.String.Utils
@ -25,15 +24,10 @@ gitStateDir repo = (gitWorkTree repo) ++ "/" ++ stateLoc ++ "/"
keyFile :: Key -> FilePath keyFile :: Key -> FilePath
keyFile key = replace "/" "&s" $ replace "&" "&a" key keyFile key = replace "/" "&s" $ replace "&" "&a" key
{- An annexed file's content is stored somewhere under .git/annex/, {- An annexed file's content is stored in
- based on the key. -} - .git/annex/<backend>/<key> ; this allows deriving the key and backend
annexLocation :: State -> Key -> FilePath - by looking at the symlink to it. -}
annexLocation state key = gitDir (repo state) ++ "/annex/" ++ (keyFile key) annexLocation :: State -> Backend -> Key -> FilePath
annexLocation state backend key =
{- The mapping from filename to its key is stored in the .git-annex directory, gitDir (repo state) ++ "/annex/" ++ (name backend) ++
- in a file named `key/$filename.$backend` -} "/" ++ (keyFile key)
backendFile :: State -> Backend -> FilePath -> String
backendFile state backend file =
gitStateDir (repo state) ++ "key/" ++
(gitRelative (repo state) file) ++
"." ++ (name backend)

7
TODO
View file

@ -1,6 +1,13 @@
* bug when annexing files in a subdir of a git repo * bug when annexing files in a subdir of a git repo
* how to handle git mv file? * how to handle git mv file?
* if the annexed files were in .git/annex/<backend>/key, and
files in the repo symlink to that, the .git-annex/key/<file>.<backend>
would be redundant, and not needed
-- no separate merge problem with it
-- want to add an url? `ln -s .git/annex/<backend>/http:%%kitenet.net%foo myfile`
* implement retrieval for backendfile * implement retrieval for backendfile
* query remotes for their annex.uuid settings * query remotes for their annex.uuid settings

View file

@ -91,11 +91,9 @@ used to store the file contents, and git-annex would then retrieve them
as needed and put them in `.git/annex/`. as needed and put them in `.git/annex/`.
When a file is annexed, a key is generated from its content and/or metadata. When a file is annexed, a key is generated from its content and/or metadata.
This key can later be used to retrieve the file's content (its value). This The file checked into git symlinks to the key. This key can later be used
key generation must be stable for a given file content, name, and size. to retrieve the file's content (its value). This key generation must be
stable for a given file content, name, and size.
The mapping from filename to its key is stored in the .git-annex directory,
in a file named `key/$filename.$backend`
Multiple pluggable backends are supported, and more than one can be used Multiple pluggable backends are supported, and more than one can be used
to store different files' contents in a given repository. to store different files' contents in a given repository.
@ -183,8 +181,8 @@ not be dropped right away, depending on number of copies available.
### branching ### branching
The use of `.git-annex` to store state means that if a repo has branches The use of `.git-annex` to store logs means that if a repo has branches
and the user switched between them, git-annex will see different state in and the user switched between them, git-annex will see different logs in
the different branches. Whether that is a bug or a feature may depend on the different branches, and so may miss info about what remotes have which
point of view -- call it Too Be Determined. An alternative would be to files (though it can re-learn). An alternative would be to
store data directly in the git repo as `pristine-tar` does. store the log data directly in the git repo as `pristine-tar` does.