diff options
-rw-r--r-- | Annex/ReplaceFile.hs | 32 | ||||
-rw-r--r-- | debian/changelog | 2 |
2 files changed, 14 insertions, 20 deletions
diff --git a/Annex/ReplaceFile.hs b/Annex/ReplaceFile.hs index 1144ba083..b090da905 100644 --- a/Annex/ReplaceFile.hs +++ b/Annex/ReplaceFile.hs @@ -1,6 +1,6 @@ {- git-annex file replacing - - - Copyright 2013 Joey Hess <id@joeyh.name> + - Copyright 2013-2015 Joey Hess <id@joeyh.name> - - Licensed under the GNU GPL version 3 or higher. -} @@ -9,35 +9,27 @@ module Annex.ReplaceFile where import Common.Annex import Annex.Perms +import Utility.Tmp {- Replaces a possibly already existing file with a new version, - atomically, by running an action. - - - The action is passed a temp file, which it can write to, and once - - done the temp file is moved into place. + - The action is passed the name of temp file, in a temp directory, + - which it can write to, and once done the temp file is moved into place + - and anything else in the temp directory is deleted. - - - The action can throw an IO exception, in which case the temp file + - The action can throw an IO exception, in which case the temp directory - will be deleted, and the existing file will be preserved. - - Throws an IO exception when it was unable to replace the file. -} replaceFile :: FilePath -> (FilePath -> Annex ()) -> Annex () -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 - tmpfile <- liftIO $ setup tmpdir - go tmpfile `catchNonAsync` (const $ rollback tmpfile) - where - setup tmpdir = do - (tmpfile, h) <- openTempFileWithDefaultPermissions tmpdir "tmp" - hClose h - return tmpfile - go tmpfile = do +replaceFile file action = do + misctmpdir <- fromRepo gitAnnexTmpMiscDir + void $ createAnnexDirectory misctmpdir + let basetmp = takeFileName file + withTmpDirIn misctmpdir basetmp $ \tmpdir -> do + let tmpfile = tmpdir <> basetmp action tmpfile liftIO $ replaceFileFrom tmpfile file diff --git a/debian/changelog b/debian/changelog index 2a05e8b0b..4f10ff57d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,8 @@ git-annex (5.20151102.2) UNRELEASED; urgency=medium are imported to is not a directort, but perhaps an annexed file. * Concurrent progress bars are now displayed when using -J with a command that moves file contents around. + * Fix race that could result in an annexed file's symlink not being + created, when eg, running concurrent git-annex adds. -- Joey Hess <id@joeyh.name> Wed, 04 Nov 2015 12:50:20 -0400 |