diff options
author | Joey Hess <joey@kitenet.net> | 2013-02-17 15:05:55 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2013-02-17 16:43:14 -0400 |
commit | 6d8b95d6bf0d7b5666efc02379fe55e8d02e1ebe (patch) | |
tree | b93747a1bad6f2ca2456d4ac95d5cf177855f98d /Annex/Direct.hs | |
parent | 898a39429f750bd05898df9a4b8dae371ddc9d68 (diff) |
fully support core.symlinks=false in all relevant symlink handling code
Refactored annex link code into nice clean new library.
Audited and dealt with calls to createSymbolicLink.
Remaining calls are all safe, because:
Annex/Link.hs: ( liftIO $ createSymbolicLink linktarget file
only when core.symlinks=true
Assistant/WebApp/Configurators/Local.hs: createSymbolicLink link link
test if symlinks can be made
Command/Fix.hs: liftIO $ createSymbolicLink link file
command only works in indirect mode
Command/FromKey.hs: liftIO $ createSymbolicLink link file
command only works in indirect mode
Command/Indirect.hs: liftIO $ createSymbolicLink l f
refuses to run if core.symlinks=false
Init.hs: createSymbolicLink f f2
test if symlinks can be made
Remote/Directory.hs: go [file] = catchBoolIO $ createSymbolicLink file f >> return True
fast key linking; catches failure to make symlink and falls back to copy
Remote/Git.hs: liftIO $ catchBoolIO $ createSymbolicLink loc file >> return True
ditto
Upgrade/V1.hs: liftIO $ createSymbolicLink link f
v1 repos could not be on a filesystem w/o symlinks
Audited and dealt with calls to readSymbolicLink.
Remaining calls are all safe, because:
Annex/Link.hs: ( liftIO $ catchMaybeIO $ readSymbolicLink file
only when core.symlinks=true
Assistant/Threads/Watcher.hs: ifM ((==) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file))
code that fixes real symlinks when inotify sees them
It's ok to not fix psdueo-symlinks.
Assistant/Threads/Watcher.hs: mlink <- liftIO (catchMaybeIO $ readSymbolicLink file)
ditto
Command/Fix.hs: stopUnless ((/=) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file)) $ do
command only works in indirect mode
Upgrade/V1.hs: getsymlink = takeFileName <$> readSymbolicLink file
v1 repos could not be on a filesystem w/o symlinks
Audited and dealt with calls to isSymbolicLink.
(Typically used with getSymbolicLinkStatus, but that is just used because
getFileStatus is not as robust; it also works on pseudolinks.)
Remaining calls are all safe, because:
Assistant/Threads/SanityChecker.hs: | isSymbolicLink s -> addsymlink file ms
only handles staging of symlinks that were somehow not staged
(might need to be updated to support pseudolinks, but this is
only a belt-and-suspenders check anyway, and I've never seen the code run)
Command/Add.hs: if isSymbolicLink s || not (isRegularFile s)
avoids adding symlinks to the annex, so not relevant
Command/Indirect.hs: | isSymbolicLink s -> void $ flip whenAnnexed f $
only allowed on systems that support symlinks
Command/Indirect.hs: whenM (liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f) $ do
ditto
Seek.hs:notSymlink f = liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f
used to find unlocked files, only relevant in indirect mode
Utility/FSEvents.hs: | Files.isSymbolicLink s = runhook addSymlinkHook $ Just s
Utility/FSEvents.hs: | Files.isSymbolicLink s ->
Utility/INotify.hs: | Files.isSymbolicLink s ->
Utility/INotify.hs: checkfiletype Files.isSymbolicLink addSymlinkHook f
Utility/Kqueue.hs: | Files.isSymbolicLink s = callhook addSymlinkHook (Just s) change
all above are lower-level, not relevant
Audited and dealt with calls to isSymLink.
Remaining calls are all safe, because:
Annex/Direct.hs: | isSymLink (getmode item) =
This is looking at git diff-tree objects, not files on disk
Command/Unused.hs: | isSymLink (LsTree.mode l) = do
This is looking at git ls-tree, not file on disk
Utility/FileMode.hs:isSymLink :: FileMode -> Bool
Utility/FileMode.hs:isSymLink = checkMode symbolicLinkMode
low-level
Done!!
Diffstat (limited to 'Annex/Direct.hs')
-rw-r--r-- | Annex/Direct.hs | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/Annex/Direct.hs b/Annex/Direct.hs index a4839d509..596997652 100644 --- a/Annex/Direct.hs +++ b/Annex/Direct.hs @@ -10,8 +10,6 @@ module Annex.Direct where import Common.Annex import qualified Git import qualified Git.LsFiles -import qualified Git.UpdateIndex -import qualified Git.HashObject import qualified Git.Merge import qualified Git.DiffTree as DiffTree import Git.Sha @@ -24,6 +22,7 @@ import Backend import Types.KeySource import Annex.Content import Annex.Content.Direct +import Annex.Link import Utility.InodeCache import Utility.CopyFile @@ -88,10 +87,7 @@ addDirect file cache = do return False got (Just (key, _)) = ifM (liftIO $ compareInodeCache file $ Just cache) ( do - link <- calcGitLink file key - sha <- inRepo $ Git.HashObject.hashObject BlobObject link - Annex.Queue.addUpdateIndex =<< - inRepo (Git.UpdateIndex.stageSymlink file sha) + stageSymlink file =<< hashSymlink =<< calcGitLink file key writeInodeCache key cache void $ addAssociatedFile key file logStatus key InfoPresent @@ -155,8 +151,8 @@ mergeDirectCleanup d oldsha newsha = do - Symlinks are replaced with their content, if it's available. -} movein k f = do l <- calcGitLink f k - replaceFile f $ const $ - liftIO $ createSymbolicLink l f + replaceFile f $ + makeAnnexLink l toDirect k f {- Any new, modified, or renamed files were written to the temp @@ -185,7 +181,7 @@ toDirectGen k f = do liftIO . moveFile loc , return Nothing ) - (loc':_) -> ifM (liftIO $ catchBoolIO $ not . isSymbolicLink <$> getSymbolicLinkStatus loc') + (loc':_) -> ifM (not . isJust <$> getAnnexLinkTarget loc') {- Another direct file has the content; copy it. -} ( return $ Just $ replaceFile f $ @@ -197,13 +193,9 @@ toDirectGen k f = do removeDirect :: Key -> FilePath -> Annex () removeDirect k f = do locs <- removeAssociatedFile k f - when (null locs) $ do - r <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus f - case r of - Just s - | not (isSymbolicLink s) -> - moveAnnex k f - _ -> noop + when (null locs) $ + whenM (not . isJust <$> getAnnexLinkTarget f) $ + moveAnnex k f liftIO $ do nukeFile f void $ tryIO $ removeDirectory $ parentDir f |