summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2014-07-10 14:15:46 -0400
committerGravatar Joey Hess <joey@kitenet.net>2014-07-10 14:15:46 -0400
commit0ecf84090ba1d59bc3d0064ac2a87874252971e4 (patch)
tree8bcd342cfb0b9763581b61ce3b331d7ecc9a7a9b
parent9d6fa46120e7bf69f4e19418c949020f69845b02 (diff)
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.
-rw-r--r--Annex/Direct.hs6
-rw-r--r--Annex/ReplaceFile.hs11
-rw-r--r--debian/changelog2
3 files changed, 15 insertions, 4 deletions
diff --git a/Annex/Direct.hs b/Annex/Direct.hs
index fdc67a720..e6b941e0f 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 8b15f5ce3..e734c4d64 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 b8d091925..250f71973 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 <joeyh@debian.org> Wed, 09 Jul 2014 23:29:21 -0400