diff options
-rw-r--r-- | Command/Add.hs | 29 | ||||
-rw-r--r-- | debian/changelog | 7 |
2 files changed, 30 insertions, 6 deletions
diff --git a/Command/Add.hs b/Command/Add.hs index 7029a9c16..2c671eea2 100644 --- a/Command/Add.hs +++ b/Command/Add.hs @@ -15,7 +15,9 @@ import qualified Annex.Queue import Backend import Logs.Location import Annex.Content +import Annex.Perms import Utility.Touch +import Utility.FileMode def :: [Command] def = [command "add" paramPaths seek "add files to annex"] @@ -44,23 +46,38 @@ start file = notBareRepo $ ifAnnexed file fixup add liftIO $ removeFile file next $ next $ cleanup file key =<< inAnnex key +{- The file that's being added is locked down before a key is generated, + - to prevent it from being modified in between. It's hard linked into a + - temporary location, and its writable bits are removed. It could still be + - written to by a process that already has it open for writing. -} perform :: FilePath -> CommandPerform perform file = do - let source = KeySource { keyFilename = file, contentLocation = file} + liftIO $ preventWrite file + tmp <- fromRepo gitAnnexTmpDir + createAnnexDirectory tmp + pid <- liftIO getProcessID + let tmpfile = tmp </> "add" ++ show pid ++ "." ++ takeFileName file + nuke tmpfile + liftIO $ createLink file tmpfile + let source = KeySource { keyFilename = file, contentLocation = tmpfile } backend <- chooseBackend file - genKey source backend >>= go + genKey source backend >>= go tmpfile where - go Nothing = stop - go (Just (key, _)) = do - handle (undo file key) $ moveAnnex key file + go _ Nothing = stop + go tmpfile (Just (key, _)) = do + handle (undo file key) $ moveAnnex key tmpfile + nuke file next $ cleanup file key True +nuke :: FilePath -> Annex () +nuke file = liftIO $ whenM (doesFileExist file) $ removeFile file + {- On error, put the file back so it doesn't seem to have vanished. - This can be called before or after the symlink is in place. -} undo :: FilePath -> Key -> IOException -> Annex a undo file key e = do whenM (inAnnex key) $ do - liftIO $ whenM (doesFileExist file) $ removeFile file + nuke file handle tryharder $ fromAnnex key file logStatus key InfoMissing throw e diff --git a/debian/changelog b/debian/changelog index fd4f7b98b..9a010327d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +git-annex (3.20120606) UNRELEASED; urgency=low + + * add: Prevent (most) modifications from being made to a file while it + is being added to the annex. + + -- Joey Hess <joeyh@debian.org> Tue, 05 Jun 2012 20:25:51 -0400 + git-annex (3.20120605) unstable; urgency=low * sync: Show a nicer message if a user tries to sync to a special remote. |