summaryrefslogtreecommitdiff
path: root/Locations.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-11-28 22:43:51 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-11-28 22:43:51 -0400
commitda9cd315beb03570b96f83063a39e799fe01b166 (patch)
tree61fdc79dd54dccf1792cf3ccadcc584e0119d077 /Locations.hs
parent2b3c120506f1f25b4c3d0e19342b9826bde0b3b5 (diff)
add support for using hashDirLower in addition to hashDirMixed
Supporting multiple directory hash types will allow converting to a different one, without a flag day. gitAnnexLocation now checks which of the possible locations have a file. This means more statting of files. Several places currently use gitAnnexLocation and immediately check if the returned file exists; those need to be optimised.
Diffstat (limited to 'Locations.hs')
-rw-r--r--Locations.hs35
1 files changed, 25 insertions, 10 deletions
diff --git a/Locations.hs b/Locations.hs
index 3cb632aae..425e4fdcf 100644
--- a/Locations.hs
+++ b/Locations.hs
@@ -9,7 +9,7 @@ module Locations (
keyFile,
fileKey,
gitAnnexLocation,
- annexLocation,
+ annexLocations,
gitAnnexDir,
gitAnnexObjectDir,
gitAnnexTmpDir,
@@ -58,17 +58,33 @@ annexDir = addTrailingPathSeparator "annex"
objectDir :: FilePath
objectDir = addTrailingPathSeparator $ annexDir </> "objects"
-{- Annexed file's location relative to the .git directory. -}
-annexLocation :: Key -> FilePath
-annexLocation key = objectDir </> hashDirMixed key </> f </> f
+{- Annexed file's possible locations relative to the .git directory.
+ - There are two different possibilities, using different hashes;
+ - the first is the default for new content. -}
+annexLocations :: Key -> [FilePath]
+annexLocations key = [using hashDirMixed, using hashDirLower]
where
+ using h = objectDir </> h key </> f </> f
f = keyFile key
-{- Annexed file's absolute location in a repository. -}
-gitAnnexLocation :: Key -> Git.Repo -> FilePath
+{- Annexed file's absolute location in a repository.
+ - Out of the possible annexLocations, returns the one where the file
+ - is actually present. When the file is not present, returns the
+ - one where the file should be put.
+ -}
+gitAnnexLocation :: Key -> Git.Repo -> IO FilePath
gitAnnexLocation key r
- | Git.repoIsLocalBare r = Git.workTree r </> annexLocation key
- | otherwise = Git.workTree r </> ".git" </> annexLocation key
+ | Git.repoIsLocalBare r =
+ go (Git.workTree r) $ annexLocations key
+ | otherwise =
+ go (Git.workTree r </> ".git") $ annexLocations key
+ where
+ go dir locs = fromMaybe (dir </> head locs) <$> check dir locs
+ check _ [] = return Nothing
+ check dir (l:ls) = do
+ let f = dir </> l
+ e <- doesFileExist f
+ if e then return (Just f) else check dir ls
{- The annex directory of a repository. -}
gitAnnexDir :: Git.Repo -> FilePath
@@ -76,8 +92,7 @@ gitAnnexDir r
| Git.repoIsLocalBare r = addTrailingPathSeparator $ Git.workTree r </> annexDir
| otherwise = addTrailingPathSeparator $ Git.workTree r </> ".git" </> annexDir
-{- The part of the annex directory where file contents are stored.
- -}
+{- The part of the annex directory where file contents are stored. -}
gitAnnexObjectDir :: Git.Repo -> FilePath
gitAnnexObjectDir r
| Git.repoIsLocalBare r = addTrailingPathSeparator $ Git.workTree r </> objectDir