In the unusual configuration where annex.crippledfilesystem=true but core.symlinks=true, store object contents in mixed case hash directories so that symlinks will point to them.

Contents are searched for in both locations, same as before, so this
does not add any overhead.
This commit is contained in:
Joey Hess 2016-05-10 15:00:19 -04:00
parent 8a81ddb448
commit 2d00523609
Failed to extract signature
3 changed files with 46 additions and 16 deletions

View file

@ -137,25 +137,28 @@ gitAnnexLocationDepth config = hashlevels + 1
- the actual location of the file's content. - the actual location of the file's content.
-} -}
gitAnnexLocation :: Key -> Git.Repo -> GitConfig -> IO FilePath gitAnnexLocation :: Key -> Git.Repo -> GitConfig -> IO FilePath
gitAnnexLocation key r config = gitAnnexLocation' key r config (annexCrippledFileSystem config) doesFileExist (Git.localGitDir r) gitAnnexLocation key r config = gitAnnexLocation' key r config (annexCrippledFileSystem config) (coreSymlinks config) doesFileExist (Git.localGitDir r)
gitAnnexLocation' :: Key -> Git.Repo -> GitConfig -> Bool -> (FilePath -> IO Bool) -> FilePath -> IO FilePath gitAnnexLocation' :: Key -> Git.Repo -> GitConfig -> Bool -> Bool -> (FilePath -> IO Bool) -> FilePath -> IO FilePath
gitAnnexLocation' key r config crippled checker gitdir gitAnnexLocation' key r config crippled symlinkssupported checker gitdir
{- Bare repositories default to hashDirLower for new {- Bare repositories default to hashDirLower for new
- content, as it's more portable. - content, as it's more portable. But check all locations. -}
- | Git.repoIsLocalBare r = checkall
- Repositories on filesystems that are crippled also use | hasDifference ObjectHashLower (annexDifferences config) =
- hashDirLower, since they do not use symlinks and it's only hashDirLower
- more portable. {- Repositories on crippled filesystems use hashDirLower
-} - for new content, unless symlinks are supported too.
| Git.repoIsLocalBare r || crippled = - Then hashDirMixed is used. But, the content could be
check $ map inrepo $ annexLocations config key - in either location so check both. -}
| hasDifference ObjectHashLower (annexDifferences config) = | symlinkssupported = check $ map inrepo $ reverse $ annexLocations config key
return $ inrepo $ annexLocation config key hashDirLower | crippled = checkall
{- Non-bare repositories only use hashDirMixed, so {- Regular repositories only use hashDirMixed, so
- don't need to do any work to check if the file is - don't need to do any work to check if the file is
- present. -} - present. -}
| otherwise = return $ inrepo $ annexLocation config key hashDirMixed | otherwise = only hashDirMixed
where where
only = return . inrepo . annexLocation config key
checkall = check $ map inrepo $ annexLocations config key
inrepo d = gitdir </> d inrepo d = gitdir </> d
check locs@(l:_) = fromMaybe l <$> firstM checker locs check locs@(l:_) = fromMaybe l <$> firstM checker locs
check [] = error "internal" check [] = error "internal"
@ -166,7 +169,7 @@ gitAnnexLink file key r config = do
currdir <- getCurrentDirectory currdir <- getCurrentDirectory
let absfile = fromMaybe whoops $ absNormPathUnix currdir file let absfile = fromMaybe whoops $ absNormPathUnix currdir file
let gitdir = getgitdir currdir let gitdir = getgitdir currdir
loc <- gitAnnexLocation' key r config False (\_ -> return True) gitdir loc <- gitAnnexLocation' key r config False False (\_ -> return True) gitdir
toInternalGitPath <$> relPathDirToFile (parentDir absfile) loc toInternalGitPath <$> relPathDirToFile (parentDir absfile) loc
where where
getgitdir currdir getgitdir currdir

3
debian/changelog vendored
View file

@ -25,6 +25,9 @@ git-annex (6.20160420) UNRELEASED; urgency=medium
when it's decrypting data. when it's decrypting data.
* fsck: When a key is not previously known in the location log, * fsck: When a key is not previously known in the location log,
record something so that reinject --known will work. record something so that reinject --known will work.
* In the unusual configuration where annex.crippledfilesystem=true but
core.symlinks=true, store object contents in mixed case hash
directories so that symlinks will point to them.
-- Joey Hess <id@joeyh.name> Thu, 28 Apr 2016 13:17:04 -0400 -- Joey Hess <id@joeyh.name> Thu, 28 Apr 2016 13:17:04 -0400

View file

@ -0,0 +1,24 @@
[[!comment format=mdwn
username="joey"
subject="""comment 5"""
date="2016-05-10T18:08:10Z"
content="""
Ok, I reproduced the problem. Normally core.symlinks will be false
by on NTFS. You have to manually set it to true to experience
this problem AFAICS.
I was able to lock a file (resulting in a broken symlink) and then successfully
unlock it and the content was back in place.
git-annex always uses the lower case hash directory names when on a
crippled filesystem, since that's more portable and avoids lots of
potential problems. By configuring core.symlinks=true, you make git-annex
support locking files using symlinks, but these symlinks can't point to the
actual content location.
I think it makes sense for git-annex to use the the mixed case hash
directory names when core.symlinks=true even if the filesystem is crippled.
There's some foot-shooting potential, since some crippled fileystems
don't support the mixed-case hash directories. But, you have to manually
set up this configuration. I've made a change along these lines.
"""]]