From 1efa51f344442f658eb728f8666be08e44d11cb2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 10 Jul 2014 14:15:46 -0400 Subject: [PATCH] direct: Fix handling of case where a work tree subdirectory cannot be written to due to permissions. Running `git annex direct` would cause loss of data, because the object was moved to a temp file, which it then tried to replace the work tree file with, and on failure, the temp file got deleted. Now it's instead moved back into the annex object location. --- Annex/Direct.hs | 6 +++++- Annex/ReplaceFile.hs | 11 ++++++++--- debian/changelog | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Annex/Direct.hs b/Annex/Direct.hs index fdc67a7206..e6b941e0f9 100644 --- a/Annex/Direct.hs +++ b/Annex/Direct.hs @@ -354,7 +354,11 @@ toDirectGen k f = do void $ addAssociatedFile k f modifyContent loc $ do thawContent loc - replaceFile f $ liftIO . moveFile loc + replaceFileOr f + (liftIO . moveFile loc) + $ \tmp -> do -- rollback + liftIO (moveFile tmp loc) + freezeContent loc fromdirect loc = do replaceFile f $ liftIO . void . copyFileExternal loc diff --git a/Annex/ReplaceFile.hs b/Annex/ReplaceFile.hs index 8b15f5ce35..e734c4d64b 100644 --- a/Annex/ReplaceFile.hs +++ b/Annex/ReplaceFile.hs @@ -23,11 +23,16 @@ import Annex.Exception - Throws an IO exception when it was unable to replace the file. -} replaceFile :: FilePath -> (FilePath -> Annex ()) -> Annex () -replaceFile file a = do +replaceFile file action = replaceFileOr file action (liftIO . nukeFile) + +{- If unable to replace the file with the temp file, runs the + - rollback action, which is responsible for cleaning up the temp file. -} +replaceFileOr :: FilePath -> (FilePath -> Annex ()) -> (FilePath -> Annex ()) -> Annex () +replaceFileOr file action rollback = do tmpdir <- fromRepo gitAnnexTmpMiscDir void $ createAnnexDirectory tmpdir - bracketIO (setup tmpdir) nukeFile $ \tmpfile -> do - a tmpfile + bracketAnnex (liftIO $ setup tmpdir) rollback $ \tmpfile -> do + action tmpfile liftIO $ catchIO (rename tmpfile file) (fallback tmpfile) where setup tmpdir = do diff --git a/debian/changelog b/debian/changelog index b8d091925c..250f719737 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,8 @@ git-annex (5.20140710) UNRELEASED; urgency=medium * Fix minor FD leak in journal code. + * direct: Fix handling of case where a work tree subdirectory cannot + be written to due to permissions. -- Joey Hess Wed, 09 Jul 2014 23:29:21 -0400