summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-07-07 21:29:31 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-07-07 21:30:51 -0400
commit40c6ba99f51875db28f3e1e8b309812c66594e32 (patch)
treebc950c0659df711c3a453ffe2b22ec674df00f62
parent2640ee820f4269ccc1b5f4cd184aaf895fcf405d (diff)
add: Be even more robust to avoid ever leaving the file seemingly deleted.
A failure at any point after the file is annexed will result in an undo that puts the original file back into place and wipes the location log.
-rw-r--r--Command/Add.hs44
-rw-r--r--debian/changelog6
2 files changed, 40 insertions, 10 deletions
diff --git a/Command/Add.hs b/Command/Add.hs
index e7d16b6c0..5c7cad044 100644
--- a/Command/Add.hs
+++ b/Command/Add.hs
@@ -9,6 +9,10 @@ module Command.Add where
import Control.Monad.State (liftIO)
import System.Posix.Files
+import System.Directory
+import Control.Exception.Control (handle)
+import Control.Exception.Base (throwIO)
+import Control.Exception.Extensible (IOException)
import Command
import qualified Annex
@@ -20,6 +24,7 @@ import Content
import Messages
import Utility
import Touch
+import Locations
command :: [Command]
command = [repoCommand "add" paramPath seek "add files to annex"]
@@ -46,20 +51,39 @@ perform (file, backend) = do
case k of
Nothing -> stop
Just (key, _) -> do
- moveAnnex key file
+ handle (undo file key) $ moveAnnex key file
next $ cleanup file key
-cleanup :: FilePath -> Key -> CommandCleanup
-cleanup file key = do
- link <- calcGitLink file key
- liftIO $ createSymbolicLink link 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
+ unlessM (inAnnex key) $ rethrow -- no cleanup to do
+ liftIO $ whenM (doesFileExist file) $ do removeFile file
+ handle tryharder $ fromAnnex key file
+ logStatus key InfoMissing
+ rethrow
+ where
+ rethrow = liftIO $ throwIO e
- logStatus key InfoPresent
+ -- fromAnnex could fail if the file ownership is weird
+ tryharder :: IOException -> Annex ()
+ tryharder _ = do
+ g <- Annex.gitRepo
+ liftIO $ renameFile (gitAnnexLocation g key) file
- -- touch the symlink to have the same mtime as the file it points to
- s <- liftIO $ getFileStatus file
- let mtime = modificationTime s
- liftIO $ touch file (TimeSpec mtime) False
+cleanup :: FilePath -> Key -> CommandCleanup
+cleanup file key = do
+ handle (undo file key) $ do
+ link <- calcGitLink file key
+ liftIO $ createSymbolicLink link file
+ logStatus key InfoPresent
+
+ -- touch the symlink to have the same mtime as the
+ -- file it points to
+ s <- liftIO $ getFileStatus file
+ let mtime = modificationTime s
+ liftIO $ touch file (TimeSpec mtime) False
force <- Annex.getState Annex.force
if force
diff --git a/debian/changelog b/debian/changelog
index 626e38837..80fe84256 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+git-annex (3.20110708) UNRELEASED; urgency=low
+
+ * add: Be even more robust to avoid ever leaving the file seemingly deleted.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 07 Jul 2011 21:28:49 -0400
+
git-annex (3.20110707) unstable; urgency=low
* Fix sign bug in disk free space checking.