atomic file retrieval from backends

This commit is contained in:
Joey Hess 2010-10-17 16:39:30 -04:00
parent 8398b9ab4a
commit a020b0c25c
4 changed files with 22 additions and 10 deletions

View file

@ -156,13 +156,16 @@ getCmd file = notinBackend file err $ \(key, backend) -> do
showStart "get" file showStart "get" file
g <- Annex.gitRepo g <- Annex.gitRepo
let dest = annexLocation g key let dest = annexLocation g key
liftIO $ createDirectoryIfMissing True (parentDir dest) let tmp = (annexTmpLocation g) ++ (keyFile key)
success <- Backend.retrieveKeyFile backend key dest liftIO $ createDirectoryIfMissing True (parentDir tmp)
success <- Backend.retrieveKeyFile backend key tmp
if (success) if (success)
then do then do
liftIO $ renameFile tmp dest
logStatus key ValuePresent logStatus key ValuePresent
showEndOk showEndOk
else showEndFail "get" file else do
showEndFail "get" file
where where
err = error $ "not annexed " ++ file err = error $ "not annexed " ++ file

View file

@ -29,6 +29,8 @@ startup flags = do
shutdown :: Annex () shutdown :: Annex ()
shutdown = do shutdown = do
g <- Annex.gitRepo g <- Annex.gitRepo
-- handle pending commits
nocommit <- Annex.flagIsSet NoCommit nocommit <- Annex.flagIsSet NoCommit
needcommit <- Annex.flagIsSet NeedCommit needcommit <- Annex.flagIsSet NeedCommit
if (needcommit && not nocommit) if (needcommit && not nocommit)
@ -36,6 +38,13 @@ shutdown = do
"git-annex log update", gitStateDir g] "git-annex log update", gitStateDir g]
else return () else return ()
-- clean up any files left in the temp directory
let tmp = annexTmpLocation g
exists <- liftIO $ doesDirectoryExist tmp
if (exists)
then liftIO $ removeDirectoryRecursive $ tmp
else return ()
{- configure git to use union merge driver on state files, if it is not {- configure git to use union merge driver on state files, if it is not
- already -} - already -}
gitAttributes :: Git.Repo -> IO () gitAttributes :: Git.Repo -> IO ()

View file

@ -7,7 +7,8 @@ module Locations (
keyFile, keyFile,
fileKey, fileKey,
annexLocation, annexLocation,
annexLocationRelative annexLocationRelative,
annexTmpLocation
) where ) where
import Data.String.Utils import Data.String.Utils
@ -36,6 +37,11 @@ annexLocation r key =
annexLocationRelative :: Git.Repo -> Key -> FilePath annexLocationRelative :: Git.Repo -> Key -> FilePath
annexLocationRelative r key = Git.dir r ++ "/annex/" ++ (keyFile key) annexLocationRelative r key = Git.dir r ++ "/annex/" ++ (keyFile key)
{- .git-annex/tmp is used for temp files
-}
annexTmpLocation :: Git.Repo -> FilePath
annexTmpLocation r = (Git.workTree r) ++ "/" ++ Git.dir r ++ "/annex/tmp/"
{- Converts a key into a filename fragment. {- Converts a key into a filename fragment.
- -
- Escape "/" in the key name, to keep a flat tree of files and avoid - Escape "/" in the key name, to keep a flat tree of files and avoid

6
TODO
View file

@ -1,9 +1,6 @@
* bug: cannot "git annex ../foo" (GitRepo.relative is buggy and * bug: cannot "git annex ../foo" (GitRepo.relative is buggy and
git-ls-files also refuses w/o --full-name, which would need other changes) git-ls-files also refuses w/o --full-name, which would need other changes)
* bug: git annex add file is silent if file was a symlink and got replaced
with a file. The you then git command -a, you'll check in the fil contents..
* --push/--pull should take a reponame and files, and push those files * --push/--pull should take a reponame and files, and push those files
to that repo; dropping them from the current repo to that repo; dropping them from the current repo
@ -17,9 +14,6 @@
* Support for remote git repositories (ssh:// specifically can be made to * Support for remote git repositories (ssh:// specifically can be made to
work, although the other end probably needs to have git-annex installed..) work, although the other end probably needs to have git-annex installed..)
* Copy files atomically, don't leave a partial key on interrupt.
(Fix for URL download too..)
* Find a way to copy a file with a progress bar, while still preserving * Find a way to copy a file with a progress bar, while still preserving
stat. Easiest way might be to use pv and fix up the permissions etc stat. Easiest way might be to use pv and fix up the permissions etc
after? after?