aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Annex/Content.hs4
-rw-r--r--Annex/Difference.hs4
-rw-r--r--Annex/DirHashes.hs86
-rw-r--r--Annex/FileMatcher.hs6
-rw-r--r--Annex/Wanted.hs8
-rw-r--r--Command/Find.hs5
-rw-r--r--Command/Log.hs3
-rw-r--r--Command/Uninit.hs5
-rw-r--r--Common.hs1
-rw-r--r--Config.hs4
-rw-r--r--Locations.hs85
-rw-r--r--Logs.hs56
-rw-r--r--Logs/Chunk.hs8
-rw-r--r--Logs/Difference.hs3
-rw-r--r--Logs/Difference/Pure.hs3
-rw-r--r--Logs/Location.hs9
-rw-r--r--Logs/MetaData.hs20
-rw-r--r--Logs/PreferredContent.hs6
-rw-r--r--Logs/RemoteState.hs10
-rw-r--r--Logs/Web.hs11
-rw-r--r--Remote/Directory.hs3
-rw-r--r--Remote/External.hs2
-rw-r--r--Remote/GCrypt.hs3
-rw-r--r--Remote/Git.hs6
-rw-r--r--Remote/Hook.hs6
-rw-r--r--Remote/Rsync.hs5
-rw-r--r--Remote/Rsync/RsyncUrl.hs6
-rw-r--r--Remote/WebDAV/DavLocation.hs5
-rw-r--r--Test.hs2
-rw-r--r--Types/Difference.hs103
-rw-r--r--Types/GitConfig.hs4
-rw-r--r--Upgrade/V1.hs3
-rw-r--r--Upgrade/V2.hs4
-rw-r--r--Utility/Url.hs1
-rw-r--r--debian/changelog2
-rw-r--r--doc/git-annex.mdwn2
-rw-r--r--doc/internals.mdwn2
-rw-r--r--doc/tuning.mdwn20
38 files changed, 271 insertions, 245 deletions
diff --git a/Annex/Content.hs b/Annex/Content.hs
index a78cf674c..f91c1e72a 100644
--- a/Annex/Content.hs
+++ b/Annex/Content.hs
@@ -110,10 +110,10 @@ inAnnexSafe key = inAnnex' (fromMaybe False) (Just False) go key
( checkOr is_unlocked lockfile
, return is_missing
)
- checkOr def lockfile = do
+ checkOr d lockfile = do
v <- checkLocked lockfile
return $ case v of
- Nothing -> def
+ Nothing -> d
Just True -> is_locked
Just False -> is_unlocked
#else
diff --git a/Annex/Difference.hs b/Annex/Difference.hs
index cb363e80c..07789e7bb 100644
--- a/Annex/Difference.hs
+++ b/Annex/Difference.hs
@@ -31,9 +31,7 @@ import qualified Data.Map as M
setDifferences :: Annex ()
setDifferences = do
u <- getUUID
- otherds <- either error return
- =<< sanityCheckDifferences . allDifferences
- <$> recordedDifferences
+ otherds <- allDifferences <$> recordedDifferences
ds <- mappend otherds . annexDifferences <$> Annex.getGitConfig
when (ds /= mempty) $ do
ds'@(Differences l) <- ifM (isJust <$> getVersion)
diff --git a/Annex/DirHashes.hs b/Annex/DirHashes.hs
new file mode 100644
index 000000000..b58b5a215
--- /dev/null
+++ b/Annex/DirHashes.hs
@@ -0,0 +1,86 @@
+{- git-annex file locations
+ -
+ - Copyright 2010-2015 Joey Hess <id@joeyh.name>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.DirHashes (
+ Hasher,
+ HashLevels(..),
+ objectHashLevels,
+ branchHashLevels,
+ branchHashDir,
+ dirHashes,
+ hashDirMixed,
+ hashDirLower,
+) where
+
+import Data.Bits
+import Data.Word
+import Data.Hash.MD5
+import Data.Default
+
+import Common
+import Types.Key
+import Types.GitConfig
+import Types.Difference
+
+type Hasher = Key -> FilePath
+
+-- Number of hash levels to use. 2 is the default.
+newtype HashLevels = HashLevels Int
+
+instance Default HashLevels where
+ def = HashLevels 2
+
+objectHashLevels :: GitConfig -> HashLevels
+objectHashLevels = configHashLevels OneLevelObjectHash
+
+branchHashLevels :: GitConfig -> HashLevels
+branchHashLevels = configHashLevels OneLevelBranchHash
+
+configHashLevels :: Difference -> GitConfig -> HashLevels
+configHashLevels d config
+ | hasDifference (== d) (annexDifferences config) = HashLevels 1
+ | otherwise = def
+
+branchHashDir :: GitConfig -> Key -> String
+branchHashDir config key = hashDirLower (branchHashLevels config) key
+
+{- Two different directory hashes may be used. The mixed case hash
+ - came first, and is fine, except for the problem of case-strict
+ - filesystems such as Linux VFAT (mounted with shortname=mixed),
+ - which do not allow using a directory "XX" when "xx" already exists.
+ - To support that, most repositories use the lower case hash for new data. -}
+dirHashes :: [HashLevels -> Hasher]
+dirHashes = [hashDirLower, hashDirMixed]
+
+hashDirs :: HashLevels -> Int -> String -> FilePath
+hashDirs (HashLevels 1) sz s = addTrailingPathSeparator $ take sz s
+hashDirs _ sz s = addTrailingPathSeparator $ take sz s </> drop sz s
+
+hashDirMixed :: HashLevels -> Hasher
+hashDirMixed n k = hashDirs n 2 $ take 4 $ display_32bits_as_dir =<< [a,b,c,d]
+ where
+ ABCD (a,b,c,d) = md5 $ md5FilePath $ key2file $ nonChunkKey k
+
+hashDirLower :: HashLevels -> Hasher
+hashDirLower n k = hashDirs n 3 $ take 6 $ md5s $ md5FilePath $ key2file $ nonChunkKey k
+
+{- modified version of display_32bits_as_hex from Data.Hash.MD5
+ - Copyright (C) 2001 Ian Lynagh
+ - License: Either BSD or GPL
+ -}
+display_32bits_as_dir :: Word32 -> String
+display_32bits_as_dir w = trim $ swap_pairs cs
+ where
+ -- Need 32 characters to use. To avoid inaverdently making
+ -- a real word, use letters that appear less frequently.
+ chars = ['0'..'9'] ++ "zqjxkmvwgpfZQJXKMVWGPF"
+ cs = map (\x -> getc $ (shiftR w (6*x)) .&. 31) [0..7]
+ getc n = chars !! fromIntegral n
+ swap_pairs (x1:x2:xs) = x2:x1:swap_pairs xs
+ swap_pairs _ = []
+ -- Last 2 will always be 00, so omit.
+ trim = take 6
diff --git a/Annex/FileMatcher.hs b/Annex/FileMatcher.hs
index c6a729a9c..16ade922c 100644
--- a/Annex/FileMatcher.hs
+++ b/Annex/FileMatcher.hs
@@ -28,12 +28,12 @@ checkFileMatcher :: (FileMatcher Annex) -> FilePath -> Annex Bool
checkFileMatcher matcher file = checkMatcher matcher Nothing (Just file) S.empty True
checkMatcher :: (FileMatcher Annex) -> Maybe Key -> AssociatedFile -> AssumeNotPresent -> Bool -> Annex Bool
-checkMatcher matcher mkey afile notpresent def
- | isEmpty matcher = return def
+checkMatcher matcher mkey afile notpresent d
+ | isEmpty matcher = return d
| otherwise = case (mkey, afile) of
(_, Just file) -> go =<< fileMatchInfo file
(Just key, _) -> go (MatchingKey key)
- _ -> return def
+ _ -> return d
where
go mi = matchMrun matcher $ \a -> a notpresent mi
diff --git a/Annex/Wanted.hs b/Annex/Wanted.hs
index 87b4377c2..ba7df0a9c 100644
--- a/Annex/Wanted.hs
+++ b/Annex/Wanted.hs
@@ -15,15 +15,15 @@ import qualified Data.Set as S
{- Check if a file is preferred content for the local repository. -}
wantGet :: Bool -> Maybe Key -> AssociatedFile -> Annex Bool
-wantGet def key file = isPreferredContent Nothing S.empty key file def
+wantGet d key file = isPreferredContent Nothing S.empty key file d
{- Check if a file is preferred content for a remote. -}
wantSend :: Bool -> Maybe Key -> AssociatedFile -> UUID -> Annex Bool
-wantSend def key file to = isPreferredContent (Just to) S.empty key file def
+wantSend d key file to = isPreferredContent (Just to) S.empty key file d
{- Check if a file can be dropped, maybe from a remote.
- Don't drop files that are preferred content. -}
wantDrop :: Bool -> Maybe UUID -> Maybe Key -> AssociatedFile -> Annex Bool
-wantDrop def from key file = do
+wantDrop d from key file = do
u <- maybe getUUID (return . id) from
- not <$> isPreferredContent (Just u) (S.singleton u) key file def
+ not <$> isPreferredContent (Just u) (S.singleton u) key file d
diff --git a/Command/Find.hs b/Command/Find.hs
index a52d17384..55124d838 100644
--- a/Command/Find.hs
+++ b/Command/Find.hs
@@ -7,6 +7,7 @@
module Command.Find where
+import Data.Default
import qualified Data.Map as M
import Common.Annex
@@ -65,8 +66,8 @@ keyVars key =
, ("bytesize", size show)
, ("humansize", size $ roughSize storageUnits True)
, ("keyname", keyName key)
- , ("hashdirlower", hashDirLower key)
- , ("hashdirmixed", hashDirMixed key)
+ , ("hashdirlower", hashDirLower def key)
+ , ("hashdirmixed", hashDirMixed def key)
, ("mtime", whenavail show $ keyMtime key)
]
where
diff --git a/Command/Log.hs b/Command/Log.hs
index 7eaa48f70..7c48388c2 100644
--- a/Command/Log.hs
+++ b/Command/Log.hs
@@ -141,7 +141,8 @@ getLog :: Key -> [CommandParam] -> Annex [String]
getLog key os = do
top <- fromRepo Git.repoPath
p <- liftIO $ relPathCwdToFile top
- let logfile = p </> locationLogFile key
+ config <- Annex.getGitConfig
+ let logfile = p </> locationLogFile config key
inRepo $ pipeNullSplitZombie $
[ Params "log -z --pretty=format:%ct --raw --abbrev=40"
, Param "--remove-empty"
diff --git a/Command/Uninit.hs b/Command/Uninit.hs
index 592b71a02..28c169919 100644
--- a/Command/Uninit.hs
+++ b/Command/Uninit.hs
@@ -18,6 +18,9 @@ import Annex.Content
import Annex.Init
import Utility.FileMode
+import System.IO.HVFS
+import System.IO.HVFS.Utils
+
cmd :: [Command]
cmd = [addCheck check $ command "uninit" paramPaths seek
SectionUtility "de-initialize git-annex and clean out repository"]
@@ -88,7 +91,7 @@ finish = do
- preparation for removal. -}
prepareRemoveAnnexDir :: FilePath -> IO ()
prepareRemoveAnnexDir annexdir =
- mapM_ (void . tryIO . allowWrite) =<< dirContentsRecursive annexdir
+ recurseDir SystemFS annexdir >>= mapM_ (void . tryIO . allowWrite)
{- Keys that were moved out of the annex have a hard link still in the
- annex, with > 1 link count, and those can be removed.
diff --git a/Common.hs b/Common.hs
index 9333a19d9..8272043c2 100644
--- a/Common.hs
+++ b/Common.hs
@@ -11,6 +11,7 @@ import Data.Maybe as X
import Data.List as X hiding (head, tail, init, last)
import Data.String.Utils as X hiding (join)
import Data.Monoid as X
+import Data.Default as X
import System.FilePath as X
import System.Directory as X
diff --git a/Config.hs b/Config.hs
index 57ced7821..29135ed96 100644
--- a/Config.hs
+++ b/Config.hs
@@ -23,7 +23,7 @@ instance Show ConfigKey where
{- Looks up a setting in git config. -}
getConfig :: ConfigKey -> String -> Annex String
-getConfig (ConfigKey key) def = fromRepo $ Git.Config.get key def
+getConfig (ConfigKey key) d = fromRepo $ Git.Config.get key d
getConfigMaybe :: ConfigKey -> Annex (Maybe String)
getConfigMaybe (ConfigKey key) = fromRepo $ Git.Config.getMaybe key
@@ -58,7 +58,7 @@ annexConfig key = ConfigKey $ "annex." ++ key
- by remote.<name>.annex-cost, or if remote.<name>.annex-cost-command
- is set and prints a number, that is used. -}
remoteCost :: RemoteGitConfig -> Cost -> Annex Cost
-remoteCost c def = fromMaybe def <$> remoteCost' c
+remoteCost c d = fromMaybe d <$> remoteCost' c
remoteCost' :: RemoteGitConfig -> Annex (Maybe Cost)
remoteCost' c = case remoteAnnexCostCommand c of
diff --git a/Locations.hs b/Locations.hs
index dcbde4bd9..c5221d8bc 100644
--- a/Locations.hs
+++ b/Locations.hs
@@ -1,6 +1,6 @@
{- git-annex file locations
-
- - Copyright 2010-2013 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2015 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@@ -20,7 +20,6 @@ module Locations (
gitAnnexInodeSentinal,
gitAnnexInodeSentinalCache,
annexLocations,
- annexLocation,
gitAnnexDir,
gitAnnexObjectDir,
gitAnnexTmpMiscDir,
@@ -59,7 +58,7 @@ module Locations (
gitAnnexRemotesDir,
gitAnnexAssistantDefaultDir,
isLinkToAnnex,
- annexHashes,
+ HashLevels(..),
hashDirMixed,
hashDirLower,
preSanitizeKeyName,
@@ -67,17 +66,16 @@ module Locations (
prop_idempotent_fileKey
) where
-import Data.Bits
-import Data.Word
-import Data.Hash.MD5
import Data.Char
+import Data.Default
import Common
-import Types
+import Types.GitConfig
import Types.Key
import Types.UUID
import Types.Difference
import qualified Git
+import Annex.DirHashes
{- Conventions:
-
@@ -103,11 +101,15 @@ objectDir :: FilePath
objectDir = addTrailingPathSeparator $ annexDir </> "objects"
{- Annexed file's possible locations relative to the .git directory.
- - There are two different possibilities, using different hashes. -}
-annexLocations :: Key -> [FilePath]
-annexLocations key = map (annexLocation key) annexHashes
-annexLocation :: Key -> Hasher -> FilePath
-annexLocation key hasher = objectDir </> keyPath key hasher
+ - There are two different possibilities, using different hashes.
+ -
+ - Also, some repositories have a Difference in hash directory depth.
+ -}
+annexLocations :: GitConfig -> Key -> [FilePath]
+annexLocations config key = map (annexLocation config key) dirHashes
+
+annexLocation :: GitConfig -> Key -> (HashLevels -> Hasher) -> FilePath
+annexLocation config key hasher = objectDir </> keyPath key (hasher $ objectHashLevels config)
{- Annexed object's location in a repository.
-
@@ -135,12 +137,12 @@ gitAnnexLocation' key r config crippled
-}
| Git.repoIsLocalBare r
|| crippled
- || hasDifference (== ObjectHashLower True) (annexDifferences config) =
- check $ map inrepo $ annexLocations key
+ || hasDifference (== ObjectHashLower) (annexDifferences config) =
+ check $ map inrepo $ annexLocations config key
{- Non-bare repositories only use hashDirMixed, so
- don't need to do any work to check if the file is
- present. -}
- | otherwise = return $ inrepo $ annexLocation key hashDirMixed
+ | otherwise = return $ inrepo $ annexLocation config key hashDirMixed
where
inrepo d = Git.localGitDir r </> d
check locs@(l:_) = fromMaybe l <$> firstM doesFileExist locs
@@ -405,9 +407,9 @@ prop_idempotent_fileKey s
where
k = stubKey { keyName = s, keyBackendName = "test" }
-{- A location to store a key on the filesystem. A directory hash is used,
- - to protect against filesystems that dislike having many items in a
- - single directory.
+{- A location to store a key on a special remote that uses a filesystem.
+ - A directory hash is used, to protect against filesystems that dislike
+ - having many items in a single directory.
-
- The file is put in a directory with the same name, this allows
- write-protecting the directory to avoid accidental deletion of the file.
@@ -417,44 +419,11 @@ keyPath key hasher = hasher key </> f </> f
where
f = keyFile key
-{- All possibile locations to store a key using different directory hashes. -}
-keyPaths :: Key -> [FilePath]
-keyPaths key = map (keyPath key) annexHashes
-
-{- Two different directory hashes may be used. The mixed case hash
- - came first, and is fine, except for the problem of case-strict
- - filesystems such as Linux VFAT (mounted with shortname=mixed),
- - which do not allow using a directory "XX" when "xx" already exists.
- - To support that, most repositories use the lower case hash for new data. -}
-type Hasher = Key -> FilePath
-
-annexHashes :: [Hasher]
-annexHashes = [hashDirLower, hashDirMixed]
-
-hashDirMixed :: Hasher
-hashDirMixed k = addTrailingPathSeparator $ take 2 dir </> drop 2 dir
- where
- dir = take 4 $ display_32bits_as_dir =<< [a,b,c,d]
- ABCD (a,b,c,d) = md5 $ md5FilePath $ key2file $ nonChunkKey k
-
-hashDirLower :: Hasher
-hashDirLower k = addTrailingPathSeparator $ take 3 dir </> drop 3 dir
- where
- dir = take 6 $ md5s $ md5FilePath $ key2file $ nonChunkKey k
-
-{- modified version of display_32bits_as_hex from Data.Hash.MD5
- - Copyright (C) 2001 Ian Lynagh
- - License: Either BSD or GPL
+{- All possibile locations to store a key in a special remote
+ - using different directory hashes.
+ -
+ - This is compatible with the annexLocations, for interoperability between
+ - special remotes and git-annex repos.
-}
-display_32bits_as_dir :: Word32 -> String
-display_32bits_as_dir w = trim $ swap_pairs cs
- where
- -- Need 32 characters to use. To avoid inaverdently making
- -- a real word, use letters that appear less frequently.
- chars = ['0'..'9'] ++ "zqjxkmvwgpfZQJXKMVWGPF"
- cs = map (\x -> getc $ (shiftR w (6*x)) .&. 31) [0..7]
- getc n = chars !! fromIntegral n
- swap_pairs (x1:x2:xs) = x2:x1:swap_pairs xs
- swap_pairs _ = []
- -- Last 2 will always be 00, so omit.
- trim = take 6
+keyPaths :: Key -> [FilePath]
+keyPaths key = map (\h -> keyPath key (h def)) dirHashes
diff --git a/Logs.hs b/Logs.hs
index 8d8ae993b..1f8cf9f9c 100644
--- a/Logs.hs
+++ b/Logs.hs
@@ -9,6 +9,7 @@ module Logs where
import Common.Annex
import Types.Key
+import Annex.DirHashes
{- There are several varieties of log file formats. -}
data LogVariety
@@ -87,8 +88,8 @@ differenceLog :: FilePath
differenceLog = "difference.log"
{- The pathname of the location log file for a given key. -}
-locationLogFile :: Key -> String
-locationLogFile key = hashDirLower key ++ keyFile key ++ ".log"
+locationLogFile :: GitConfig -> Key -> String
+locationLogFile config key = branchHashDir config key </> keyFile key ++ ".log"
{- Converts a pathname into a key if it's a location log. -}
locationLogFileKey :: FilePath -> Maybe Key
@@ -101,15 +102,17 @@ locationLogFileKey path
(base, ext) = splitAt (length file - 4) file
{- The filename of the url log for a given key. -}
-urlLogFile :: Key -> FilePath
-urlLogFile key = hashDirLower key </> keyFile key ++ urlLogExt
+urlLogFile :: GitConfig -> Key -> FilePath
+urlLogFile config key = branchHashDir config key </> keyFile key ++ urlLogExt
{- Old versions stored the urls elsewhere. -}
-oldurlLogs :: Key -> [FilePath]
-oldurlLogs key =
- [ "remote/web" </> hashDirLower key </> key2file key ++ ".log"
- , "remote/web" </> hashDirLower key </> keyFile key ++ ".log"
+oldurlLogs :: GitConfig -> Key -> [FilePath]
+oldurlLogs config key =
+ [ "remote/web" </> hdir </> key2file key ++ ".log"
+ , "remote/web" </> hdir </> keyFile key ++ ".log"
]
+ where
+ hdir = branchHashDir config key
urlLogExt :: String
urlLogExt = ".log.web"
@@ -130,8 +133,9 @@ isUrlLog :: FilePath -> Bool
isUrlLog file = urlLogExt `isSuffixOf` file
{- The filename of the remote state log for a given key. -}
-remoteStateLogFile :: Key -> FilePath
-remoteStateLogFile key = hashDirLower key </> keyFile key ++ remoteStateLogExt
+remoteStateLogFile :: GitConfig -> Key -> FilePath
+remoteStateLogFile config key = branchHashDir config key
+ </> keyFile key ++ remoteStateLogExt
remoteStateLogExt :: String
remoteStateLogExt = ".log.rmt"
@@ -140,8 +144,8 @@ isRemoteStateLog :: FilePath -> Bool
isRemoteStateLog path = remoteStateLogExt `isSuffixOf` path
{- The filename of the chunk log for a given key. -}
-chunkLogFile :: Key -> FilePath
-chunkLogFile key = hashDirLower key </> keyFile key ++ chunkLogExt
+chunkLogFile :: GitConfig -> Key -> FilePath
+chunkLogFile config key = branchHashDir config key </> keyFile key ++ chunkLogExt
chunkLogFileKey :: FilePath -> Maybe Key
chunkLogFileKey path
@@ -159,35 +163,11 @@ isChunkLog :: FilePath -> Bool
isChunkLog path = chunkLogExt `isSuffixOf` path
{- The filename of the metadata log for a given key. -}
-metaDataLogFile :: Key -> FilePath
-metaDataLogFile key = hashDirLower key </> keyFile key ++ metaDataLogExt
+metaDataLogFile :: GitConfig -> Key -> FilePath
+metaDataLogFile config key = branchHashDir config key </> keyFile key ++ metaDataLogExt
metaDataLogExt :: String
metaDataLogExt = ".log.met"
isMetaDataLog :: FilePath -> Bool
isMetaDataLog path = metaDataLogExt `isSuffixOf` path
-
-prop_logs_sane :: Key -> Bool
-prop_logs_sane dummykey = and
- [ isNothing (getLogVariety "unknown")
- , expect gotUUIDBasedLog (getLogVariety uuidLog)
- , expect gotPresenceLog (getLogVariety $ locationLogFile dummykey)
- , expect gotPresenceLog (getLogVariety $ urlLogFile dummykey)
- , expect gotNewUUIDBasedLog (getLogVariety $ remoteStateLogFile dummykey)
- , expect gotChunkLog (getLogVariety $ chunkLogFile dummykey)
- , expect gotOtherLog (getLogVariety $ metaDataLogFile dummykey)
- , expect gotOtherLog (getLogVariety numcopiesLog)
- ]
- where
- expect = maybe False
- gotUUIDBasedLog UUIDBasedLog = True
- gotUUIDBasedLog _ = False
- gotNewUUIDBasedLog NewUUIDBasedLog = True
- gotNewUUIDBasedLog _ = False
- gotChunkLog (ChunkLog k) = k == dummykey
- gotChunkLog _ = False
- gotPresenceLog (PresenceLog k) = k == dummykey
- gotPresenceLog _ = False
- gotOtherLog OtherLog = True
- gotOtherLog _ = False
diff --git a/Logs/Chunk.hs b/Logs/Chunk.hs
index 8ca3ffed3..8f0e7cedb 100644
--- a/Logs/Chunk.hs
+++ b/Logs/Chunk.hs
@@ -29,6 +29,7 @@ import Logs
import Logs.MapLog
import qualified Annex.Branch
import Logs.Chunk.Pure
+import qualified Annex
import qualified Data.Map as M
import Data.Time.Clock.POSIX
@@ -36,14 +37,17 @@ import Data.Time.Clock.POSIX
chunksStored :: UUID -> Key -> ChunkMethod -> ChunkCount -> Annex ()
chunksStored u k chunkmethod chunkcount = do
ts <- liftIO getPOSIXTime
- Annex.Branch.change (chunkLogFile k) $
+ config <- Annex.getGitConfig
+ Annex.Branch.change (chunkLogFile config k) $
showLog . changeMapLog ts (u, chunkmethod) chunkcount . parseLog
chunksRemoved :: UUID -> Key -> ChunkMethod -> Annex ()
chunksRemoved u k chunkmethod = chunksStored u k chunkmethod 0
getCurrentChunks :: UUID -> Key -> Annex [(ChunkMethod, ChunkCount)]
-getCurrentChunks u k = select . parseLog <$> Annex.Branch.get (chunkLogFile k)
+getCurrentChunks u k = do
+ config <- Annex.getGitConfig
+ select . parseLog <$> Annex.Branch.get (chunkLogFile config k)
where
select = filter (\(_m, ct) -> ct > 0)
. map (\((_ku, m), l) -> (m, value l))
diff --git a/Logs/Difference.hs b/Logs/Difference.hs
index 68d624f99..fcebffee9 100644
--- a/Logs/Difference.hs
+++ b/Logs/Difference.hs
@@ -24,10 +24,11 @@ import Logs.UUIDBased
import Logs.Difference.Pure
recordDifferences :: Differences -> UUID -> Annex ()
-recordDifferences differences uuid = do
+recordDifferences (Differences differences) uuid = do
ts <- liftIO getPOSIXTime
Annex.Branch.change differenceLog $
showLog id . changeLog ts uuid (show differences) . parseLog Just
+recordDifferences UnknownDifferences _ = return ()
-- Map of UUIDs that have Differences recorded.
-- If a new version of git-annex has added a Difference this version
diff --git a/Logs/Difference/Pure.hs b/Logs/Difference/Pure.hs
index 76d995a01..25f3844d6 100644
--- a/Logs/Difference/Pure.hs
+++ b/Logs/Difference/Pure.hs
@@ -18,8 +18,7 @@ import Types.Difference
import Logs.UUIDBased
parseDifferencesLog :: String -> (M.Map UUID Differences)
-parseDifferencesLog = simpleMap
- . parseLog (Just . fromMaybe UnknownDifferences . readish)
+parseDifferencesLog = simpleMap . parseLog (Just . readDifferences)
-- The sum of all recorded differences, across all UUIDs.
allDifferences :: M.Map UUID Differences -> Differences
diff --git a/Logs/Location.hs b/Logs/Location.hs
index d0109b848..7c6888c0b 100644
--- a/Logs/Location.hs
+++ b/Logs/Location.hs
@@ -29,6 +29,7 @@ import Logs
import Logs.Presence
import Annex.UUID
import Git.Types (RefDate)
+import qualified Annex
{- Log a change in the presence of a key's value in current repository. -}
logStatus :: Key -> LogStatus -> Annex ()
@@ -38,7 +39,9 @@ logStatus key s = do
{- Log a change in the presence of a key's value in a repository. -}
logChange :: Key -> UUID -> LogStatus -> Annex ()
-logChange key (UUID u) s = addLog (locationLogFile key) =<< logNow s u
+logChange key (UUID u) s = do
+ config <- Annex.getGitConfig
+ addLog (locationLogFile config key) =<< logNow s u
logChange _ NoUUID _ = noop
{- Returns a list of repository UUIDs that, according to the log, have
@@ -51,7 +54,9 @@ loggedLocationsHistorical :: RefDate -> Key -> Annex [UUID]
loggedLocationsHistorical = getLoggedLocations . historicalLog
getLoggedLocations :: (FilePath -> Annex [String]) -> Key -> Annex [UUID]
-getLoggedLocations getter key = map toUUID <$> (getter . locationLogFile) key
+getLoggedLocations getter key = do
+ config <- Annex.getGitConfig
+ map toUUID <$> (getter . locationLogFile config) key
{- Finds all keys that have location log information.
- (There may be duplicate keys in the list.) -}
diff --git a/Logs/MetaData.hs b/Logs/MetaData.hs
index 3091935cf..ed4e2363e 100644
--- a/Logs/MetaData.hs
+++ b/Logs/MetaData.hs
@@ -38,6 +38,7 @@ import Common.Annex
import Types.MetaData
import Annex.MetaData.StandardFields
import qualified Annex.Branch
+import qualified Annex
import Logs
import Logs.SingleValue
@@ -52,7 +53,9 @@ instance SingleValueSerializable MetaData where
deserialize = Types.MetaData.deserialize
getMetaDataLog :: Key -> Annex (Log MetaData)
-getMetaDataLog = readLog . metaDataLogFile
+getMetaDataLog key = do
+ config <- Annex.getGitConfig
+ readLog $ metaDataLogFile config key
{- Go through the log from oldest to newest, and combine it all
- into a single MetaData representing the current state.
@@ -97,10 +100,12 @@ addMetaData k metadata = addMetaData' k metadata =<< liftIO getPOSIXTime
addMetaData' :: Key -> MetaData -> POSIXTime -> Annex ()
addMetaData' k d@(MetaData m) now
| d == emptyMetaData = noop
- | otherwise = Annex.Branch.change (metaDataLogFile k) $
- showLog . simplifyLog
- . S.insert (LogEntry now metadata)
- . parseLog
+ | otherwise = do
+ config <- Annex.getGitConfig
+ Annex.Branch.change (metaDataLogFile config k) $
+ showLog . simplifyLog
+ . S.insert (LogEntry now metadata)
+ . parseLog
where
metadata = MetaData $ M.filterWithKey (\f _ -> not (isLastChangedField f)) m
@@ -181,6 +186,7 @@ copyMetaData oldkey newkey
| oldkey == newkey = noop
| otherwise = do
l <- getMetaDataLog oldkey
- unless (S.null l) $
- Annex.Branch.change (metaDataLogFile newkey) $
+ unless (S.null l) $ do
+ config <- Annex.getGitConfig
+ Annex.Branch.change (metaDataLogFile config newkey) $
const $ showLog l
diff --git a/Logs/PreferredContent.hs b/Logs/PreferredContent.hs
index 83269e6d7..6c885041a 100644
--- a/Logs/PreferredContent.hs
+++ b/Logs/PreferredContent.hs
@@ -52,12 +52,12 @@ isRequiredContent :: Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFi
isRequiredContent = checkMap requiredContentMap
checkMap :: Annex (FileMatcherMap Annex) -> Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool
-checkMap getmap mu notpresent mkey afile def = do
+checkMap getmap mu notpresent mkey afile d = do
u <- maybe getUUID return mu
m <- getmap
case M.lookup u m of
- Nothing -> return def
- Just matcher -> checkMatcher matcher mkey afile notpresent def
+ Nothing -> return d
+ Just matcher -> checkMatcher matcher mkey afile notpresent d
preferredContentMap :: Annex (FileMatcherMap Annex)
preferredContentMap = maybe (fst <$> preferredRequiredMapsLoad) return
diff --git a/Logs/RemoteState.hs b/Logs/RemoteState.hs
index 7b3859a35..b302b739a 100644
--- a/Logs/RemoteState.hs
+++ b/Logs/RemoteState.hs
@@ -14,6 +14,7 @@ import Common.Annex
import Logs
import Logs.UUIDBased
import qualified Annex.Branch
+import qualified Annex
import qualified Data.Map as M
import Data.Time.Clock.POSIX
@@ -23,11 +24,14 @@ type RemoteState = String
setRemoteState :: UUID -> Key -> RemoteState -> Annex ()
setRemoteState u k s = do
ts <- liftIO getPOSIXTime
- Annex.Branch.change (remoteStateLogFile k) $
+ config <- Annex.getGitConfig
+ Annex.Branch.change (remoteStateLogFile config k) $
showLogNew id . changeLog ts u s . parseLogNew Just
getRemoteState :: UUID -> Key -> Annex (Maybe RemoteState)
-getRemoteState u k = extract . parseLogNew Just
- <$> Annex.Branch.get (remoteStateLogFile k)
+getRemoteState u k = do
+ config <- Annex.getGitConfig
+ extract . parseLogNew Just
+ <$> Annex.Branch.get (remoteStateLogFile config k)
where
extract m = value <$> M.lookup u m
diff --git a/Logs/Web.hs b/Logs/Web.hs
index 4729cead4..38993c33c 100644
--- a/Logs/Web.hs
+++ b/Logs/Web.hs
@@ -37,7 +37,8 @@ import Utility.Url
{- Gets all urls that a key might be available from. -}
getUrls :: Key -> Annex [URLString]
getUrls key = do
- l <- go $ urlLogFile key : oldurlLogs key
+ config <- Annex.getGitConfig
+ l <- go $ urlLogFile config key : oldurlLogs config key
tmpl <- Annex.getState (maybeToList . M.lookup key . Annex.tempurls)
return (tmpl ++ l)
where
@@ -54,13 +55,15 @@ getUrlsWithPrefix key prefix = filter (prefix `isPrefixOf`) <$> getUrls key
setUrlPresent :: UUID -> Key -> URLString -> Annex ()
setUrlPresent uuid key url = do
us <- getUrls key
- unless (url `elem` us) $
- addLog (urlLogFile key) =<< logNow InfoPresent url
+ unless (url `elem` us) $ do
+ config <- Annex.getGitConfig
+ addLog (urlLogFile config key) =<< logNow InfoPresent url
logChange key uuid InfoPresent
setUrlMissing :: UUID -> Key -> URLString -> Annex ()
setUrlMissing uuid key url = do
- addLog (urlLogFile key) =<< logNow InfoMissing url
+ config <- Annex.getGitConfig
+ addLog (urlLogFile config key) =<< logNow InfoMissing url
whenM (null <$> getUrls key) $
logChange key uuid InfoMissing
diff --git a/Remote/Directory.hs b/Remote/Directory.hs
index 2b887a82f..2eeb79317 100644
--- a/Remote/Directory.hs
+++ b/Remote/Directory.hs
@@ -15,6 +15,7 @@ module Remote.Directory (
import qualified Data.ByteString.Lazy as L
import qualified Data.Map as M
+import Data.Default
import Common.Annex
import Types.Remote
@@ -107,7 +108,7 @@ getLocation d k = do
{- Directory where the file(s) for a key are stored. -}
storeDir :: FilePath -> Key -> FilePath
-storeDir d k = addTrailingPathSeparator $ d </> hashDirLower k </> keyFile k
+storeDir d k = addTrailingPathSeparator $ d </> hashDirLower def k </> keyFile k
{- Where we store temporary data for a key, in the directory, as it's being
- written. -}
diff --git a/Remote/External.hs b/Remote/External.hs
index 0ec284ff4..0579400ed 100644
--- a/Remote/External.hs
+++ b/Remote/External.hs
@@ -184,7 +184,7 @@ handleRequest' lck external req mp responsehandler
handleRemoteRequest (PROGRESS bytesprocessed) =
maybe noop (\a -> liftIO $ a bytesprocessed) mp
handleRemoteRequest (DIRHASH k) =
- send $ VALUE $ hashDirMixed k
+ send $ VALUE $ hashDirMixed def k
handleRemoteRequest (SETCONFIG setting value) =
liftIO $ atomically $ do
let v = externalConfig external
diff --git a/Remote/GCrypt.hs b/Remote/GCrypt.hs
index b977750c3..aed54d20f 100644
--- a/Remote/GCrypt.hs
+++ b/Remote/GCrypt.hs
@@ -16,6 +16,7 @@ module Remote.GCrypt (
import qualified Data.Map as M
import qualified Data.ByteString.Lazy as L
import Control.Exception
+import Data.Default
import Common.Annex
import Types.Remote
@@ -361,7 +362,7 @@ checkKey r rsyncopts k
{- Annexed objects are hashed using lower-case directories for max
- portability. -}
gCryptLocation :: Remote -> Key -> FilePath
-gCryptLocation r key = Git.repoLocation (repo r) </> objectDir </> keyPath key hashDirLower
+gCryptLocation r key = Git.repoLocation (repo r) </> objectDir </> keyPath key (hashDirLower def)
data AccessMethod = AccessDirect | AccessShell
diff --git a/Remote/Git.hs b/Remote/Git.hs
index b31a1d850..328e39111 100644
--- a/Remote/Git.hs
+++ b/Remote/Git.hs
@@ -327,13 +327,15 @@ keyUrls r key = map tourl locs'
-- If the remote is known to not be bare, try the hash locations
-- used for non-bare repos first, as an optimisation.
locs
- | remoteAnnexBare (gitconfig r) == Just False = reverse (annexLocations key)
- | otherwise = annexLocations key
+ | remoteAnnexBare remoteconfig == Just False = reverse (annexLocations cfg key)
+ | otherwise = annexLocations cfg key
#ifndef mingw32_HOST_OS
locs' = locs
#else
locs' = map (replace "\\" "/") locs
#endif
+ remoteconfig = gitconfig r
+ cfg = fromJust $ remoteGitConfig remoteconfig
dropKey :: Remote -> Key -> Annex Bool
dropKey r key
diff --git a/Remote/Hook.hs b/Remote/Hook.hs
index ce7781cfb..592564772 100644
--- a/Remote/Hook.hs
+++ b/Remote/Hook.hs
@@ -7,8 +7,6 @@
module Remote.Hook (remote) where
-import qualified Data.Map as M
-
import Common.Annex
import Types.Remote
import Types.Key
@@ -20,6 +18,8 @@ import Annex.UUID
import Remote.Helper.Special
import Utility.Env
+import qualified Data.Map as M
+
type Action = String
type HookName = String
@@ -90,7 +90,7 @@ hookEnv action k f = Just <$> mergeenv (fileenv f ++ keyenv)
]
fileenv Nothing = []
fileenv (Just file) = [envvar "FILE" file]
- hashbits = map takeDirectory $ splitPath $ hashDirMixed k
+ hashbits = map takeDirectory $ splitPath $ hashDirMixed def k
lookupHook :: HookName -> Action -> Annex (Maybe String)
lookupHook hookname action = do
diff --git a/Remote/Rsync.hs b/Remote/Rsync.hs
index ae6f5450e..f5d4c85c4 100644
--- a/Remote/Rsync.hs
+++ b/Remote/Rsync.hs
@@ -37,6 +37,7 @@ import Annex.Perms
import Logs.Transfer
import Types.Creds
import Types.Key (isChunkKey)
+import Annex.DirHashes
import qualified Data.Map as M
@@ -212,8 +213,8 @@ remove o k = do
- content could be. Note that the parent directories have
- to also be explicitly included, due to how rsync
- traverses directories. -}
- includes = concatMap use annexHashes
- use h = let dir = h k in
+ includes = concatMap use dirHashes
+ use h = let dir = h def k in
[ parentDir dir
, dir
-- match content directory and anything in it
diff --git a/Remote/Rsync/RsyncUrl.hs b/Remote/Rsync/RsyncUrl.hs
index 7ebd2f68d..9a7319246 100644
--- a/Remote/Rsync/RsyncUrl.hs
+++ b/Remote/Rsync/RsyncUrl.hs
@@ -14,10 +14,12 @@ import Locations
import Utility.Rsync
import Utility.SafeCommand
+import Data.Default
import System.FilePath.Posix
#ifdef mingw32_HOST_OS
import Data.String.Utils
#endif
+import Annex.DirHashes
type RsyncUrl = String
@@ -35,12 +37,12 @@ rsyncEscape o u
| otherwise = u
rsyncUrls :: RsyncOpts -> Key -> [RsyncUrl]
-rsyncUrls o k = map use annexHashes
+rsyncUrls o k = map use dirHashes
where
use h = rsyncUrl o </> hash h </> rsyncEscape o (f </> f)
f = keyFile k
#ifndef mingw32_HOST_OS
- hash h = h k
+ hash h = h def k
#else
hash h = replace "\\" "/" (h k)
#endif
diff --git a/Remote/WebDAV/DavLocation.hs b/Remote/WebDAV/DavLocation.hs
index b5d374943..157e7151a 100644
--- a/Remote/WebDAV/DavLocation.hs
+++ b/Remote/WebDAV/DavLocation.hs
@@ -17,6 +17,7 @@ import Utility.Url (URLString)
import System.FilePath.Posix -- for manipulating url paths
import Network.Protocol.HTTP.DAV (inDAVLocation, DAVT)
import Control.Monad.IO.Class (MonadIO)
+import Data.Default
#ifdef mingw32_HOST_OS
import Data.String.Utils
#endif
@@ -33,9 +34,9 @@ keyDir :: Key -> DavLocation
keyDir k = addTrailingPathSeparator $ hashdir </> keyFile k
where
#ifndef mingw32_HOST_OS
- hashdir = hashDirLower k
+ hashdir = hashDirLower def k
#else
- hashdir = replace "\\" "/" (hashDirLower k)
+ hashdir = replace "\\" "/" (hashDirLower def k)
#endif
keyLocation :: Key -> DavLocation
diff --git a/Test.hs b/Test.hs
index 8d432cb61..633ef3690 100644
--- a/Test.hs
+++ b/Test.hs
@@ -38,7 +38,6 @@ import qualified Types.KeySource
import qualified Types.Backend
import qualified Types.TrustLevel
import qualified Types
-import qualified Logs
import qualified Logs.MapLog
import qualified Logs.Trust
import qualified Logs.Remote
@@ -138,7 +137,6 @@ properties = localOption (QuickCheckTests 1000) $ testGroup "QuickCheck"
, testProperty "prop_idempotent_key_decode" Types.Key.prop_idempotent_key_decode
, testProperty "prop_idempotent_shellEscape" Utility.SafeCommand.prop_idempotent_shellEscape
, testProperty "prop_idempotent_shellEscape_multiword" Utility.SafeCommand.prop_idempotent_shellEscape_multiword
- , testProperty "prop_logs_sane" Logs.prop_logs_sane
, testProperty "prop_idempotent_configEscape" Logs.Remote.prop_idempotent_configEscape
, testProperty "prop_parse_show_Config" Logs.Remote.prop_parse_show_Config
, testProperty "prop_upFrom_basics" Utility.Path.prop_upFrom_basics
diff --git a/Types/Difference.hs b/Types/Difference.hs
index cbfad0fce..e4562a0d6 100644
--- a/Types/Difference.hs
+++ b/Types/Difference.hs
@@ -8,8 +8,8 @@
module Types.Difference (
Difference(..),
Differences(..),
+ readDifferences,
getDifferences,
- sanityCheckDifferences,
differenceConfigKey,
differenceConfigVal,
hasDifference,
@@ -22,114 +22,67 @@ import qualified Git.Config
import Data.List
import Data.Maybe
import Data.Monoid
-import Control.Applicative
-- Describes differences from the v5 repository format.
--
--- The serilization is stored in difference.log, so avoid changes that
+-- The serialization is stored in difference.log, so avoid changes that
-- would break compatability.
--
--- Not breaking comparability is why a list of Differences is used, rather
+-- Not breaking compatability is why a list of Differences is used, rather
-- than a sum type. With a sum type, adding a new field for some future
-- difference would serialize to a value that an older version could not
-- parse, even if that new field was not used. With the Differences list,
-- old versions can still parse it, unless the new Difference constructor
-- is used.
+--
+-- The constructors intentionally do not have parameters; this is to
+-- ensure that any Difference that can be expressed is supported.
+-- So, a new repository version would be Version6, rather than Version Int.
data Difference
- = Version Int
- | ObjectHashLower Bool
- | ObjectHashDirectories Int
- | BranchHashDirectories Int
- deriving (Show, Read, Ord)
-
-instance Eq Difference where
- Version a == Version b = a == b
- ObjectHashLower a == ObjectHashLower b = a == b
- ObjectHashDirectories a == ObjectHashDirectories b = a == b
- BranchHashDirectories a == BranchHashDirectories b = a == b
- _ == _ = False
+ = ObjectHashLower
+ | OneLevelObjectHash
+ | OneLevelBranchHash
+ deriving (Show, Read, Ord, Eq, Enum, Bounded)
data Differences
= Differences [Difference]
| UnknownDifferences
- deriving (Show, Read, Ord)
instance Eq Differences where
- Differences a == Differences b = simplify (defver:a) == simplify (defver:b)
- _ == _ = False
+ Differences a == Differences b = canon a == canon b
+ _ == _ = False -- UnknownDifferences cannot be equal
instance Monoid Differences where
mempty = Differences []
- mappend (Differences l1) (Differences l2) = Differences (simplify (l1 ++ l2))
+ mappend (Differences l1) (Differences l2) = Differences (canon (l1 ++ l2))
mappend _ _ = UnknownDifferences
--- This is the default repository version that is assumed when no other one
--- is given. Note that [] == [Version 5]
-defver :: Difference
-defver = Version 5
-
--- Larger values of the same Difference constructor dominate
--- over smaller values, so given [Version 6, Version 5], returns [Version 6]
-simplify :: [Difference] -> [Difference]
-simplify = go . sort
- where
- go [] = []
- go (d:[]) = [d]
- go (d1:d2:ds)
- | like d1 d2 = go (d2:ds)
- | otherwise = d1 : go (d2:ds)
+-- Canonical form, allowing comparison.
+canon :: [Difference] -> [Difference]
+canon = nub . sort
- like (Version _) (Version _) = True
- like (ObjectHashLower _) (ObjectHashLower _) = True
- like (ObjectHashDirectories _) (ObjectHashDirectories _) = True
- like (BranchHashDirectories _) (BranchHashDirectories _) = True
- like _ _ = False
+readDifferences :: String -> Differences
+readDifferences = maybe UnknownDifferences Differences . readish
getDifferences :: Git.Repo -> Differences
-getDifferences r = checksane $ Differences $ catMaybes
- [ ObjectHashLower
- <$> getmaybebool (differenceConfigKey (ObjectHashLower undefined))
- , ObjectHashDirectories
- <$> getmayberead (differenceConfigKey (ObjectHashDirectories undefined))
- , BranchHashDirectories
- <$> getmayberead (differenceConfigKey (BranchHashDirectories undefined))
- ]
+getDifferences r = Differences $ catMaybes $
+ map getmaybe [minBound .. maxBound]
where
- getmaybe k = Git.Config.getMaybe k r
- getmayberead k = readish =<< getmaybe k
- getmaybebool k = Git.Config.isTrue =<< getmaybe k
- checksane = either error id . sanityCheckDifferences
+ getmaybe d = case Git.Config.isTrue =<< Git.Config.getMaybe (differenceConfigKey d) r of
+ Just True -> Just d
+ _ -> Nothing
differenceConfigKey :: Difference -> String
-differenceConfigKey (Version _) = "annex.version"
-differenceConfigKey (ObjectHashLower _) = tunable "objecthashlower"
-differenceConfigKey (ObjectHashDirectories _) = tunable "objecthashdirectories"
-differenceConfigKey (BranchHashDirectories _) = tunable "branchhashdirectories"
+differenceConfigKey ObjectHashLower = tunable "objecthashlower"
+differenceConfigKey OneLevelObjectHash = tunable "objecthash1"
+differenceConfigKey OneLevelBranchHash = tunable "branchhash1"
differenceConfigVal :: Difference -> String
-differenceConfigVal (Version v) = show v
-differenceConfigVal (ObjectHashLower b) = Git.Config.boolConfig b
-differenceConfigVal (ObjectHashDirectories n) = show n
-differenceConfigVal (BranchHashDirectories n) = show n
+differenceConfigVal _ = Git.Config.boolConfig True
tunable :: String -> String
tunable k = "annex.tune." ++ k
-sanityCheckDifferences :: Differences -> Either String Differences
-sanityCheckDifferences d@(Differences l)
- | null problems = Right d
- | otherwise = Left (intercalate "; " problems)
- where
- problems = catMaybes (map check l)
- check (ObjectHashDirectories n)
- | n == 1 || n == 2 = Nothing
- | otherwise = Just $ "Bad value for objecthashdirectories -- should be 1 or 2, not " ++ show n
- check (BranchHashDirectories n)
- | n == 1 || n == 2 = Nothing
- | otherwise = Just $ "Bad value for branhhashdirectories -- should be 1 or 2, not " ++ show n
- check _ = Nothing
-sanityCheckDifferences UnknownDifferences = Left "unknown differences detected; update git-annex"
-
hasDifference :: (Difference -> Bool) -> Differences -> Bool
hasDifference f (Differences l) = any f l
hasDifference _ UnknownDifferences = False
diff --git a/Types/GitConfig.hs b/Types/GitConfig.hs
index 5ac524f45..ef8f2f2bd 100644
--- a/Types/GitConfig.hs
+++ b/Types/GitConfig.hs
@@ -98,7 +98,7 @@ extractGitConfig r = GitConfig
, annexDifferences = getDifferences r
}
where
- getbool k def = fromMaybe def $ getmaybebool k
+ getbool k d = fromMaybe d $ getmaybebool k
getmaybebool k = Git.Config.isTrue =<< getmaybe k
getmayberead k = readish =<< getmaybe k
getmaybe k = Git.Config.getMaybe k r
@@ -178,7 +178,7 @@ extractRemoteGitConfig r remotename = RemoteGitConfig
, remoteGitConfig = Nothing
}
where
- getbool k def = fromMaybe def $ getmaybebool k
+ getbool k d = fromMaybe d $ getmaybebool k
getmaybebool k = Git.Config.isTrue =<< getmaybe k
getmayberead k = readish =<< getmaybe k
getmaybe k = mplus (Git.Config.getMaybe (key k) r)
diff --git a/Upgrade/V1.hs b/Upgrade/V1.hs
index e8a7efe13..801cdafa0 100644
--- a/Upgrade/V1.hs
+++ b/Upgrade/V1.hs
@@ -9,6 +9,7 @@ module Upgrade.V1 where
import System.Posix.Types
import Data.Char
+import Data.Default
import Common.Annex
import Types.Key
@@ -228,7 +229,7 @@ logFile1 :: Git.Repo -> Key -> String
logFile1 repo key = Upgrade.V2.gitStateDir repo ++ keyFile1 key ++ ".log"
logFile2 :: Key -> Git.Repo -> String
-logFile2 = logFile' hashDirLower
+logFile2 = logFile' (hashDirLower def)
logFile' :: (Key -> FilePath) -> Key -> Git.Repo -> String
logFile' hasher key repo =
diff --git a/Upgrade/V2.hs b/Upgrade/V2.hs
index 2b0b277e8..0f09205ff 100644
--- a/Upgrade/V2.hs
+++ b/Upgrade/V2.hs
@@ -12,6 +12,7 @@ import qualified Git
import qualified Git.Command
import qualified Git.Ref
import qualified Annex.Branch
+import qualified Annex
import Annex.Content
import Utility.Tmp
import Logs
@@ -47,7 +48,8 @@ upgrade = do
e <- liftIO $ doesDirectoryExist old
when e $ do
- mapM_ (\(k, f) -> inject f $ locationLogFile k) =<< locationLogs
+ config <- Annex.getGitConfig
+ mapM_ (\(k, f) -> inject f $ locationLogFile config k) =<< locationLogs
mapM_ (\f -> inject f f) =<< logFiles old
saveState False
diff --git a/Utility/Url.hs b/Utility/Url.hs
index cb4fc7d37..ddf5eea40 100644
--- a/Utility/Url.hs
+++ b/Utility/Url.hs
@@ -28,7 +28,6 @@ import Common
import Network.URI
import Network.HTTP.Conduit
import Network.HTTP.Types
-import Data.Default
import qualified Data.CaseInsensitive as CI
import qualified Data.ByteString as B
import qualified Data.ByteString.UTF8 as B8
diff --git a/debian/changelog b/debian/changelog
index 3caa7ddad..529d460c8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -26,6 +26,8 @@ git-annex (5.20150114) UNRELEASED; urgency=medium
http://git-annex.branchable.com/tuning/
* merge: Refuse to merge changes from a git-annex branch of a repo
that has been tuned in incompatable ways.
+ * Support annex.tune.objecthash1, annex.tune.objecthashlower, and
+ annex.tune.branchhash1.
-- Joey Hess <id@joeyh.name> Tue, 13 Jan 2015 17:03:39 -0400
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 06eb85e11..80dce0ddc 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -1839,7 +1839,7 @@ Here are all the supported configuration settings.
Used by hook special remotes and external special remotes to record
the type of the remote.
-* `annex.tune.objecthashdirectories`, `annex.tune.objecthashlower`, `annex.tune.branchhashdirectories`
+* `annex.tune.objecthash1`, `annex.tune.objecthashlower`, `annex.tune.branchhash1`
These can be passed to `git annex init` to tune the repository.
They cannot be safely changed in a running repository.
diff --git a/doc/internals.mdwn b/doc/internals.mdwn
index 4eb72ceac..a562d6067 100644
--- a/doc/internals.mdwn
+++ b/doc/internals.mdwn
@@ -265,4 +265,4 @@ that should prevent merging.
Example:
- e605dca6-446a-11e0-8b2a-002170d25c55 [Version 5] timestamp=1422387398.30395s
+ e605dca6-446a-11e0-8b2a-002170d25c55 [ObjectHashLower] timestamp=1422387398.30395s
diff --git a/doc/tuning.mdwn b/doc/tuning.mdwn
index 761071b6b..cbe0eca64 100644
--- a/doc/tuning.mdwn
+++ b/doc/tuning.mdwn
@@ -12,7 +12,7 @@ done by passing `-c name=value` parameters to `git annex init`.
For example, this will make git-annex use only 1 level for hash directories
in `.git/annex/objects`:
- git -c annex.tune.objecthashdirectories=1 annex init
+ git -c annex.tune.objecthash1=true annex init
It's very important to keep in mind that this makes a nonstandard format
git-annex repository. In general, this cannot safely be used with
@@ -29,16 +29,18 @@ Again, tuned repositories are an experimental feature; use with caution!
The following tuning parameters are available:
-* `annex.tune.objecthashdirectories` (default: 2)
- Sets the number of hash directories to use in `.git/annex/objects/`
+* `annex.tune.objecthash1=true`
+ Use just one level of hash directories in `.git/annex/objects/`,
+ instead of the default two levels.
-* `annex.tune.objecthashlower` (default: false)
- Set to true to make the hash directories in `.git/annex/objects/` use
- all lower-case.
+* `annex.tune.objecthashlower=true`
+ Make the hash directories in `.git/annex/objects/` use
+ all lower-case, instead of the default mixed-case.
-* `annex.tune.branchhashdirectories` (default: 2)
- Sets the number of hash directories to use in the git-annex branch.
+* `annex.tune.branchhash1=true`
+ Use just one level of hash directories in the git-annex branch,
+ instead of the default two levels.
Note that git-annex will automatically propigate these setting to
-`.git/config` for tuned repsitories. You should never directly change
+`.git/config` for tuned repositories. You should never directly change
these settings in `.git/config`